RemoteViews嵌入ListView复杂布局

主要函数

public void setRemoteAdapter (int appWidgetId, int viewId, Intent intent)

当在widgets中使用集合(比如说ListView, StackView等等),在单独的一个条目中设置PendingIntents是非常浪费的,并且是不被允许的。然而一个单独的PendingIntents模板可以设置在集合里,参见setPendingIntentTemplate(int, PendingIntent),并且一个给定条目的单独的on-click的动作可以通过在条目上设置fillInIntent来区别。然后这个fillInIntent就和PendingIntent的实例结合在一起决定最终的被点击执行的intent。规定如下:在PendingIntent实例里,左边为空白的任何区域,但由fillInIntent提供的,将被重写,同时PendingIntent的结果将被使用。然后PendingIntent将被在fillInIntent中设置的有联系的字段填充。

public void setOnClickFillInIntent (int viewId, Intent fillInIntent)

当在widgets中使用集合(比如说ListView, StackView等等)时,在单独的一个条目中设置PendingIntent代价是很昂贵的,因此也是不被允许的。这个方法应该在集合中设置一个单独的PendingIntent模板,然后每一个单独的条目都可以通过setOnClickFillInIntent(int, Intent)来区别他们的点击事件。

public void setPendingIntentTemplate (int viewId, PendingIntent pendingIntentTemplate)

1.布局文件

在Mantifest中:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test.appwidget"
    android:versionCode="1"
    android:versionName="1.0" >
 
    <uses-sdk android:minSdkVersion="15" />
 
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        
        <receiver android:name=".CustomWidget">
            <intent-filter >
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE"></action>
            </intent-filter>
            <meta-data 
                android:name="android.appwidget.provider"
                android:resource="@xml/custom_widget">
            </meta-data>
        </receiver>
        
           <service 
            android:name=".UpdateService"
            android:permission="android.permission.BIND_REMOTEVIEWS"
            android:exported="false" >
        </service>
    </application>
 
</manifest>

在res/xml/下建立custom_widget.xml文件    

<?xml version="1.0" encoding="UTF-8"?>
<appwidget-provider 
    xmlns:android = "http://schemas.android.com/apk/res/android"
    android:minWidth="280dp"
    android:minHeight="280dp"
    android:initialLayout="@layout/widget_layout"
    android:updatePeriodMillis="0"> 
    <!-- sdk1.5之后updatePeriodMillis已失效,置为0,循环执行自行在代码中实现 -->
</appwidget-provider>

在res/layout/下建立widget_layout和widget_list_item布局文件

   widget_layout.xml

<?xml version="1.0" encoding="UTF-8"?>
<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000000">
    
    <ListView 
        android:id="@+id/widget_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="none"
        android:divider="@drawable/widget_list_divider"
        android:listSelector="@drawable/list_bg_selector" 
        android:layout_marginTop="4dp"
        android:layout_marginBottom="4dp"
        android:layout_marginLeft = "5dp"
        android:cacheColorHint="#00000000"/> 
    
</FrameLayout>

widget_list_item布局文件:

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout 
	xmlns:android = "http://schemas.android.com/apk/res/android"
    android:id = "@+id/widget_list_item_layout"
    android:layout_width = "fill_parent"
    android:layout_height = "fill_parent"
    android:background="#00000000"
    android:orientation="vertical"> 
  	<TextView 
    	android:id = "@+id/widget_list_item_tv"
        android:layout_width = "fill_parent"
        android:layout_height = "wrap_content"
        android:layout_marginTop = "10dip"
        android:layout_marginRight="10dip"
        android:layout_marginLeft = "20dp"
        android:lineSpacingExtra = "4dip"
    	android:textSize="20sp"
       	android:textColor="#FFFFF0"/>
</LinearLayout>

CustomWidget.java

package com.test.appwidget;
 
import java.util.ArrayList;
import java.util.List;
 
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
 
public class CustomWidget extends AppWidgetProvider{
 
	private static List<String> sList;
 
	static{
		sList = new ArrayList<String>();
		sList.add("第一条新闻");
		sList.add("第二条新闻");
		sList.add("第三条新闻");
		sList.add("第四条新闻");
		sList.add("第五条新闻");
		sList.add("第六条新闻");
	}
 
