Pro Android学习笔记(一四十):List Widgets(2):App Widget Provider

文章转载只能用于非商业性质,且不能带有虚拟货币、积分、注册等附加条件。转载须注明出处http://blog.csdn.net/flowingflying/以及作者@恺风Wei。

下面是App Widget Provider的代码:

public class TestListWidgetProvider extends AppWidgetProvider{
    private static String tag = "provider";
    public final static String ACTION_LIST_CLICK = "cn.wei.flowingflying.list_click";
    public static final String EXTRA_LIST_ITEM_TEXT = "cn.wei.flowingflying.item_text";

    @Override //【1】在onUpdate()中设置并加载Remote views,具体在updateWidget()中处理
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {      
       Log.d(tag,"onUpdate() ... ");
        for(int i = 0 ; i < appWidgetIds.length ; i ++){
            updateWidget(context,appWidgetManager,appWidgetIds[i]);
       }
    }

   … …         
    
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(tag,"onReceive() : " + intent);
        if(intent.getAction().equals(ACTION_LIST_CLICK)){ //【3】处理点击item的广播
            dealWithItemClick(context,intent);
        }else{
           super.onReceive(context, intent);  //处理widget相关的广播,触发onUpdate()等回调函数
        }
    }

   
    /* 【2】具体处理onUpdate()中某个widget的Remote Views的设置和价值 */
    private void updateWidget(Context context,AppWidgetManager appWidgetManager,int widgetId){
        Log.d(tag,"update widget " + widgetId); 
        // 2.1)从layout文件中创建remote views对象。 
        RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.test_list_widget_layout);
        //等同于 calling AdapterView.setEmptyView(),如果list空时,将显示R.id.listwidget_empty_tv,即显示“Empty Records View”的TextView 
        rv.setEmptyView(R.id.listwidget_list_view, R.id.listwidget_empty_tv);
       
       /* 2.2)设置RemoteViewsService,通过在后台对remote adapter进行设置,即设置remote list item
         * onUpdate()是运行在main线程,Android通过一个后台服务(RemoteViews Service的继承)对list view的数据进行设置。这个intent传递到RemoteViewsService的onGetViewFactory(Intent intent)中。 */ 
        Intent intent = new Intent(context,TestRemoteViewsService.class);
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
        rv.setRemoteAdapter(R.id.listwidget_list_view, intent);
       
       
        /* 2.3)设置点击item。分为两部,第一步、为所有的item设置模板(由于list有多个子view,为每个子view都进行一次设置很麻烦,而且低效,通过统一提供模板的方式来处理);第二步、在factory中为每个item在模板的基础上设置其特定的intent extra,具体见下一学习笔记。本例子采用点击触发广播消息的方式,广播消息(action为ACTION_LIST_CLICK)并被本TestListWidgetProvider类(也是接收器)收听。PendingIntent中设置tag为FLAG_UPDATE_CURRENT,表示如果有相似的intent(模板),使用之并更新extras。 */
        Intent onListViewClickIntent = new Intent(context,TestListWidgetProvider.class);
        onListViewClickIntent.setAction(ACTION_LIST_CLICK);
        onListViewClickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId); 
        PendingIntent pi = PendingIntent.getBroadcast(
                context, 0, onListViewClickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        rv.setPendingIntentTemplate(R.id.listwidget_list_view, pi); //设置为模板PengdingIntent
       
        // 2.4)部署到具体的widget
        appWidgetManager.updateAppWidget(widgetId, rv);        
    }
   
    /*【3】处理点击item的广播,小例子讲弹框显示 */
    private void dealWithItemClick(Context context,Intent intent){
        int widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
        if(widgetId == AppWidgetManager.INVALID_APPWIDGET_ID){
            Log.d(tag,"无效widget ID");
            return;           
        } 

        String itemText =  intent.getStringExtra(EXTRA_LIST_ITEM_TEXT);
        if(itemText == null){
            itemText = "Error";
        }         
        itemText = "You have client on item : " + itemText;
        Toast.makeText(context, itemText, Toast.LENGTH_LONG).show();

    }

}

小例子代码在:Pro Android学习:list widget小例子 

相关链接:我的Android开发相关文章

你可能感兴趣的:(Pro Android学习笔记(一四十):List Widgets(2):App Widget Provider)