java web widget_Android基础 --- Widget

先来看下效果图. 这是仿三星FM收音机的一个widget.

2e1a37d479dfbf399d19bb82d4a36958.png

1. 首先在widget创建一个布局文件: layout/widget.xml.

2. 在xml中创建xml/radioinfo.xml:

android:initialLayout="@layout/widget"

android:minHeight="50.0dip"

android:minWidth="300.0dip"

android:previewImage="@drawable/fm_radio_widget_preview"

android:resizeMode="vertical" />

属性解释: android:initialLayout="@layout/widget"   : 指定widget的布局文件

android:previewImage="@drawable/fm_radio_widget_preview"  指定widget在手机小部件中的缩略图.

3.  创建一个继承AppWidgetProvider类FMRadioWidgetProvider.java, 并实现onUpdate , onReceive ,这两个函数.

3.1 AppWidgetProvider解释:  这个类其实是一个广播接收器, 当widget被拖放到桌面的时候会首先调用onUpdate(Context context, AppWidgetManager appWidgetManager,

int[] appWidgetIds)函数. 所以 , 一般在这个函数中做初始化操作.

3.2为按钮添加事件:

Intent intent = new Intent(FMRadioService.ACTION_FM_NEXT);

intent.setClass(context, FMRadioService.class);

pIntent = PendingIntent.getService(context, 0, intent, 0);

remoteViews.setOnClickPendingIntent(R.id.ic_arrow_right, pIntent);

当点击这个这个按钮的时候, 会发送一个Intent并FMRadioService类.

这种方式绑定的事件只能适用于单个View.  对于像ListView,  GridView这样的集合的item要绑定事件的话不适用. 这点后面讲到.

3.3为组件设置相关属性, 例如给TextView设置文本:

RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);

remoteViews.setTextViewText(R.id.txt_frequency, String.valueOf(freq));

最后: 要记得updateWidget一下: AppWidgetManager.getInstance(context).updateAppWidget(appWidgetIds, remoteViews); 一开始我就忘记了update , 导致widget没有显示

任何东西.

3.4 为GridView/ListView绑定数据集: widget中的FM电台列表是一个GridView. 那么如何为GridView设置数据集呢.

Intent intent = new Intent(context , FMRadioWidgetService.class);

intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);

intent.setData(FMRadioStation.Station.CONTENT_URI);

remoteViews.setRemoteAdapter(appWidgetId, R.id.widget_gridView, intent);

设置数据集需要提供一个远程适配器. 适配器是一个RemoteViewsService类型的对象. 该类实现一个onGetViewFactory(Intent intent)函数:

public class FMRadioWidgetService extends RemoteViewsService {

private final String LOGTAG = "FMRadioWidgetService" ;

private final boolean ISLOG = false ;

@Override

public RemoteViewsFactory onGetViewFactory(Intent intent) {

if(ISLOG)Log.d(LOGTAG , " FMRadioWidgetService::[onGetViewFactory ] intent = "+intent);

return new FMRadioRemoteViewsFactory(getApplicationContext() , intent);

}

}

FMRadioRemoteViewsFactory才是一个正在的adapter. 该类实现RemoteViewsFactory接口, 并实现了onDataSetChanged() 和 getViewAt(int position)函数,

此处getViewAt(int position)的实现类似我们传统Adapter的bindView()函数. 然后在onDataSetChanged() 一般会从数据库读取数据.

@Override

public RemoteViews getViewAt(int position) {

RemoteViews rv = new RemoteViews(mContext.getPackageName() , R.layout.widget_item);

...

HashMap map = mlistStations.get(position);

rv.setTextViewText(R.id.widget_gv_txt_itme, freqStr);

...

Intent fillInIntent = new Intent();

Bundle extras = new Bundle();

extras.putInt(FMRadioAppWidgetProvider.EXTRA_SORT, position);

fillInIntent.putExtras(extras);

// Make it possible to distinguish the individual on-click

// action of a given item

rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent);

return rv;

}

@Override

public void onDataSetChanged() {

queryFMradioStation();

}

在getViewAt()中为GridView的每一个item设置click事件:

Intent fillInIntent = new Intent();

Bundle extras = new Bundle();

extras.putInt(FMRadioAppWidgetProvider.EXTRA_SORT, position);

fillInIntent.putExtras(extras);

// Make it possible to distinguish the individual on-click

// action of a given item

rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent);

而该处的intent要与FMRadioWidgetProvider.java的onUpdate函数中的:

// Set the action for the intent.

// When the user touches a particular view, it will have the effect of

// broadcasting TOAST_ACTION.

itemClcikIntent.setAction(FMRadioAppWidgetProvider.ACTION_CLICK);

itemClcikIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);

intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));

PendingIntent itemPendingIntent = PendingIntent.getBroadcast(context, 0, itemClcikIntent,

PendingIntent.FLAG_UPDATE_CURRENT);

remoteViews.setPendingIntentTemplate(R.id.widget_gridView, itemPendingIntent);

这两处最终合成一个Intent. 当点击每一个item的时候, 会发送一个ACTION_CLICK的广播, 并且在FMRadioAppWidgetProvide接收广播后, 在onReceive中进行处理.

整个widget大概基本完成.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值