android widget笔记

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

一:实现一个Activity配置widget

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

<appwidget-provider
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:minWidth="250dp"
  android:minHeight="180dp"
  android:updatePeriodMillis="0"
  android:initialLayout="@layout/widget_layout"
  android:resizeMode="vertical"
  android:configure="xx.widgets.ExampleAppWidgetConfigure" 
  android:previewImage="@drawable/ic_launcher">
</appwidget-provider>

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

Intent launchIntent = getIntent();
Bundle extras = launchIntent.getExtras();
if (extras != null) {
	
	appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,AppWidgetManager.INVALID_APPWIDGET_ID);
	Intent cancelResultValue = new Intent();
	cancelResultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetId);
	//未配置完成返回结果
	setResult(RESULT_CANCELED, cancelResultValue);
} else {
	// only launch if it's for configuration
	// Note: when you launch for debugging, this does prevent this
	// activity from running. We could also turn off the intent
	// filtering for main activity.
	// But, to debug this activity, we can also just comment the
	// following line out.
	finish();
}
if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) 
{
					
	Intent resultValue = new Intent();
	resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetId);
	//配置完成返回结果
	setResult(RESULT_OK, resultValue);
					
}

二:如何在RemoteViews中使用ListView

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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
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 = getDataSources();//获取数据源
			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.row);
			Intent intent = new Intent();
			// TODO
			// intent.setComponent(new ComponentName("包名", "类名"));
			// 与CustomWidget中remoteViews.setPendingIntentTemplate配对使用实现ListView中的Item的点击事件
			rv.setOnClickFillInIntent(R.id.widget_list_item_layout, intent);		
			rv.setTextViewText(android.R.id.text1, 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;
		}
	}
	
	public List<String>getDataSources() {
		List<String> list = new ArrayList<String>();
		......
		return list;
	}
}
(2):在widget的onUpdate中添加代码:

	for (int i = 0; i < appWidgetIds.length; i++) {//如果使用循环,当调试重新运行程序或者重启机器时widget点击事情会失灵
			Intent intent = new Intent(ctxt, WidgetService.class);
			RemoteViews widget = new RemoteViews(ctxt.getPackageName(),
					R.layout.widget);
			widget.setRemoteAdapter(appWidgetIds[i], R.id.words, intent);

			Intent clickIntent = new Intent(ctxt, LoremActivity.class);
			PendingIntent clickPI = PendingIntent.getActivity(ctxt, 0,
					clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
			widget.setPendingIntentTemplate(R.id.words, clickPI);//配合getViewAt方法中的setOnClickFillInIntent实现listView中Item的点击事件

			appWidgetManager.updateAppWidget(appWidgetIds[i], widget);
		}
(3):widget.xml

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/words"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:layout_marginTop="3dp"
  android:layout_marginLeft="3dp"
  android:background="@drawable/widget_frame"
/>

(4):row.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:gravity="center_vertical"
    android:paddingLeft="6dip"
    android:minHeight="?android:attr/listPreferredItemHeight"
/>
三:如何更新widget

(1):定时更新

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

  private void setAlarm(Context context, int appWidgetId, int updateRateSeconds) {
        Intent widgetUpdate = new Intent();
        widgetUpdate.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
        widgetUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { appWidgetId });

        // make this pending intent unique by adding a scheme to it
        widgetUpdate.setData(Uri.withAppendedPath(Uri.parse(ImagesWidgetProvider.URI_SCHEME + "://widget/id/"), String.valueOf(appWidgetId)));
        PendingIntent newPending = PendingIntent.getBroadcast(context, 0, widgetUpdate, PendingIntent.FLAG_UPDATE_CURRENT);

        // schedule the updating
        AlarmManager alarms = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        if (updateRateSeconds >= 0) {
            alarms.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), updateRateSeconds * 1000, newPending);
        } else {
            alarms.cancel(newPending);
        }
    }
(2):事件更新,不通过时间更新widget一般使用广播来更新

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

	}
AndroidManifest.xml中widget的配置中添加:
<action android:name="com.example.widgettestone.WIDGET_CONTROL" />

