<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                #### 5.1.2 RemoteViews在桌面小部件上的應用 AppWidgetProvider是Android中提供的用于實現桌面小部件的類,其本質是一個廣播,即BroadcastReceiver,圖5-2所示的是它的類繼承關系。所以,在實際的使用中,把AppWidgetProvider當成一個BroadcastReceiver就可以了,這樣許多功能就很好理解了。 :-: ![](https://img.kancloud.cn/02/78/0278fa8d7c2f9deacb06489d2648c6d5_1356x454.png) 圖5-2 AppWidgetProvider的類繼承關系 為了更好地展示RemoteViews在桌面小部件上的應用,我們先簡單介紹桌面小部件的開發步驟,分為如下幾步。 * 1.定義小部件界面 在res/layout/下新建一個XML文件,命名為widget.xml,名稱和內容可以自定義,看這個小部件要做成什么樣子,內容如下所示。 <? xml version="1.0" encoding="utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon1" /> </LinearLayout> * 2.定義小部件配置信息 在res/xml/下新建appwidget_provider_info.xml,名稱隨意選擇,添加如下內容: <? xml version="1.0" encoding="utf-8"? > <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:initialLayout="@layout/widget" android:minHeight="84dp" android:minWidth="84dp" android:updatePeriodMillis="86400000" > </appwidget-provider> 上面幾個參數的意義很明確,initialLayout就是指小工具所使用的初始化布局,minHeight和minWidth定義小工具的最小尺寸,updatePeriodMillis定義小工具的自動更新周期,毫秒為單位,每隔一個周期,小工具的自動更新就會觸發。 * 3.定義小部件的實現類 這個類需要繼承AppWidgetProvider,代碼如下: public class MyAppWidgetProvider extends AppWidgetProvider { public static final String TAG = "MyAppWidgetProvider"; public static final String CLICK_ACTION = "com.ryg.chapter_5.action. CLICK"; public MyAppWidgetProvider() { super(); } @Override public void onReceive(final Context context, Intent intent) { super.onReceive(context, intent); Log.i(TAG, "onReceive : action = " + intent.getAction()); // 這里判斷是自己的action,做自己的事情,比如小部件被單擊了要干什么,這里是做 一個動畫效果 if (intent.getAction().equals(CLICK_ACTION)) { Toast.makeText(context, "clicked it", Toast.LENGTH_SHORT).show(); new Thread(new Runnable() { @Override public void run() { Bitmap srcbBitmap = BitmapFactory.decodeResource( context.getResources(), R.drawable.icon1); AppWidgetManager appWidgetManager = AppWidgetManager. getInstance(context); for (int i = 0; i < 37; i++) { float degree = (i * 10) % 360; RemoteViews remoteViews = new RemoteViews(context .getPackageName(), R.layout.widget); remoteViews.setImageViewBitmap(R.id.imageView1, rotateBitmap(context, srcbBitmap, degree)); Intent intentClick = new Intent(); intentClick.setAction(CLICK_ACTION); PendingIntent pendingIntent = PendingIntent .getBroadcast(context, 0, intentClick, 0); remoteViews.setOnClickPendingIntent(R.id.imageView1, pendingIntent); appWidgetManager.updateAppWidget(new ComponentName( context, MyAppWidgetProvider.class), remoteViews); SystemClock.sleep(30); } } }).start(); } } /** * 每次桌面小部件更新時都調用一次該方法 */ @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); Log.i(TAG, "onUpdate"); final int counter = appWidgetIds.length; Log.i(TAG, "counter = " + counter); for (int i = 0; i < counter; i++) { int appWidgetId = appWidgetIds[i]; onWidgetUpdate(context, appWidgetManager, appWidgetId); } } /** *桌面小部件更新 * * @param context * @param appWidgeManger * @param appWidgetId */ private void onWidgetUpdate(Context context, AppWidgetManager appWidgeManger, int appWidgetId) { Log.i(TAG, "appWidgetId = " + appWidgetId); RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget); // “桌面小部件”單擊事件發送的Intent廣播 Intent intentClick = new Intent(); intentClick.setAction(CLICK_ACTION); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentClick, 0); remoteViews.setOnClickPendingIntent(R.id.imageView1, pendingIntent); appWidgeManger.updateAppWidget(appWidgetId, remoteViews); } private Bitmap rotateBitmap(Context context, Bitmap srcbBitmap, float degree) { Matrix matrix = new Matrix(); matrix.reset(); matrix.setRotate(degree); Bitmap tmpBitmap = Bitmap.createBitmap(srcbBitmap, 0, 0, srcbBitmap.getWidth(), srcbBitmap.getHeight(), matrix, true); return tmpBitmap; } } 上面的代碼實現了一個簡單的桌面小部件,在小部件上面顯示一張圖片,單擊它后,這個圖片就會旋轉一周。當小部件被添加到桌面后,會通過RemoteViews來加載布局文件,而當小部件被單擊后的旋轉效果則是通過不斷地更新RemoteViews來實現的,由此可見,桌面小部件不管是初始化界面還是后續的更新界面都必須使用RemoteViews來完成。 * 4.在AndroidManifest.xmI中聲明小部件 這是最后一步,因為桌面小部件本質上是一個廣播組件,因此必須要注冊,如下所示。 <receiver android:name=".MyAppWidgetProvider" > <meta-data android:name="android.appwidget.provider" android:resource="@xml/appwidget_provider_info" > </meta-data> <intent-filter> <action android:name="com.ryg.chapter_5.action.CLICK" /> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> </receiver> 上面的代碼中有兩個Action,其中第一個Action用于識別小部件的單擊行為,而第二個Action則作為小部件的標識而必須存在,這是系統的規范,如果不加,那么這個receiver就不是一個桌面小部件并且也無法出現在手機的小部件列表里。 AppWidgetProvider除了最常用的onUpdate方法,還有其他幾個方法:onEnabled、onDisabled、onDeleted以及onReceive。這些方法會自動地被onReceive方法在合適的時間調用。確切來說,當廣播到來以后,AppWidgetProvider會自動根據廣播的Action通過onReceive方法來自動分發廣播,也就是調用上述幾個方法。這幾個方法的調用時機如下所示。 * onEnable:當該窗口小部件第一次添加到桌面時調用該方法,可添加多次但只在第一次調用。 * onUpdate:小部件被添加時或者每次小部件更新時都會調用一次該方法,小部件的更新時機由updatePeriodMillis來指定,每個周期小部件都會自動更新一次。 * onDeleted:每刪除一次桌面小部件就調用一次。 * onDisabled:當最后一個該類型的桌面小部件被刪除時調用該方法,注意是最后一個。 * onReceive:這是廣播的內置方法,用于分發具體的事件給其他方法。 關于AppWidgetProvider的onReceive方法的具體分發過程,可以參看源碼中的實現,如下所示。通過下面的代碼可以看出,onReceive中會根據不同的Action來分別調用onEnable、onDisable和onUpdate等方法。 public void onReceive(Context context, Intent intent) { // Protect against rogue update broadcasts (not really a security issue, // just filter bad broacasts out so subclasses are less likely to crash). String action = intent.getAction(); if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) { Bundle extras = intent.getExtras(); if (extras ! = null) { int[] appWidgetIds = extras.getIntArray(AppWidgetManager. EXTRA_APPWIDGET_IDS); if (appWidgetIds ! = null && appWidgetIds.length > 0) { this.onUpdate(context, AppWidgetManager.getInstance (context), appWidgetIds); } } } else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) { Bundle extras = intent.getExtras(); if (extras ! = null && extras.containsKey(AppWidgetManager.EXTRA_ APPWIDGET_ID)) { final int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_ APPWIDGET_ID); this.onDeleted(context, new int[] { appWidgetId }); } } else if (AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED.equals (action)) { Bundle extras = intent.getExtras(); if (extras ! = null && extras.containsKey(AppWidgetManager.EXTRA_ APPWIDGET_ID) && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ OPTIONS)) { int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_ APPWIDGET_ID); Bundle widgetExtras = extras.getBundle(AppWidgetManager.EXTRA_ APPWIDGET_OPTIONS); this.onAppWidgetOptionsChanged(context, AppWidgetManager. getInstance(context), appWidgetId, widgetExtras); } } else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) { this.onEnabled(context); } else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) { this.onDisabled(context); } else if (AppWidgetManager.ACTION_APPWIDGET_RESTORED.equals(action)) { Bundle extras = intent.getExtras(); if (extras ! = null) { int[] oldIds = extras.getIntArray(AppWidgetManager.EXTRA_ APPWIDGET_OLD_IDS); int[] newIds = extras.getIntArray(AppWidgetManager.EXTRA_ APPWIDGET_IDS); if (oldIds ! = null && oldIds.length > 0) { this.onRestored(context, oldIds, newIds); this.onUpdate(context, AppWidgetManager.getInstance (context), newIds); } } } } 上面描述了開發一個桌面小部件的典型過程,例子比較簡單,實際開發中會稍微復雜一些,但是開發流程是一樣的。可以發現,桌面小部件在界面上的操作都要通過Remote-Views,不管是小部件的界面初始化還是界面更新都必須依賴它。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看