• android appwidget笔记


    一:实现一个Activity配置widget

    (1):在widget配置文件中加入如下代码:

    [html] view plaincopy
     
    1. <span style="white-space:pre"><appwidget-provider  
    2.   xmlns:android="http://schemas.android.com/apk/res/android"  
    3.   android:minWidth="250dp"  
    4.   android:minHeight="180dp"  
    5.   android:updatePeriodMillis="0"  
    6.   android:initialLayout="@layout/widget_layout"  
    7.   android:resizeMode="vertical"  
    8.   android:configure="xx.widgets.ExampleAppWidgetConfigure"   
    9.   android:previewImage="@drawable/ic_launcher">  
    10. </appwidget-provider></span>  

    (2):在Activity中加入如下代码:

    [java] view plaincopy
     
    1. Intent launchIntent = getIntent();  
    2. Bundle extras = launchIntent.getExtras();  
    3. if (extras != null) {  
    4.       
    5.     appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,AppWidgetManager.INVALID_APPWIDGET_ID);  
    6.     Intent cancelResultValue = new Intent();  
    7.     cancelResultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetId);  
    8.     //未配置完成返回结果  
    9.     setResult(RESULT_CANCELED, cancelResultValue);  
    10. else {  
    11.     // only launch if it's for configuration  
    12.     // Note: when you launch for debugging, this does prevent this  
    13.     // activity from running. We could also turn off the intent  
    14.     // filtering for main activity.  
    15.     // But, to debug this activity, we can also just comment the  
    16.     // following line out.  
    17.     finish();  
    18. }  
    [java] view plaincopy
     
    1. if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID)   
    2. {  
    3.                       
    4.     Intent resultValue = new Intent();  
    5.     resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetId);  
    6.     //配置完成返回结果  
    7.     setResult(RESULT_OK, resultValue);  
    8.                       
    9. }  

    二:如何在RemoteViews中使用ListView

    (1):通过RemoteViewsService 渲染器实现

    [java] view plaincopy
     
    1. import java.util.ArrayList;  
    2. import java.util.HashMap;  
    3. import java.util.List;  
    4.   
    5. import android.annotation.SuppressLint;  
    6. import android.content.Context;  
    7. import android.content.Intent;  
    8. import android.content.SharedPreferences;  
    9. import android.database.Cursor;  
    10. import android.database.sqlite.SQLiteDatabase;  
    11. import android.os.IBinder;  
    12. import android.os.Looper;  
    13. import android.widget.RemoteViews;  
    14. import android.widget.RemoteViewsService;  
    15. public class UpdateService extends RemoteViewsService {  
    16.   
    17.     @Override  
    18.     public void onStart(Intent intent, int startId) {  
    19.           
    20.         super.onCreate();  
    21.     }  
    22.   
    23.     @Override  
    24.     public IBinder onBind(Intent intent) {  
    25.         return super.onBind(intent);  
    26.     }  
    27.   
    28.     @Override  
    29.     public RemoteViewsFactory onGetViewFactory(Intent intent) {  
    30.         return new ListRemoteViewsFactory(this.getApplicationContext(), intent);  
    31.     }  
    32.       
    33.       
    34.     class ListRemoteViewsFactory implements  
    35.             RemoteViewsService.RemoteViewsFactory {  
    36.   
    37.         private final Context mContext;  
    38.         private final List<String> mList;  
    39.   
    40.         public ListRemoteViewsFactory(Context context, Intent intent) {  
    41.             mContext = context;  
    42.             mList = getDataSources();//获取数据源  
    43.             if (Looper.myLooper() == null) {  
    44.                 Looper.prepare();  
    45.             }  
    46.         }  
    47.   
    48.         @Override  
    49.         public void onCreate() {  
    50.               
    51.         }  
    52.   
    53.           
    54.         @Override  
    55.         public void onDataSetChanged() {  
    56.   
    57.         }  
    58.   
    59.         @Override  
    60.         public void onDestroy() {  
    61.               
    62.             mList.clear();  
    63.         }  
    64.   
    65.         @Override  
    66.         public int getCount() {  
    67.               
    68.             return mList.size();  
    69.         }  
    70.   
    71.         @Override  
    72.         public RemoteViews getViewAt(int position) {  
    73.             if (position < 0 || position >= mList.size())  
    74.                 return null;  
    75.             String content = mList.get(position);  
    76.             final RemoteViews rv = new RemoteViews(mContext.getPackageName(),  
    77.                     R.layout.row);  
    78.             Intent intent = new Intent();  
    79.             // TODO  
    80.             // intent.setComponent(new ComponentName("包名", "类名"));  
    81.             // 与CustomWidget中remoteViews.setPendingIntentTemplate配对使用实现ListView中的Item的点击事件  
    82.             rv.setOnClickFillInIntent(R.id.widget_list_item_layout, intent);          
    83.             rv.setTextViewText(android.R.id.text1, content);  
    84.   
    85.             return rv;  
    86.         }  
    87.   
    88.         @Override  
    89.         public RemoteViews getLoadingView() {  
    90.             return null;  
    91.         }  
    92.   
    93.         @Override  
    94.         public int getViewTypeCount() {  
    95.             return 1;  
    96.         }  
    97.   
    98.         @Override  
    99.         public long getItemId(int position) {  
    100.             return position;  
    101.         }  
    102.   
    103.         @Override  
    104.         public boolean hasStableIds() {  
    105.             return true;  
    106.         }  
    107.     }  
    108.       
    109.     public List<String>getDataSources() {  
    110.         List<String> list = new ArrayList<String>();  
    111.         ......  
    112.         return list;  
    113.     }  
    114. }  

    (2):在widget的onUpdate中添加代码:

    [java] view plaincopy
     
    1. for (int i = 0; i < appWidgetIds.length; i++) {//如果使用循环,当调试重新运行程序或者重启机器时widget点击事情会失灵  
    2.         Intent intent = new Intent(ctxt, WidgetService.class);  
    3.         RemoteViews widget = new RemoteViews(ctxt.getPackageName(),  
    4.                 R.layout.widget);  
    5.         widget.setRemoteAdapter(appWidgetIds[i], R.id.words, intent);  
    6.   
    7.         Intent clickIntent = new Intent(ctxt, LoremActivity.class);  
    8.         PendingIntent clickPI = PendingIntent.getActivity(ctxt, 0,  
    9.                 clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);  
    10.         widget.setPendingIntentTemplate(R.id.words, clickPI);//配合getViewAt方法中的setOnClickFillInIntent实现listView中Item的点击事件  
    11.   
    12.         appWidgetManager.updateAppWidget(appWidgetIds[i], widget);  
    13.     }  

    (3):widget.xml

    [html] view plaincopy
     
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <ListView xmlns:android="http://schemas.android.com/apk/res/android"  
    3.   android:id="@+id/words"  
    4.   android:layout_width="match_parent"  
    5.   android:layout_height="match_parent"  
    6.   android:layout_marginTop="3dp"  
    7.   android:layout_marginLeft="3dp"  
    8.   android:background="@drawable/widget_frame"  
    9. />  


    (4):row.xml

    [html] view plaincopy
     
    1. <TextView xmlns:android="http://schemas.android.com/apk/res/android"  
    2.     android:id="@android:id/text1"  
    3.     android:layout_width="match_parent"  
    4.     android:layout_height="wrap_content"  
    5.     android:textAppearance="?android:attr/textAppearanceLarge"  
    6.     android:gravity="center_vertical"  
    7.     android:paddingLeft="6dip"  
    8.     android:minHeight="?android:attr/listPreferredItemHeight"  
    9. />  

    三:如何更新widget

    (1):定时更新

    在widget配置文件中有这句 android:updatePeriodMillis="0",这种更新方式已经不能使用了,一般定时更新使用AlarmManager,如下代码

    [html] view plaincopy
     
    1. private void setAlarm(Context context, int appWidgetId, int updateRateSeconds) {  
    2.       Intent widgetUpdate = new Intent();  
    3.       widgetUpdate.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);  
    4.       widgetUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { appWidgetId });  
    5.   
    6.       // make this pending intent unique by adding a scheme to it  
    7.       widgetUpdate.setData(Uri.withAppendedPath(Uri.parse(ImagesWidgetProvider.URI_SCHEME + "://widget/id/"), String.valueOf(appWidgetId)));  
    8.       PendingIntent newPending = PendingIntent.getBroadcast(context, 0, widgetUpdate, PendingIntent.FLAG_UPDATE_CURRENT);  
    9.   
    10.       // schedule the updating  
    11.       AlarmManager alarms = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);  
    12.       if (updateRateSeconds >= 0) {  
    13.           alarms.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), updateRateSeconds * 1000, newPending);  
    14.       } else {  
    15.           alarms.cancel(newPending);  
    16.       }  
    17.   }  

    (2):事件更新,不通过时间更新widget一般使用广播来更新

    [java] view plaincopy
     
    1. public void onReceive(Context context, Intent intent) {  
    2.         // TODO Auto-generated method stub  
    3.         if (intent.getAction().equals(  
    4.                 "com.example.widgettestone.WIDGET_CONTROL")) {  
    5.             AppWidgetManager manager = AppWidgetManager.getInstance(context);  
    6.             ComponentName thisWidget = new ComponentName(context, TaskPad.class);  
    7.             int[] appWidgetIds = manager.getAppWidgetIds(thisWidget);  
    8.             manager.notifyAppWidgetViewDataChanged(appWidgetIds,R.id.widget_list);//通知RemoteViews刷新数据,在渲染器中重写onDataSetChanged方法重写获取数据源  
    9.         } else {  
    10.             super.onReceive(context, intent);  
    11.         }  
    12.   
    13.     }  

    AndroidManifest.xml中widget的配置中添加:

    [html] view plaincopy
     
    1. <action android:name="com.example.widgettestone.WIDGET_CONTROL" />  


    当需要更新的时候发出该广播即可更新:

    [java] view plaincopy
     
    1. Intent intentUpdate = new Intent("com.example.widgettestone.WIDGET_CONTROL");  
    2. pan style="white-space:pre">        </span>context.sendBroadcast(intentUpdate);  

    四:小问题:

    (1):ListView的getview()中重复调用(position重复调用)问题:

    网友提供的解决方法:

    [java] view plaincopy
     
      1. 重写的listview adapter中,在getView()方法中,打印语句时,相同的position打印了多次,修改方法:  
      2. 将布局文件中ListView的高度改为“fill_parent”  
      3.  <ListView  
      4.    android:id="@+id/dynamic_list"  
      5.    android:layout_height="fill_parent"  
      6.    android:layout_width="fill_parent"  
      7.    android:scrollbars="vertical"  
      8.    android:layout_weight="1"  
      9.    android:drawSelectorOnTop="false"      
      10.    android:fadingEdgeLength="0dip"    
      11.    android:divider="@null"   
      12.    android:dividerHeight="0dip"  
      13.    android:cacheColorHint="#00000000"   
      14.    android:background="@color/listview_bg_color" />  

    原文:http://blog.csdn.net/limitemp/article/details/9101763

  • 相关阅读:
    Hadoop_HDFS文件读写代码流程解析和副本存放机制
    Hadoop_MapReduce流程
    Hadoop_YARN框架
    Spark任务流程笔记
    3D俄罗斯方块设计
    Hadoop_FileInputFormat分片
    二叉查找树的懒惰删除(lazy deletion)
    数组的三种随机排序方法
    SpringBoot @Async 异步处理业务逻辑和发短信逻辑
    json字符串转java对象
  • 原文地址:https://www.cnblogs.com/veins/p/3838450.html
Copyright © 2020-2023  润新知