想做一个widget里面包含listview的复杂布局,于是查了些资料。整理了一下,形成自己的思路,把它写下来。第一次写,希望多给些意见。
我想先从我要实现的界面开始介绍起,请大家耐心读完它
首先是这样一个界面,这是在widget里面的布局,可以看到的是这个widget布局里面 有两部分需要处理,一是图标“花”点击之后应该有个动作,第二是如何处理listview的数据。而我要实现的是动态加载listview的数据,数据来源于数据库。
了解过widget的同学应该知道实现widget,首先需要重写AppWidgetProvider,而我们要实现listview还需要另外两个类,RemoteViewsService、RemoteViewsFactory,准备好三个类之后才能进行下面详细的实施,至于这三者的作用我将会详细的介绍给大家。
1、RemoteViews 和AppWidgetProvider
RemoteViews翻译为远程试视图,是widget里面操作视图时必须用的,创建widget时,只需继承AppwidgetProvider,然后重写里面的Update就可以了。
像这样:
public class WidgetProvider extends AppWidgetProvider{
private AppWidgetManager appWidgetManager; private int[] appWidgetIds; private Context context; @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); } }然后再onUpdate里面处理RemoteViews,下面具体根据我这个案例,介绍怎么处理Remoteviews
this.appWidgetIds = appWidgetIds; this.appWidgetManager = appWidgetManager; this.context = context; Timer timer = new Timer();//时时更新 timer.schedule(new TimerTask() { @Override public void run() { // TODO Auto-generated method stub for (int i = 0; i < WidgetProvider.this.appWidgetIds.length; i++)// appWidgetIds.length,表示创建了多少个widget { Intent ServiceIntent = new Intent(WidgetProvider.this.context, WidgetService.class); // 创建一个intent,启动WidgetService,WidgetService事继承的RemoteViewsService,返回一个RemoteViewsFactory ServiceIntent.putExtra(WidgetProvider.this.appWidgetManager.EXTRA_APPWIDGET_ID, WidgetProvider.this.appWidgetIds[i]); ServiceIntent.setData(Uri.parse(ServiceIntent.toUri(ServiceIntent.URI_INTENT_SCHEME))); // 设置uri,我不太清楚的地方是这边的uri是怎么获取到的,是根据刚开始new的时候得出的URI吗? RemoteViews widgetRemoteView = new RemoteViews(WidgetProvider.this.context .getPackageName(), R.layout.widget); widgetRemoteView.setRemoteAdapter(WidgetProvider.this.appWidgetIds[i], R.id.widget_content_list_view, ServiceIntent); // 走到这里大家应该可以看出处理Listview需要用SetRemoteAdapter,和ServiceIntent返回的值 Intent logoIntent = new Intent(WidgetProvider.this.context, MainActivity.class);// 设置点击的intent PendingIntent clickPendingIntent = PendingIntent.getActivity(WidgetProvider.this.context, 0, logoIntent, PendingIntent.FLAG_CANCEL_CURRENT); // 这边不知道干吗的?有懂的回复评论谢谢。 widgetRemoteView .setPendingIntentTemplate(R.id.widget_logo_image_view, clickPendingIntent);// 和楼上要结合使用 WidgetProvider.this.appWidgetManager.updateAppWidget(WidgetProvider.this.appWidgetIds[i], widgetRemoteView); } } }, 0, 1000);
RemoteViewsService,是管理RemoteViews的服务。
一般,当App Widget 中包含“GridView、ListView、StackView等”集合视图时,才需要使用RemoteViewsService来进行更新、管理。(集合视图是指GridView、ListView、StackView等包含子元素的视图)
RemoteViewsService更新“集合视图”的一般步骤是:
(01) 通过setRemoteAdapter来设置 “RemoteViews对应RemoteViewsService”。
(02) 之后在RemoteViewsService中,实现RemoteViewsFactory接口。然后,在RemoteViewsFactory接口中对“集合视图”的各个子项进行设置(“集合视图”的各个子项:例如,GridView的每一个格子都是一个子项;ListView中的每一列也是一个子项)。
上述代码已经介绍了,我下面把例子贴给大家
public class WidgetService extends RemoteViewsService{ @Override public RemoteViewsFactory onGetViewFactory(Intent intent) { // TODO Auto-generated method stub return new WidgetFactory(this,intent); } }可以看到的是,所有的数据处理都在factory,那下面就来进行数据处理的过程
3、RemoteViewsFactory
RemoteViewsFactory是RemoteViewsService中的一个接口。RemoteViewsFactory提供了一系列的方法管理“集合视图”中的每一项。例如:
(01)RemoteViews getViewAt(int position)
通过getViewAt()来获取“集合视图”中的第position项的视图,视图是以RemoteViews的对象返回的。
(02)int getCount()
通过getCount()来获取“集合视图”中所有子项的总数。
大家只需关注以上两个函数,例子代码中的其他函数基本功能都是获取数据,至于如何获取,请大家认真开代码和注解
import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.widget.RemoteViews; import android.widget.RemoteViewsService.RemoteViewsFactory; public class WidgetFactory implements RemoteViewsFactory { private Context context; private int appwidgetId; private Cursor cursor; private int[] typeImageViews = {R.drawable.metting_menu, R.drawable.memo_menu, R.drawable.memorialday_menu, R.drawable.todo_menu}; private String timeAndAdressStrings; private String titleStrings; private String TIMEANDADRESS = "timeAndAdress"; private String TITLE = "title"; private String TYPE = "type"; private ArrayList<HashMap<String, Object>> data; private MyDatabaseHelper myDatabaseHelper; public WidgetFactory(Context context, Intent intent) { // TODO Auto-generated constructor stub this.context = context; this.cursor = WidgetData.QueryData(context); myDatabaseHelper = new MyDatabaseHelper(context, 1); } @Override public void onCreate() { // TODO Auto-generated method stub InitListViewData(); } // 初始化DATA private void InitListViewData() { data = new ArrayList<HashMap<String, Object>>(); cursor.moveToFirst(); for (int i = 0; i < cursor.getCount(); i++) { HashMap<String, Object> map = new HashMap<String, Object>(); String timeString = cursor.getString(cursor.getColumnIndex(myDatabaseHelper.time)); String adressString = cursor.getString(cursor.getColumnIndex(myDatabaseHelper.adress)); String titleString = cursor.getString(cursor.getColumnIndex(myDatabaseHelper.title)); //将数据库数据全部取出来,生成字符的形式 int type = cursor.getInt(cursor.getColumnIndex(myDatabaseHelper.typeid)); timeAndAdressStrings = timeString + "," + adressString; titleStrings = titleString; map.put(TIMEANDADRESS, timeAndAdressStrings); map.put(TITLE, titleStrings); map.put(TYPE, type); data.add(map);//用hashmap处理数据,再在getviewAt中处理hashmap的数据 } } @Override public void onDataSetChanged() { // TODO Auto-generated method stub } @Override public void onDestroy() { // TODO Auto-generated method stub data.clear(); } @Override public int getCount() { // TODO Auto-generated method stub return cursor.getCount(); } @Override public RemoteViews getViewAt(int position) { // TODO Auto-generated method stub HashMap<String, Object> map; RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_listview_single_item);//获取item的视图 map = data.get(position);//获取数据 remoteViews.setImageViewResource(R.id.widget_single_list_view_item_type_image_view, typeImageViews[(Integer) map.get(TYPE)]); remoteViews.setTextViewText(R.id.widget_single_view_item_time_and_adress_text_view, (CharSequence) map.get(TIMEANDADRESS)); remoteViews.setTextViewText(R.id.widget_single_view_item_title_text_view, (CharSequence) map.get(TITLE));//处理数据 return remoteViews; } @Override public RemoteViews getLoadingView() { // TODO Auto-generated method stub return null; } @Override public int getViewTypeCount() { // TODO Auto-generated method stub return 1; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public boolean hasStableIds() { // TODO Auto-generated method stub return true; } }如果需要代码,私信我
在widget实现复杂布局(Listview,GirdView)以及RemoteViewsService、RemoteViewsFactory的用法,布布扣,bubuko.com
在widget实现复杂布局(Listview,GirdView)以及RemoteViewsService、RemoteViewsFactory的用法
原文:http://blog.csdn.net/chinhape/article/details/22278683