	private ComponentName thisWidget;
	private RemoteViews remoteViews;
 
	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){
 
		thisWidget = new ComponentName(context, CustomWidget.class);
		remoteViews = new RemoteViews(context.getPackageName(),	R.layout.widget_layout);
 
		Intent intent = new Intent(context, UpdateService.class);
		intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[0]);
		//设置适配器
		remoteViews.setRemoteAdapter(R.id.widget_list, intent);
 
		Intent intent2 = new Intent();
		//TODO
		//intent2.setComponent(new ComponentName("包名", "类名"));
		PendingIntent pendingIntentTemplate = PendingIntent.getActivity(context, 1, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
		
		//拼接PendingIntent
		remoteViews.setPendingIntentTemplate(R.id.widget_list, pendingIntentTemplate);
 
		//更新RemoteViews
		appWidgetManager.updateAppWidget(thisWidget, remoteViews);
		
		AppWidgetManager manager = AppWidgetManager.getInstance(context);
		manager.notifyAppWidgetViewDataChanged(appWidgetIds[0], R.id.widget_list);
	}
 
	@Override
	public void onDisabled(Context context) {
		super.onDisabled(context);
	}
 
 
	public static List<String> getList(){
		return sList;
	}
 
}

UpdateService.java

package com.test.appwidget;
 
import java.util.List;
 
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.Looper;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;
 
public class UpdateService extends RemoteViewsService {
 
	@Override
	public void onStart(Intent intent, int startId){
		super.onCreate();
	}
	@Override
	public IBinder onBind(Intent intent) {
		return super.onBind(intent);
	}
	@Override
	public RemoteViewsFactory onGetViewFactory(Intent intent) {
		return new ListRemoteViewsFactory(this.getApplicationContext(), intent);
	}
 
	class ListRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory{
 
		private final Context mContext;
		private final List<String> mList;
 
		public ListRemoteViewsFactory(Context context, Intent intent){
			mContext = context;
			mList = CustomWidget.getList();
 
			if(Looper.myLooper() == null){
				Looper.prepare();
			}
		}
 
		@Override
		public void onCreate() {
		}
 
		@Override
		public void onDataSetChanged() {
		}
 
		@Override
		public void onDestroy() {
			mList.clear();
		}
 
		@Override
		public int getCount() {
			return mList.size();
		}
 
		@Override
		public RemoteViews getViewAt(int position) {
			if(position<0 || position>=mList.size())
				return null;
			String content = mList.get(position);
			final RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_list_item);
 
			Intent intent = new Intent();
			//TODO
			//intent.setComponent(new ComponentName("包名", "类名"));
			//与CustomWidget中remoteViews.setPendingIntentTemplate配对使用
			rv.setOnClickFillInIntent(R.id.widget_list_item_layout, intent);
 
			rv.setTextViewText(R.id.widget_list_item_tv, content);
 
			return rv;
		}
 
		@Override
		public RemoteViews getLoadingView() {
			return null;
		}
 
		@Override
		public int getViewTypeCount() {
			return 1;
		}
 
		@Override
		public long getItemId(int position) {
			return position;
		}
 
		@Override
		public boolean hasStableIds() {
			return true;
		}
	}
}


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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Android 中,你可以使用 `Handler` 和 `postDelayed` 方法来实现定时更新 `RemoteViews`。以下是一个示例代码,展示如何在 `RemoteViews` 中实现定时更新: ```kotlin import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetProvider import android.content.Context import android.os.Handler import android.widget.RemoteViews class MyWidgetProvider : AppWidgetProvider() { private val updateInterval = 1000L // 更新间隔,单位为毫秒 override fun onUpdate( context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray ) { for (appWidgetId in appWidgetIds) { val views = RemoteViews(context.packageName, R.layout.widget_layout) // 创建 Handler 对象 val handler = Handler(context.mainLooper) // 创建一个 Runnable,用于更新 RemoteViews val updateRunnable = object : Runnable { override fun run() { // 更新 RemoteViews 中的内容 updateViews(views) // 延迟指定的时间后再次调用该 Runnable handler.postDelayed(this, updateInterval) } } // 开始调用 Runnable,实现定时更新 handler.postDelayed(updateRunnable, updateInterval) // 更新 App Widget 布局 appWidgetManager.updateAppWidget(appWidgetId, views) } } private fun updateViews(views: RemoteViews) { // 在这里更新 RemoteViews 的内容 // 例如可以使用 views.setTextViewText() 方法更新文本内容 } } ``` 在上述示例中,我们在 `onUpdate` 方法中创建了一个 `Handler` 对象,并定义了一个 `Runnable` 对象来更新 `RemoteViews` 的内容。我们使用 `handler.postDelayed` 方法来延迟指定的时间后再次调用 `Runnable`,从而实现定时更新。 你可以在 `updateViews` 方法中实现对 `RemoteViews` 的内容进行更新。例如,可以使用 `views.setTextViewText` 方法来更新文本内容。 希望这个示例对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值