2016年2月28日 星期日

Create a Widget for a app

Create a Widget for a app


a Widget  depend on a application
it make by two part:
appwidgetprovider and appwidgetprovider xml
appwidgetprovider xml:
describe your widget attribute:size,can reszie?,preview image


appwidgetprovider :
hold all the logic for create the widget view
fill the view with correct data
set the click listener


we can have not only one widget instance


image that,sunschine can have many widget,that support different location


now,start to code





the widget we can think that it is a remote view of the app,it put on the launcger.
In the remote view,it only can content the view original in the android,can not have custom view













if need to click


in manifest xml


now ,we want to create a widget with  static data


1.Layout
important***In the remote view,it only can content the view original in the android,can not have custom view


we crate a layout call widget_today_small
there is a problem,it is because
<4.0the mergian need to make by urself
>=4.0,auto have
how to make the widget show the same in different system?


we know that the auto margin is 8dp
so we can add widget_margin in dimens.xml:,if>=v14 widget_margin =0
if <v-14,widget_margin =8dp


like this


res/values/dimens.xml:
<dimen name="widget_margin">8dp</dimen>
res/values-v14/dimens.xml:
<dimen name="widget_margin">0dp</dimen>


1.now we can make the layout:


<?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:padding="@dimen/widget_margin">


   <LinearLayout
       android:id="@+id/widget"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:background="@color/primary"


       android:orientation="vertical">


       <ImageView
           android:id="@+id/widget_icon"
           android:layout_width="wrap_content"
           android:layout_height="0dp"
           android:layout_gravity="center_horizontal"
           android:layout_weight="1"
           android:src="@drawable/art_clear" />


       <TextView
           android:id="@+id/widget_high_temperature"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_gravity="center_horizontal"
           android:text="25"
           android:textAppearance="?android:textAppearanceLarge"
           android:textColor="@color/primary_text" />
   </LinearLayout>


</FrameLayout>


2.AppwidgetProvider info
n is the number of the box


set the preview image :
android:previewImage="@drawable/preview"


we create widget_info_today.xml in rex/xml


<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
   android:initialLayout="@layout/widget_today_small"
   android:minHeight="@dimen/widget_today_default_height"
   android:minWidth="@dimen/widget_today_default_width"
   android:updatePeriodMillis="0" />


How often, in milliseconds, that this AppWidget wants to be updated. will call onUpdate,
it is because now the widget is static 0,or the app will updateit,show is 0.


<dimen name="widget_today_default_width">40dp</dimen>
<dimen name="widget_today_default_height">40dp</dimen>
it is because n=1,so 40dp


3.Appwidget provioder
step1,create a class call   TodayWidgetProvider extends AppWidgetProvider


step 2 override onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)


Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_UPDATE} and
    * {@link AppWidgetManager#ACTION_APPWIDGET_RESTORED} broadcasts


it is because a widget may have different instance,each instance have a id,so the int[] appWidgetIds hold all the id




4.for all the weidget,give a view to them, and add onClick to them
this is the code example:


public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
       super.onUpdate(context, appWidgetManager, appWidgetIds);
       for (int appWidgetId : appWidgetIds) {
           RemoteViews remoteV = new RemoteViews(context.getPackageName(), R.layout.widget_today_small);


           Intent intent = new Intent(context, MainActivity.class);
           PendingIntent pendintent = PendingIntent.getActivity(context, 0, intent, 0);
           remoteV.setOnClickPendingIntent(R.id.widget, pendintent);
           appWidgetManager.updateAppWidget(appWidgetId, remoteV);


       }
   }


how to set the text and img src?
need to use the remote view specical method:
//            set the text
           remoteV.setTextViewText(R.id.widget_high_temperature, Utility.formatTemperature(context,10));
//            set the image
           remoteV.setImageViewResource(R.id.widget_icon,R.drawable.art_clear);

5.change the Manifest file


<receiver
           android:name="TodayWidgetProvider"
           android:label="@string/title_widget_today">
           <intent-filter>
               <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
           </intent-filter>
           <meta-data
               android:name="android.appwidget.provider"
               android:resource="@xml/widget_info_today" />
       </receiver>


TodayWidgetProvider is a Brodcast receiver, when it receive a brodcast have action(android.appwidget.action.APPWIDGET_UPDATE),
The AppWidgetManager automatically sends all other App Widget broadcasts to the AppWidgetProvider as necessary.
the OnUpdat will run,so we need to declare these.


the project code:



but,now,it can only show the static data,How can it show the update data form the content provider?Next we will talk.