当需要更新的时候发出该广播即可更新:
		Intent intentUpdate = new Intent("com.example.widgettestone.WIDGET_CONTROL");
		context.sendBroadcast(intentUpdate);
四:小问题:

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

网友提供的解决方法:

重写的listview adapter中,在getView()方法中,打印语句时,相同的position打印了多次,修改方法:
将布局文件中ListView的高度改为“fill_parent”
 <ListView
   android:id="@+id/dynamic_list"
   android:layout_height="fill_parent"
   android:layout_width="fill_parent"
   android:scrollbars="vertical"
   android:layout_weight="1"
   android:drawSelectorOnTop="false"    
   android:fadingEdgeLength="0dip"  
   android:divider="@null" 
   android:dividerHeight="0dip"
   android:cacheColorHint="#00000000" 
   android:background="@color/listview_bg_color" />


Widget桌面小组件-Android学习笔记,总结到位 特点 – 快捷、方便 个性化、可定义功能 可及时控制更新Widget显示内容 用法步骤流程图 Created with Raphaël 2.1.2 绘制Widget布局 配置Widget的基本属性 定义AppWidgetProvider 提供Configuration Activity 学习目标 掌握Android Widget基础用法及步骤 Android Widget实现一个基本的时钟功能 效果 – 可以自动更新时间 可以添加删除时钟Widget 实验过程 阅读详情

相关推荐

安卓小部件(APPWidget)刷新源码解析一非列表

安卓小部件(AppWidget)刷新源码解析一列表。从收到刷新通知,到system_process进程,再到host进程,一步一步分析整个刷新流程。

挨踢人one的博客 1354

android桌面小部件appwidget使用ListView或者StackView如何刷新

如何刷新adapter中的数据先把结果贴上来。 使用如下方式,StackView的远端Adapter就会调用onDataSetChanged() AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(entry.widgetId,R.id.appwidget_stack_view);

qinxue24的博客 3989

Android Widget工作原理详解(一) 最全介绍

讲解怎么创建一个widget,并且给其点击事件,并介绍了其相关的类,以及widget的相关管理。 当widget指定其具体的AppWidgetProvider,AppWidgetProvider通过创建RemoteViews来加载视图,其RemoteViews将会调用setRemoteViewsAdapter来设置内部适配器,此适配器也将会继续获取widget管理器调用updateAppWidget()方法,此方法有会用远程视图工厂(RemoteViewsFactroy)来初始化数据并调用其onDataSe

Tamic (大白) 1万+

java/android 设计模式学习笔记(6)---适配器模式

这篇来介绍一下适配器模式(Adapter Pattern),适配器模式在开发中使用的频率也是很高的,像 ListView 和 RecyclerView 的 Adapter 等都是使用的适配器模式。在我们的实际生活中也有很多类似于适配器的例子,比如香港的插座和大陆的插座就是两种格式的,为了能够成功适配,一般会在中间加上一个电源适配器,形如:    这样就能够将原来不符合的现有系统和目标系统通过适配

Shawn_Dut的专栏 1万+

App Widget

App Widget是一种可以被放在其他应用中(如Launcher)并接收周期性更新的应用视图。这些视图在UI上就表现为Widget,并且你可以同App Widget Provider一起发布。 对于能够包含其他App Widget的应用程序组件,称为App Widget Host。 基本信息 要创建一个App Widget,你需要完成以下步骤: lAppWidgetProviderInf

lijinjinxuzhou的专栏 941

安卓笔记Widget

什么是Widget? App Widgetandroid提供的桌面小工具,它能够嵌入到桌面,并且可以定期更新自己的数据。 如下图所示: 如何创建Widget? 创建一个Widget需要以下几个组件: 1AppWidgetProviderInfo:这个类提供了Widget的元数据,比如Widget的布局,更新频率,大小等等。它通常都使用xml定义,位置

RowandJJ 1991

Simplenote for Android与Wear OS集成:移动端笔记的全新体验

Simplenote for Android是一款备受欢迎的开源笔记应用,它以简洁高效的设计理念帮助用户轻松管理日常笔记。随着智能穿戴设备的普及,Simplenote进一步拓展了其应用场景,通过与Wear OS的深度集成,为用户带来了更加便捷、无缝的移动端笔记体验。无论是在手机上快速记录灵感,还是通过智能手表随时查看重要信息,Simplenote都能满足你对笔记管理的各种需求。 ## 跨设备同步

