Android UIコンポーネントAppWidgetコントロール入門の詳細


Widget導入 
私たちはWidgetをデスクトップの上に置いてある小さい部品(ペンダント)として理解できます。Widgetがあります。私たちは直接にデスクトップで様々な操作ができます。例えば音楽を再生します。 
デスクトップを長押しすると、Widgetのオプションが見えます。 

上の矢印のwidgetsアイコンをクリックすると、次のような画面が表示されます。 

上の図のいずれかのwidgetを長押してデスクトップに置くことができます。 
Widgetの使用
Widgetの実現構想 
(1)Android ManifestでApWidgetを宣言する; 
(2)appWidgetのプロファイルをxmlディレクトリに定義する。 
(3)layoutディレクトリにWidgetのレイアウトファイルを定義する。 
(4)新しいクラスを作成し、App Widget Provider類を継承し、具体的なwidget業務ロジックを実現する。 
私たちは新しいクラスを作る必要があります。アプリWidget Providerを引き継ぎます。アプリWidget Providerを点けば、App Widget ProviderがBroadcastReceiverから継承されていることが分かります。 
なぜWidgetは放送受信機ですか?我々は、BroadcastReceiver類の中にラジオ放送を受信するためのonReceive方法があることを知っています。私達がデスクトップのペンダントの上で操作する時、必然的に応用の変化を引き起こして、これはペンダントと応用の間の通信に関連して、この時ラジオで通信するのは更に良いです。 
Widgetの具体的な使用手順 
(1)Test Widget.javaを新規作成し、App Widget Providerを継承する:
 Test Widget.java: 

import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
/**
 * Created by smyhvae on 2016/9/7.
 */
public class TestWidget extends AppWidgetProvider{
 @Override
 public void onReceive(Context context, Intent intent) {
  super.onReceive(context, intent);
 }
} 
(2)Widgetはブロードキャスト受信機であるため、リストファイルに登録する必要があります。

 <!--   widget   AppWidgetProvider -->
  <receiver android:name=".TestWidget">
   <intent-filter>
    <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
   </intent-filter>
   <meta-data
    android:name="android.appwidget.provider"
    android:resource="@layout/widget_setting"/>
  </receiver> 
04行:actionはフィルタリング条件であり、動作をフィルタリングし、widgetの更新を監視する。
08行:android:resourceはwidgetの配置を指定しました。属性はリストファイルにデータを保存するために使われていることを知っています。 
(3)ラyoutフォルダに新しいファイルwidget_setting.xml:(widgetのプロファイル)
 セットニングwidget.xml: 

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:initialLayout="@layout/layout_widget"
     android:minHeight="140dp"
     android:minWidth="140dp"
     android:previewImage="@mipmap/ic_launcher"
     android:updatePeriodMillis="20000"
     android:widgetCategory="home_screen"
 >
</appwidget-provider> 
08行:android:initial Layoutはwidgetのレイアウトを指定しました。
09行:android:udatePeriodMillis更新の時間周期を指定します。
10行:android:widget Category=「home_」screen「widgetをホーム画面に表示する(スクリーンロックに表示することもできます)。
(4)ラyoutフォルダに新規ファイルのラyout_widget.xml:(widgetのレイアウト)
 ラyout_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">
 <TextView
  android:id="@+id/textView"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_gravity="center_horizontal"
  android:text="Large Text"
  android:textAppearance="?android:attr/textAppearanceLarge"/>
 <Button
  android:id="@+id/button2"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_gravity="center_horizontal"
  android:text="New Button"/>
</LinearLayout> 
これでプログラムは走れます。プログラムを実行した後、デスクトップを長く押して、「Widget」ボタンを押してください。私たちがデザインしたばかりのwidgetが見えます。 

上の図の矢印を長く押すと、私達が設計したwidgetをデスクトップにドラッグして置くことができます。 

Widgetのクリックと更新【重要】 
私たちは、Test Widget.javaがApp Widget Providerから継承されていることを知っています。App Widget ProviderはBroadcastReceiverを継承した後、OReceive方法を書き換えて、多くの方法をカスタマイズしました。 

上図には、削除時、無効時、有効時、更新された時など、様々な方法が含まれています。特に重要なのはonReceive()方法とonUpDate()方法です。
 ウィジェットが変更された場合(例えばデスクトップにインストールされた場合)、システムは更新されたブロードキャストを送信します(上の図の赤枠の部分に示されています)。私たちはセットしていますwidget.xmlにはwidgetの更新頻度が設定されています。これも更新を呼びます。 
