长安cs35,Android主屏幕小构件AppWidget设计规划,邢台

暖心故事 384℃ 0

什么是AppWidget

AppWidget 即桌面小部件,也叫桌面控件,便是能直接显现在Android体系桌面上的小程序,先看图:

图中我用黄色箭头指示的即为AppWidget,一些用户运用比较频频的程序,能够做成AppWidget,这样能便利地运用。典型的程序有时钟、气候、音乐播放器等。AppWidget 是Android 体系运用开发层面的一部分,有着特别用处,运用妥当的化,确实会为app 增色不少,它的作业原理是把一个进程的控件嵌入到别外一个进程的窗口里的一种办法。长按桌面空白处,会呈现一个 AppWidget 的文件夹,在里边找到相应的 AppWidget ,长按拖出,即可将 AppWidget 增加到桌面,

怎样开发AppWidget

AppWidget 是经过 BroadCastReceiver 的方式进行操控的,开发 AppWidget 的首要类为 AppWidgetProvider, 该类承继自 BroadCastReceiver。为了完成桌面小部件,开发者只需开发一个承继自 AppWidgetProvider 的子类,并重写它的 onUpdate() 办法即可。重写该办法,一般来说可按如下几个进程进行:

1、创立一个 RemoteViews 目标,这个目标加载时指定了桌面小部件的界面布局文件。

2、设置 RemoteViews 创立时加载的布局文件中各个元素的特点。

3、创立一个 ComponentName 目标

4、调用 AppWidgetManager 更新桌面小部件。

下面来看一个实践的比如,用 Android Studio 主动生成的比如来说。

新建了一个 HelloWorld 项目,然后新建一个 AppWidget ,命名为 MyAppWidgetProvider,按默许下一步,就完成了一个最简略的AppWidget的开发。运转程序之后,将小部件增加到桌面。操作进程和默许作用如下:


咱们看看 AS 为咱们主动生成了哪些代码呢?对照着上面说的的进程咱们来看看。

首要,有一个 MyAppWidgetProvider 的类。

package com.example.joy.remoteviewstest;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.widget.RemoteViews;

/**
* Implementation of App Widget functionality.
*/
public class MyAppWidgetProvider extends AppWidgetProvider {

static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {

CharSequence widgetText = context.getString(R.string.appwidget_text);  
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.my_app_widget_provider);
views.setTextViewText(R.id.appwidget_text, widgetText);

// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}

@Override
public void onUpdate(Context context, AppWidget长安cs35,Android主屏幕小构件AppWidget设计规划,邢台Manager appWidgetManager, int[] appWidgetIds) {
// There 化妆品加盟店may be multiple widgets active, so update all of them
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}

@Override
public void onEnabled(Context context) {
// Enter relevant functionality for when the first widget is created
}

@Override
public void onDisabled(Context context) {
// Enter relevant functionality for when the last widget is disabled
}
}

该类承继自 AppWidgetProvider ,AS默许帮咱们重写 onUpdate() 办法,遍历 appWidgetIds, 调用了 updateAppWidget() 办法。再看 updateAppWidget() 办法,很简略,只要四行:

榜首行,CharSequence widgetText = context.getString(R.string.appwidget_text);声明晰一个字符串;

第二行,RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.my_app_widget_provider);

创立了一个 RemoteViews 目标,榜首个参数传运用程序包名,第二个参数指定了,RemoteViews 加载的布局文件。这一行对应上面进程中说的榜首点。能够看到在 res/layout/ 目录下面 AS 主动生成了一个 my_app_widget_provider.xml 文件,内容如下:

`<``RelativeLayout` `xmlns:android``=``"[http://schemas.android.com/apk/res/android](http://schemas.android.com/apk/res/android)"`
`android:layout_width``=``"match_parent"`
`android:layout_height``=``"match_parent"`
`android:background``=``"#09C"`
`android:padding``=``"@dimen/widget_margin"``>`
`<``TextView`
`android:id``=``"@+id/appwidget_text"`
`android:layout_width``=``"wrap_content"`
`android:layout_height``=``"wrap_content"`
`android:layout_centerHorizontal``=``"true"`
`android:layout_centerVertical``=``"true"`
`android:layout_margin``=``"8dp"`
`android:background``=``"#09C"`
`android:contentDescription``=``"@string/appwidget_text"`
`android:text``=``"@string/appwidget_text"`
`android:textColor``=``"#ffffff"`
`android:textStyle``=``"bold|italic"` `/>警营放歌献给党`
``

