赞
踩
1.生命周期
2.怎么处理点击事件
3.怎么创建集合
4.怎么处理动画效果
1.1 添加小组件的生命周期
onEnabled:
onReceive:
onUpdate:
onReceive:
onAppWidgetOptionsChanged:
onReceive:
1.2 移除小组件的生命周期
onDeleted:
onReceive:
onDisabled:
onReceive:
这个问题解决方案的关键是 设置广播action
<receiver android:name=".listWidget.ListWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.zg.todesk.CLICK" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/listwidget" />
</receiver>
这里添加的是
<action android:name="com.zg.todesk.CLICK" />
然后再组件中,发送广播,就能在onReceive中收到消息,然后做相应的处理就好
val pendingIntent = PendingIntent.getBroadcast(
context,
0,
Intent(context, MuyuAppWidget::class.java).apply {
action = "com.zg.todesk.CLICK"
},
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
views.setOnClickPendingIntent(R.id.rl_muyu, pendingIntent)//这里选择最大的控件
然后onReceive处理消息
override fun onReceive(context: Context?, intent: Intent?) {
super.onReceive(context, intent)
Log.e("zxd", "onReceive: ${intent!!.action}")
if (intent!!.action == "com.zg.zanglidemo.ANIM") {
...
}
}
这里简单的举一个例子。
<?xml version="1.0" encoding="UTF-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/list_widget_layout"
android:minWidth="280dp"
android:minHeight="280dp"
android:updatePeriodMillis="0">
<!-- sdk1.5之后updatePeriodMillis已失效,置为0,循环执行自行在代码中实现 -->
</appwidget-provider>
<!-- list widget -->
<receiver android:name=".listWidget.ListWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.zg.todesk.CLICK" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/listwidget" />
</receiver>
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.util.Log; import android.widget.RemoteViews; import com.zg.todesk.MainActivity; import com.zg.todesk.R; import java.util.ArrayList; import java.util.List; /*** * @Author: zxd * @CreateDate: 2024/5/11 8:25:03 * @Description: */ public class ListWidget extends AppWidgetProvider { private static List<String> sList; static { sList = new ArrayList<>(); 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, ListWidget.class); remoteViews = new RemoteViews(context.getPackageName(), R.layout.list_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(context, MainActivity.class); //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; } @Override public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); //在这里可以添加 if (intent.getAction().equals("com.zg.todesk.CLICK")) { Log.i("zxd", "onReceive: " + intent.getStringExtra("val")); } } }
<?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:layout_marginLeft="5dp" android:layout_marginTop="4dp" android:layout_marginBottom="4dp" android:cacheColorHint="#00000000" android:scrollbars="none" /> <!-- android:divider="@drawable/widget_list_divider" android:listSelector="@drawable/list_bg_selector"--> </FrameLayout>
import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.IBinder; import android.os.Looper; import android.widget.RemoteViews; import android.widget.RemoteViewsService; import com.zg.todesk.MainActivity; import com.zg.todesk.R; import java.util.List; 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 = ListWidget.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.putExtra("val", content); //与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; } } }
<service
android:name=".listWidget.UpdateService"
android:exported="false"
android:permission="android.permission.BIND_REMOTEVIEWS" />
要想小组件有动画效果,就需要点击配合layoutAnimation才能实现动画效果
小组件布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" style="@style/Widget.ZangliDemo.AppWidget.Container" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg_raidus" android:id="@+id/rl_muyu" android:theme="@style/AppTheme.AppWidgetContainer"> <LinearLayout android:id="@+id/ll_muyu" android:layout_width="140dp" android:layout_height="140dp" android:gravity="center_horizontal" android:orientation="vertical"> <TextView android:id="@+id/appwidget_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:contentDescription="测试桌面木鱼" android:text="已敲0次" android:textColor="@color/gray_8f" android:textSize="18sp" android:textStyle="bold" /> <RelativeLayout android:id="@+id/muyu_rl" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/widget_muyu_iv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerHorizontal="true" android:layout_margin="15dp" android:src="@mipmap/muyu" /> </RelativeLayout> </LinearLayout> </RelativeLayout>
实现效果
private fun doAnimation(context: Context?, remoteViews: RemoteViews?) {
remoteViews?.removeAllViews(R.id.muyu_rl)
val remoteViews2 = RemoteViews(context?.packageName, R.layout.anim_layout)
remoteViews2.setImageViewResource(R.id.widget_muyu_iv, R.mipmap.muyu)
remoteViews?.addView(R.id.muyu_rl, remoteViews2)
clickNum++
Log.e("zxd", "doAnimation: $clickNum")
remoteViews?.setTextViewText(R.id.appwidget_text, "已敲${clickNum}次")
}
动画效果(anim_layout)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layoutAnimation="@anim/muyu_anim">
<ImageView
android:id="@+id/widget_muyu_iv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@mipmap/muyu" />
</RelativeLayout>
muyu_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:animation="@anim/scale_anim" />
scale_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="100"
android:fromXScale="0.9"
android:fromYScale="0.9"
android:interpolator="@android:anim/accelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1"
android:toYScale="1" />
在widget实现复杂布局(Listview,GirdView)以及RemoteViewsService、RemoteViewsFactory的用法
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。