StackView Widget

將StackView 使用在桌面小工具

  • layout中新增StackView

    <StackView
          android:id="@+id/stack_view"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:gravity="center"
          android:loopViews="true" />
    
  • 在res新增directory並新增xml resourse

<appwidget-provider
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="120dp"
    android:minHeight="120dp"
    android:initialLayout="@layout/widget_layout"
    android:resizeMode="horizontal|vertical" 
    android:autoAdvanceViewId="@id/stack_view"/> 
</appwidget-provider>
android:autoAdvanceViewId    自動更新畫面
  • 新增class繼承AppWidgetprovider
  @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        for (int i = 0; i < appWidgetIds.length; ++i) {

            Intent intent = new Intent(context, StackWidgetService.class);
            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
            intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
            RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
            remoteViews .setRemoteAdapter(appWidgetIds[i], R.id.stack_view, intent);


            //不能在每項item設置pending Intent 所以將全部通一設置成PendingIntentTemplate
            Intent toastIntent = new Intent(context, StackWidgetProvider.class);
            toastIntent.setAction(TOAST_ACTION);
            intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
            PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
            remoteViews .setPendingIntentTemplate(R.id.stack_view, toastPendingIntent);

            appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
        }
        super.onUpdate(context, appWidgetManager, appWidgetIds);
    }
@Override
    public void onReceive(Context context, Intent intent) {

        if (intent.getAction().equals(TOAST_ACTION)) {
            int viewIndex = intent.getIntExtra(EXTRA_ITEM, 0);
            Toast.makeText(context, "Touched view " + viewIndex, Toast.LENGTH_SHORT).show();
        }

        super.onReceive(context, intent);
    }
  • 新增class繼承RemoteViewsService
@Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) {

       //widget 中包含ListView、StackView時才需要用到RemoteViewsService管理
        return new StackRemoteViewsFactory(this.getApplicationContext(), intent);
    }
  • StackRemoteViewsFactory
class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
        private static final int mCount = 10;
        private List<WidgetItem> mWidgetItems = new ArrayList<>();
        private Context mContext;
        private int mAppWidgetId;

        public StackRemoteViewsFactory(Context context, Intent intent) {
            mContext = context;
            mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                    AppWidgetManager.INVALID_APPWIDGET_ID);
        }

        public void onCreate() {
            for (int i = 0; i < mCount; i++) {
                mWidgetItems.add(new WidgetItem(i + "!"));
            }

        }

        public int getCount() {
            return mCount;
        }

        public RemoteViews getViewAt(int position) {
             //用xml 建立 RemoteViews
            RemoteViews remoteViews = new RemoteViews(mContext.getPackageName(), R.layout.widget_item);

             remoteViews.setTextViewText(R.id.widget_item, mWidgetItems.get(position).text);

        //   設定fillIn intent 可區分Item單獨點擊
            Bundle extras = new Bundle();
            extras.putInt(StackWidgetProvider.EXTRA_ITEM, position);
            Intent fillInIntent = new Intent();
            fillInIntent.putExtras(extras);
            remoteViews.setOnClickFillInIntent(R.id.widget_item, fillInIntent);

            return remoteViews;
        }


        public int getViewTypeCount() {
            return 1;
        }

        public long getItemId(int position) {
            return position;
        }
  • 最後記得在AndroidManifest註冊
     <receiver  android:name="StackWidgetProvider">
         <intent-filter>
               <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
         </intent-filter>
         <meta-data android:name="android.appwidget.provider"
                    android:resource="@xml/stackwidgetinfo" />
     </receiver>

     <service   android:name="StackWidgetService"
           android:permission="android.permission.BIND_REMOTEVIEWS"
           android:exported="false" />