这个文件便是咱们最终看到的桌面小部件的姿态,布局文件中只要一个TextView。这是你或许会问,想要加图片能够吗?能够,就像正常的Activity布局相同增加 ImageView 就行了,聪明的你或许开端想自界说小部件的款式了,增加功能强大外观美丽逼格高的自界说控件了,很惋惜,不能够。小部件布局文件能够增加的组件是有约束的,详细内容在下文介绍RemoteViews 时再说。

第三行,views.setTextViewText(R.id.appwidget_text, widgetText);

将榜首行声明的字符串赋值给上面布局文件中的 TextView,留意这儿赋值时,指定TextView的 id,要对应起来。这一行关于了上面进程中的第二点。

第四行,appWidgetManager.updateAppWidget(appWidgetId, views嫡女宛秋);

这儿调用了 appWidgetManager.updateAppWidget() 办法,更新小部件。这一行对应了上面进程中的第四点。

这时,你或许有疑问了,上面分明说了四个进程,其间第三步,创立一个 ComponentName 目标,分明就不需求。确实,这个比如中也没有用到。假如咱们手敲第四步代码,AS的智能提示会告诉你,appWidgetManager.updateAppWidget() 有三个重载的办法。源码中三个办法没有写在一同,为了便利,这儿我仿制贴出官方 API 中的介绍

void 
updateAppWidget(ComponentName provider, RemoteViews views)
Set the RemoteViews to use for all AppWidget instances for the supplied AppWidget provider.
void
updateAppWidget(int[] appWidgetIds, RemoteViews views)
Set the RemoteViews to use for the specified appWidgetIds.
void
updateAppWidget(int appWidgetId, RemoteViews views)
Set the RemoteViews to use for the specified appWidgetId.

这个三个办法都接纳两个参数,第二个参数都是 RemoteViews 目标。其间榜首个办法的榜首个参数便是 ComponentName 目标,更新一切的 AppWidgetProvider 供给的一切的 AppWidget 实例,第二个办法时更新清晰指定 Id 的 AppWidget 的目标集,第三个办法,更新清晰指定 Id 的某个 AppWidget 目标。所以一般咱们运用长安cs35,Android主屏幕小构件AppWidget设计规划,邢台榜首个办法,针对一切的 AppWidget 目标,咱们也能够根据需求挑选性地去更新。

到这儿,一切进程都完毕了,就完了?还没。前面说了,自界说的 MyAppWidgetProvider 承继自 AppWidgetProvider,而 AppWidgetProvider 又是承继自 BroadCastReceiver,

所以说 MyAppWidgetProvider 本质上是一个播送接受者,归于四大组件之一,需求咱们的清单文件中注册。翻开AndroidManifest.xml文件能够看到,确实是注册了小部件的,内容如下:


  
    



android:name="android.appwidget.provider"
android:resource="@xml/my_app_widget_provider_info" />

上面代码中有一个 Action,这个 Action 必需求加,且不能更改,归于体系标准,是作为小部件的标识而存在的。假如不加,这个 Receiver 就不会呈现在小部件列表里边。然后看到小部件指定了 @xml/my_app_widget_provider_info 作为meta-data,仔细的你发现了,在 res/ 目录下面建立了一个 xml 文件夹,下面新建了一个 my_app_widget_provider_info.xml 文件,内容如下:

