在widget实现复杂布局(Listview,GirdView)以及RemoteViewsService、RemoteViewsFactory的用法

想做一个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中的每一列也是一个子项)。

2、 RemoteViewsService
上述代码已经介绍了,我下面把例子贴给大家
 

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;
	}
 
}

————————————————
版权声明:本文为CSDN博主「chinhape」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/chinhape/article/details/22278683

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值