gitblog_00597的博客 621

Android Widget学习笔记

学习目标: 1)掌握Widget的用途;2)掌握Widget的特点和用法步骤。 Widget的用途:类似便签 Widget特点:快捷、方便;个性化、可自定义功能;可及时控制更新Widget显示内容 Widget用法步骤: 1)绘制Widget布局;2)配置Widget的基本属性;3)定义AppWidgetProvider;4)提供Configuration Activity 学习目标:

dontletmedown的博客 433

EasyNotes Widget使用指南:在桌面快速创建与管理笔记的完整教程

想要在Android桌面上快速创建和管理笔记吗?EasyNotes的Widget功能让你无需打开应用即可快速访问笔记!🚀 本文将详细介绍EasyNotes Widget的完整使用方法,帮助你在桌面上高效管理笔记。 EasyNotes是一款基于Jetpack Compose MVVM架构设计的现代化笔记应用,以其简洁的设计和强大的功能受到用户喜爱。其中最实用的功能之一就是Widget支持,让你在

gitblog_00509的博客 920

Widget桌面小组件-Android学习笔记

Widget桌面小组件-Android学习笔记 本篇文章是学习widget笔记,参考学习了widget视频教程。 特点 快捷、方便 个性化、可定义功能 可及时控制更新Widget显示内容 用法步骤流程图 Created with Raphaël 2.1.2绘制Widget布局配置Widget的基本属性定义AppWidgetProvider提供Configurat...

fjnu_se的博客 531

Android开发笔记widget

参考资料 《Android Widget开发系列(一)》http://www.iteye.com/topic/406052 《Android 桌面组件【widget】初探》http://www.cnblogs.com/TerryBlog/archive/2010/07/29/1788319.html 《android widget 开发实例 : 桌面便签程序的实现详解和源码 (上)》ht

OneSea 976

Android学习笔记-widget

Widget桌面小组件-Android学习笔记 本篇文章是学习widget笔记,参考学习了widget视频教程。 特点 快捷、方便 个性化、可定义功能 可及时控制更新Widget显示内容 用法步骤流程图 xm=&amp;gt;operation: 绘制Widget布局 ch=&amp;gt;operation: 配置Widget的基本属性 pr=&amp;gt;operation: 定义A...

qq_41018182的博客 377

android widget 学习笔记

(1)创建一个类,让其继承类AppWidgetProvider,在AppWidgetProvider中有许多方法,例如onDelete(Context,int[]),onEnable(Context)等,但一般情况下我们只是覆写onUpdate(Context,AppWidgetManager,int[])方法。在该方法中,我们启动后台服务的类,一般是启动Thread类或者Android中的Ser

510

安卓学习笔记之使用widget桌面小控件及源码分析

安卓学习笔记之使用widget桌面小控件一、 使用步骤创建所需要的Receiver,并在清单文件中配置 <!-- 桌面小部件 --> <receiver android:name="com.yu.receiver.SaferAppWidgetProvider" > <intent-filter> <action android:

pecuyu 4315

Android学习笔记 - 插件篇 (Widget)

1.什么是App widget  Application Widget 应用程序插件 可以放置于桌面    1.AppWidgetProviderInfo对象   为App Widget提供元数据,包括布局,更新频率等等数据,被定义于XML文件中;    2.AppWidgetProvider   定义了App Widget的基本生命周期    2.创建一个App Widget

D!eR 个人博客 2448

Android 学习笔记Widget

记录贴,看到一篇关于AndroidAppwidget的文章,感觉不错,特此记录。网址:AndroidWidget

rebirth2009的专栏 359

android widget——ViewFlipper 学习笔记

ViewFlipper:          Simple ViewAnimator that will animate between two or more views that have been added to it. Only one child is shown at a time. If requested, can automatically flip between each

xiangyong2008的专栏 4281
上一篇: 关于proguard使用总结
下一篇: 使用eclipse编译jni代码遇到的问题记录
limitemp
博客等级 码龄16年 3粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值