`
`<``appwidget-provider` `xmlns:android``=``"[http://schemas.android.com/apk/res/android](http://schemas.android.com/apk/res/android)"`
`android:initialKeyguardLayout``=``"@layout/my_app_widget_provider"`
`android:initialLayout``=``"@layout/my_app_widget_provider"`
`android:minHeight``=``"40dp"`
`android:minWidth``=``"40dp"`
`android:previewImage``=``"@drawable/example_appwidget_preview"`
`android:resizeMode``=``"horizontal|vertical"`
`android:updatePeriodMillis``=``"86400000"`
`android:widgetCategory``=``"home_screen"``>`
``

这儿装备了一些小部件的基本信息,常用的特点有 initialLayout 便是小部件的初始化布局, minHeight 界说了小部件的最小高度,previewImage 指定了小部件在小部件列表里的预览图,updatePeriodMillis 指定了小部件更新周期,单位为毫秒。更多特点,能够检查API文档。

到这儿,上面这个极简略的小部件开发进程就真的完毕了。为了开宣布更强大一点小部件,咱们还需求进一步了解 RemoteViews 和 AppWidgetProvider。

AppWidget的妆容——RemoteViews

下面简略说说 RemoteViews 相关的几个类。

1.1 RemoteViews

RemoteViews,从字面意思理解为它是一个长途视图。是一种长途的 View,它在其它进程中显现,却能够在另一个进程中更新。RemoteViews 在Android中的运用场景首要有:自界说告诉栏和桌面小部件。

在RemoteViews 的结构函数中,第二个参数接纳一个 layout 文件来确认 RemoteViews 的视图;然后,咱们调用RemoteViews 中的 set 办法对 layout 中的各个组件进行设置,例如,能够调用 setTextViewText() 来设置 TextView 组件的文本。

前面说到,小部件布局文件能够增加的组件是有约束的,它能够支撑的 View 类型包括四种布局:FrameLayout、LinearLayout、RelativeLayout、GridLayout 和 13 种View: AnalogClock、Button、Chronometer、ImageButton、ImageView、ProgressBar、TextView、ViewFlipper、ListView、GridView、StackView、AdapterViewFlipper、ViewSub。留意:RemoteViews 也并不支撑上述 View 的子类。

RemoteViews 供给了一系列 setXXX() 办法来为小部件的子视图设置特点。详细能够参阅 API 文档。

1.2 RemoteViewsService

RemoteViewsService,是办理RemoteViews的服务。一般,当AppWidget 中包括 GridView、ListView、StackView 等调集视图时,才需求运用RemoteViewsService来进行更新、办理。RemoteViewsService 更新调集视图的一般进程是:

(01) 经过 setRemoteAdapter() 办法来设置 RemoteViews 对应 RemoteViewsService 。

(02) 之后在 RemoteViewsService 中,完成 RemotroubleteViewsFactory 接口。然后,在 RemoteViewsFactory 接口中对调集视图的各个子项进行设置,例如 ListView 中常石磊的每一Item。

1.3 RemoteViewsFactory

经过RemoteViewsService中的介绍,咱们知道RemoteViewsService是经过 RemoteViewsFactory来详细办理layout中调集视图的,RemoteViewsFactory是RemoteViewsService中的一个内部接口。RemoteViewsFactory供给了一系列的办法办理调集视图中的每一项。例如:

RemoteViews getViewAt(int position)

经过getViewAt()来获取“调集视图”中的第position项的视图,视图是以RemoteViews的目标回来的。

int getCount()

经过getCount()来获取“调集视图”中一切子项的总数。

AppWidget的美貌——AppWidgetProvider

咱们说一位女同事美丽,除了由于她穿的衣服、化的妆美丽以外,我想最首要的原因仍是她自己长的美丽吧。相同,小部件之所以有附着在桌面,跨进程更新 View 的才能,首要是由于AppWidgetProvider 是一个播送接纳者。

咱们发现,上面的比如中,AS 帮咱们主动生成的代码中,除了 onUpdate() 办法被咱们重写了,还有重写 onEnable() 和 onDisable() 两个办法,但都是空完成,这两个办法什么时分会被调用?还有,咱们说自界说的 MyAppWidgetProvider,承继自 AppWidgetProvider,而 MyAppWidgetProvider 又是BroadCastReceiver 的子类,而咱们却没有向写惯例播送接纳者相同重写 onReceiver() 办法?被侵略下面跟进去 AppWidgetProvider 源码,一探终究。

这个类代码并不多,其实,AppWidgetProvider 出去结构办法外,一共只要下面这些办法:

onEnable() :当小部件榜首次被增加到桌面时回调该办法,可增加屡次,但只在榜首次调用。对用播送的 Action 为 ACTION_APPWIDGET_ENABLE。

onUpdate(): 当小部件被增加时或许每次小部件更新时都会调用一次该办法,装备文件中装备小部件的更新周期 updatePeriodMillis,每次更新都会调用。对应播送 Action 为:ACTION_APPWIDGET_UPDATE长安cs35,Android主屏幕小构件AppWidget设计规划,邢台 和 ACTION_APPWIDGET_RESTORED 。

onDisabled(): 当最终一个该类型的小部件从桌面移除时调用,对应的播送的 Action 为 ACTION_APPWIDGET_DISABLED。

onDeleted(): 每删去一个小部件就调用一次。对应的播送的 Action 为: ACTION_APPWIDGET_DELETED 。

onRestored(): 当小部件从备份中复原,或许康复设置的时分,会调用,实践用的比较少。对应播送的 Action 为 ACTION_APPWIDGET_RESTORED。

onAppWidgetOptionsChanged(): 当小部件布局发作更改的时分调用。对应播送的 Action 为 ACTION_APPWIDGET_OPTIONS_CHANGED。

最终便是 onReceive() 办法了,AppWidgetProvider 重写了该办法,用于分发详细的时刻给上述的办法。看看源码:

public void onReceive(Context context, Intent intent) {
// Protect against rogue update broadcasts (not really a security issue,
// just filter bad broacasts out so subclasses are less likely to crash).
String action = intent.getAction();
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null) {
int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
if (appWidgetIds != null && appWidgetIds.length > 0) {
this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);
}
}
} else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)) {
final int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWI轿车标志大全DGET_ID);
this.onDeleted(context, new int[] { appWidgetId });
}
} else if (AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED.equal蛮荒记s(action)) {
Bundle extras = intent.getExtras();
if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)
&& extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS)) {
int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_高叉比基尼APPWIDGET_ID);
Bundle widgetExtras = extras.getBundle(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS);
this.onAppWidgetOptionsChanged(context, AppWidgetManager.getInstance(context),
appWidgetId, widgetExtras);
}
} else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {
this.onEnabled(context);
} else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) {
this.onDisabled(context);
} else if (AppWidgetManager.ACTION_APPWIDGET_RESTORED.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null) {
int[] oldIds = extras.悟空录getIntArray(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS);
int[] newIds = extras.ge福娃tIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
if (oldIds != null && oldIds.length > 0) {
this.onRestored(context, oldIds, newIds);
this.onUpdate(context, AppWidgetManager.getInstance(context), newIds);
}
}
}
}

AppWidget 操练

下面再自己写个比如,学习 RemoteViews 中的其它知识点,这个比如中小部件布局中用到 button 和 listview。上代码:

小部件的布局文件 mul_app_widget_provider.xml 如下:

`
`<``LinearLayout` `xmlns:android``=``"[http://schemas.android.com/apk/res/android](http://schemas.android.com/apk/res/android)"`
`android:orientation``=``"horizontal"`
`android:layout_width``=``"match_parent"`
`android:layout_height``=``"match_parent"``>`
`<``LinearLayout`
`android:layout_width``=``"100dp"`
`android:layout_height``=``"200dp"`
`android:orientation``=``"vertical"``>`
`<``ImageView`
`android:id``=``"@+id/iv_test"`
`android:layout_width``=``天山雪莲"match_parent"`
`android:layout_height``=``"100dp"`
`android:src``=``"@mipmap/ic_launcher"``/>`
`<``Button`
`android:id``=``"@+id/btn_test"`
`android:layout_width``=``"match_parent"`
`andr长安cs35,Android主屏幕小构件AppWidget设计规划,邢台oid:layout_height``=``"wrap_content"`
`android:text``=``"点击跳转"``/>`
``
`<``TextView`
`android:layout_width``=``"1dp"`
`android:layout_height``=``"200dp"`
`android:layout_marginLeft``=``"5dp"`
`android:layout_marginRight``=``"5dp"`
`android:background``=``"#f00"``/>`
`<``ListView`
`android:id``=``"@+id/lv_test"`
`android:layout_width``=``"100dp"`
`android:layout_height``=``"200dp"``>`
``
``

