您的位置:首页 > 其它

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

2014-03-27 16:15 549 查看
想做一个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;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