ある人が聞きますが、電源を入れてから天気などのwidgetはなぜ更新しないですか?これはプロセスが殺されたからです。私たちはこのコントロールを先に取り除いてからインストールします。この時にアプリはアップデートの放送があります。 
widgetのクリックと更新が必要な場合は、OnUpdate()を書き換える方法が必要です。放送を送ります。プログラムを初期化すると、システムはOUpdate()メソッドを呼び出します。 
onUpdate()メソッドのコードは以下の通りです。

  @Override
 public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
  super.onUpdate(context, appWidgetManager, appWidgetIds);
  RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.layout_widget);//      RemoteViews
  Intent intent = new Intent();
  intent.setClass(context, TestWidget.class); //  intent     TestWidget  ,TestWidget       ,   。。        // 。
  intent.setAction(WIDGET_BTN_ACTION);
  PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
  remoteViews.setOnClickPendingIntent(R.id.widget_btn, pendingIntent);//  btn_widget     :     ,     action   。
  appWidgetManager.updateAppWidget(appWidgetIds, remoteViews); //      ,      。
 } 
コードの説明:
まずnew一つのRemoteViewが必要です。構造方法には二つのパラメータが必要です。一つはパッケージ名です。一つはレイアウトファイルです。widget。
 そしてremoteViews.set OnClickPendingIntent()設定ボタンのクリックイベントを通じて。set OnClickPendingIntent()では二つのパラメータを渡す必要があります。一つはidです。一つはPendingIntentです。PendingIntentは未来の意図です。
 そこで私たちは事前にPendingIntentを構成しておく必要があります。これはPendingIntent.get Broadcast()を通じて構成します。get Broadcast()法では4つのパラメータを伝達する必要があり、そのうちの一つはIntentである。
 そこで私たちはIntentを作る必要があります。intentで放送を送り、アクションを設定します。
 ボタンをクリックした後、appWidgetManager.udateApple Widget(int[appWidgetIds],RemoteViews views)を呼び出して更新してください。最初のパラメータはonUpdateメソッドのパラメータで、すべてのコントロールを表しています。 
OnUpdate()メソッドでは、ボタンを押して時間の放送を送信した後、OneReceive()メソッドで放送の受信が必要です。
 onReceive()メソッドのコードは以下の通りです。 

 @Override
 public void onReceive(Context context, Intent intent) {
  super.onReceive(context, intent);
  if (intent != null && TextUtils.equals(intent.getAction(), WIDGET_BTN_ACTION)) { // intent   , action     ,     ,        
   Log.i(WIDGET_BTN_ACTION, "is clicked");
   //               
   RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.layout_widget);//  :  【  】    RemoteViews
   remoteViews.setTextViewText(R.id.widget_tv, "be clicked");
   remoteViews.setTextColor(R.id.widget_tv, Color.RED);
   AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);//     
   ComponentName componentName = new ComponentName(context, TestWidget.class);
   appWidgetManager.updateAppWidget(componentName, remoteViews);//setText  ,      
  }
 } 
コードの説明:
 intentのactionマッチングが成功すると、クリック時間後のset Textを実行し始めますが、ここではRemoteViewを再利用し、onUpdate()メソッドのRemoteViewを共有することができません。
 クリックした後のsetTextを実行した後、appWidgetManager.udateApple Widget(ComponentName,RemoteView)メソッドを呼び出してください。一番目のパラメータはコンポーネント名です。自分達がnewしてください。二つ目のパラメータは説明しやすいです。 
総合的に、Test Widget.javaの完全版コードは以下の通りです。
Testwidget.java:

 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.graphics.Color;
import android.text.TextUtils;
import android.util.Log;
import android.widget.RemoteViews;
/**
 * Created by smyhvae on 2016/9/7.
 */
public class TestWidget extends AppWidgetProvider {
 public static final String WIDGET_BTN_ACTION = "widget_btn_action";
 @Override
 public void onReceive(Context context, Intent intent) {
  super.onReceive(context, intent);
  if (intent != null && TextUtils.equals(intent.getAction(), WIDGET_BTN_ACTION)) { // intent   , action     ,     ,        
   Log.i(WIDGET_BTN_ACTION, "is clicked");
   //               
   RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.layout_widget);//  :  【  】    RemoteViews
   remoteViews.setTextViewText(R.id.widget_tv, "be clicked");
   remoteViews.setTextColor(R.id.widget_tv, Color.RED);
   AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);//     
   ComponentName componentName = new ComponentName(context, TestWidget.class);
   appWidgetManager.updateAppWidget(componentName, remoteViews);//setText  ,      
  }
 }
 @Override
 public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
  super.onUpdate(context, appWidgetManager, appWidgetIds);
  RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.layout_widget);//      RemoteViews
  Intent intent = new Intent();
  intent.setClass(context, TestWidget.class); //  intent     TestWidget  ,TestWidget       ,   。。        // 。
  intent.setAction(WIDGET_BTN_ACTION);
  PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
  remoteViews.setOnClickPendingIntent(R.id.widget_btn, pendingIntent);//  btn_widget     :     ,     action   。
  appWidgetManager.updateAppWidget(appWidgetIds, remoteViews); //      ,      。
 }
} 
運行後、widgetをデスクトップにドラッグすると、効果は以下の通りです。
 
ボタンをクリックした後、効果は以下の通りです。
 
工程書類:(Android Studio 2.1) 
もちろん、widgetには他にも多くの用途があります。たとえば:
 •サービスと通信する
 •widgetコントロールのインタラクション方法。
 •どのようにデスクトッププレーヤーWidgetを作りますか?
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。