小部件的装备信息 mul_app_widget_provider_info.xml 如下:

`
`<``appwidget-provider` `xmlns:android``=``"[http://schemas.android.com/apk/res/android](http://schemas.android.com/apk/res/android)"`
`android:initialLayout``=``"@layout/mul_app_widget_provider"`
`android:minHeight``=``"200dp"`
`android:minWidth``=``"200dp"`
`android:previewImage``=``"@mipmap/a1"`
`android:updatePeriodMillis``=``"86400000"``>`
``

MulAppWidgetProvider.java:

package com.example.joy.remoteviewstest;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.widget.RemoteViews;
import android.widget.Toast;

public class MulAppWidgetProvider extends AppWidgetProvider {

public static final String CHANGE_IMAGE = "com.example.joy.action.CHANGE_IMAGE";

private RemoteViews mRemoteViews;
private ComponentName mComponentName;

private int[] imgs = new int[]{
R.mipmap.a1,
R.mipmap.b2,
R.mipmap.c3,
R.mipmap.d4,
R.mipmap.e5,
R.mipmap.f6
};


@Override
public void onUpdate(Context 罗振跃context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
mRemoteViews = new RemoteVie比亚迪供货商门户ws(context.getPackageName(), R.layout.mul_app_widget_provider);
mRemoteViews.setImageViewResource(R.id.iv_test, R.mipmap.ic_launcher);
mRemoteViews.setTextViewText(R.id.btn_test, "点击跳转到Activity");
Intent skipIntent = new Intent(context, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(context, 200, skipIntent, PendingIntent.FLAG_CANCEL_CURRENT);
mRemoteViews.setOnClickPendingIntent(R.id.btn_test, pi);

// 设置 ListView 的adapter。
// (01) intent: 对应发动 ListViewService(RemoteViewsService) 的intent
// (02) setRemoteAdapter: 设置 ListView 的适配器
// 经过setRemoteAdapter将 ListView 和ListViewService相关起来,
// 以到达经过 GridWidgetService 更新 gridview 的意图
Intent lvIntent = new Intent(context, ListViewService.class);
mRemoteViews.setRemoteAdapter(R.id.lv_test, lvIntent);
mRemoteViews.setEmptyView长安cs35,Android主屏幕小构件AppWidget设计规划,邢台(R.id.lv_test,android.R.id.empty);

// 设置呼应 ListView 的intent模板
// 阐明:“调集控件(如GridView、ListView、StackView等)”中包括许多子元素,如GridView包括许多格子。
// 它们不能像一般的按钮相同经过 setOnClickPendingIntent 设置点击事情,必须先经过两步。
// (01) 经过 无敌大军阀setPendingIntentTemplate 设置 “intent模板”,这是比不行少的!
// (02) 然后在处理该“调集控件”的RemoteViewsFactory类的getViewAt()接口中 经过 setOnClickFillInIntent 设置“调集控件的某一项的数据”

/*
* setPendingIntentTemplate 设置pendingIntent 模板
* setOnClickFillInIntent 能够将fillInIntent 增加到pendingIntent中
*/
Intent toIntent = new Intent(CHANGE_IMAGE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 200, toIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mRemoteViews.setPendingIntentTemplate(R.id.lv_test, pendingIntent);


mComponentName = new ComponentName(context, MulAppWidgetProvider.class);
appWidgetManager.updateAppWidget(mComponentName, mRemoteViews);
}

@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if(TextUtils.equals(CHANGE_IMAGE,intent.getAction())){
Bundle extras = intent.getExtras();
int position = extras.getInt(ListViewService.INITENT_DATA);
mRemoteViews = new RemoteViews(context.getPackageName(), R.layout.mul_app_widget_provider);
mRemoteViews.setImageViewResource(R.id.iv_test, imgs[position]);
mComponentName = new ComponentName(context, MulAppWidgetProvider.class);
AppWidgetManager.getInstance(context).updateAppWidget(mComponentName, mRemoteViews);
}
}
}

MainActivity.java:

ge com.example.joy.remoteviewstest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}

下面要点是 ListView 在小部件中的用法:

 com.example.joy.remoteviewstest;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;

import java.util.ArrayList;
import java.util.List;

public class ListViewService extends RemoteViewsService {
public static final String INITENT_DATA = "extra_data";

@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
return new ListRemoteViewsFactory(this.getApplicationContext(), intent);
}

private class ListRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {

private Context mContext;

p长安cs35,Android主屏幕小构件AppWidget设计规划,邢台rivate List mList = new ArrayList<>();

public ListRemoteViewsFactory(Context context, Intent intent) {
mContext = context;
}

@Override
public void onCreate() {
mList.add("一");
mList.add("二");
mList.add("三");
mList.add("四");
mList.add("五");
mList.add("六");
}

@Override
public void onDataSetChanged() {

}

@Override
public void onDestroy() {
mList玉女心.clear();
}

@Override
public int getCount() {
return mList.size();
}

@Override
public RemoteViews getViewAt(int position) {
RemoteViews views = new RemoteViews(mContext.getPackageName(), android.R.layout.simple_list_item_1);
views.setTextViewText(android.R.id.text1, "item:" + mList.get(position));

Bundle extras = new Bundle();
extras.putInt(ListViewService.INITENT_DATA, position);
Intent changeIntent = new Intent();
changeIntent.setAction(MulAppWidgetProvider.CHANGE_IMAGE);
changeIntent.putExtras(extras);

/* android.R.layout.simple_list_item_1 --- id --- text1
* listview的item click:将 changeIntent 发送,
* changeIntent 它默许的就有action 是provider中运用 setPe锦纶丝袜ndingIntentTemplate 设置的action*/
views.setOnClickFillInIntent(android.R.id.text1, changeIntent);
return views;
}

/* 在更新界面的时分假如耗时就会显现 正在加载... 的默许字样,可是你能够更改这个界面
* 假如回来null 显现默许界面
* 不然 加载自界说的,回来RemoteViews
*/
@Over长安cs35,Android主屏幕小构件AppWidget设计规划,邢台ride
public RemoteViews getLoadingView() {
return null;
}

@Override
public int getViewTypeCoun三七粉怎样吃t() {
return 1;
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public boolean hasStableIds() {
return false;
}
}
}

最终看看清单文件:

`
`<``manifest` `xmlns:android``=``"[http://schemas.android.com/apk/res/android](http://schemas.android.com/apk/res/android)"`
`package``=``"com.example.joy.remoteviewstest"``>`
`<``application`
`android:allowBackup``=``"true"`
`android:icon``=``"@mipmap/ic_launcher"`
`android:label``=``"@string/app_name"`
`android:supportsRtl``=``"true"`
`android:theme``=``"@style/AppTheme"``>`
`<``activity` `android:name``=``".MainActivity"``>`
`<``intent-filter``>`
`<``action` `android:name``=``"android.intent.action.MAIN"` `/>`
`<``category` `android:name``=``"android.intent.category.LAUNCHER"` `/>`
``
``
`<``receiver` `android:name``=``".MulAppWidgetProvider"`
`android:label``=``"@string/app_name"``>`
`<``intent-filter``>`
`<``action` `android:name``=``"com.example.joy.action.CHANGE_IMAGE"``/>`
`<``action` `android:name``=``"android.appwidget.action.APPWIDGET_UPDATE"``/>`
``
`<``meta-data`
`android:name``=``"android.appwidget.provider"`
`android:resource``=``"@xml/mul_app_widget_provider_info"``>`
``
``
`<``service` `android:name``=``".ListViewService"`
`android:permission``=``"android.permission.BIND_REMOTEVIEWS"`
`android:exported``=``"false"`
`android:enabled``=``"true"``/>`
``
``

这个小部件增加到桌面后有一个 ImageView 显现小机器人,下面有一个 Button ,右边有一个ListView。

这儿首要看看,Button 和 ListView 在 RemoteViews中怎样运用。、

Button 设置 Text 和 TextView 相同,由于 Button 自身承继自 TextView,Button 设置点击事情如下:

Intent skipIntent = new In波多野结衣无码tent(context, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(context, 200, skipIntent, PendingIntent.FLAG_CANCEL_CURRENT);
mRemoteViews.setOnClickPendingIntent(R.id.btn_test, pi);

用到办法 setOnClickPendingIntent,PendingIntent 表明推迟的 Intent , 与告诉中的用法相同。这儿点击之后跳转到了 MainActivity。

关于 ListView 的用法就杂乱一些了。首要需求自界说一个类承继自 RemoteViewsServices ,并重写 onGetViewFactory 办法,回来 RemoteViewsService.RemoteViewsFactory 接口的目标。这儿界说了一个内部类完成该接口,需求重写多个办法,与 ListView 的多布局适配很相似。要点办法是

1

public RemoteViews getViewAt(int position){}

这个办法中指定了 ListView 的每一个 item 的布局以及内容,一起经过 setOnClickFillInIntent() 或许 setOnClickPendingIntent() 给 item 设置点击事情。这儿我完成的点击 item,替换左面的 ImageView 的图片。重写了 MulAppWidgetProvider 类的 onReceiver 办法,处理替换图片的逻辑。

程序运转作用如下图:


标签: 迷墓惊魂五官