Android widget 用法总结

来源:互联网 发布:sql loader 704 编辑:程序博客网 时间:2024/06/07 19:29

Android widget 用法总结

(2010-12-01 20:52:23)
转载
标签:

android

widget

实例

分类:Android
最近做了一个widget,功能跟android自带的Picture frame功能相似,唯一不同的是,Pictureframe是从SDCard中取得图片,而我做的这个widget所找的图片是从GooglePicasa上面找,具体操作不是写本文的目的。在这里,我就对widget的用法作一个总结,算是自己记的笔记吧。大家可以与我交流:leehong2005@163.com,由于代码太多,想要代码的可以给我发邮件。

直接先看看效果图:
Android <wbr>widget <wbr>用法总结

选择 Picture Frame

Android <wbr>widget <wbr>用法总结

从SDCard中找图片,它会一个一个地显示出来。

Android <wbr>widget <wbr>用法总结

选择要剪切的图片部分

Android <wbr>widget <wbr>用法总结
点击 Save 按钮后的界面

Android <wbr>widget <wbr>用法总结

在上一界面上,点击 Save 按钮,就会把选择的图片加入到widget中。

Android <wbr>widget <wbr>用法总结

当按 Ctrl + F11切换屏幕显示方式后,得到的界面。

这个跟android自带的Pictureframe功能就是一样的,唯一的就是界面上有些差别,实现上也有些差别,我这个更加简单,系统的那个Pictureframe功能很多。

1,widget可以有config,也可以没有,config其实就是一个activity,当运行widget时,就会最先启动这个config。
2,最重要的就是要实现AppWidgetProvider这个类,这个类其实是一个BroadcastReceiver,能接受一些系统发过来的消息等,它有几个方法,在此说明一下:

public void onReceive(Context context, Intent intent)
这个函数里面会调用相应的update, delete, enable,disabled这些方法,你可以在这个方法里处理自定义的消息。

public void onUpdate(Context context, AppWidgetManagerappWidgetManager, int[] appWidgetIds)
当widget要更新时调用,一般在这个函数里设置widget view的数据,如果设置文本值,图片等。

public void onDeleted(Context context, int[] appWidgetIds)
当一个widget删除时,就会调用这个函数。

public void onEnabled(Context context)
如果第一次加widget,就会调用这个函数,如果android系统重启时也会调用这个方法。

public void onDisabled(Context context)
当最后一个widget被删除后,就会调用这个方法,可以在这个函数里进行一些数据清除等。

3,widget一般要每次把数据结存起来,可以存到数据库中,也可以存到sharepreference里面,因为在android重启后,它要能正确加载数据。

4,widget的处理流程(有config)
1)怎么启动config,也就是说,怎么说这个widget与这个config相关联?
2)config结束后,怎么把数据更新到widget里面?
首先,应该在res/xml新建一个appwidget-provider的.xml文件。这个文件就指定了这个widget的一些属性:
<appwidget-providerxmlns:android="http://schemas.android.com/apk/res/android"
 
  android:minHeight="146dp"
   android:minWidth="146dp"
    android:configure="com.lee.demo.activity.PictureFrameConfig">
</appwidget-provider>

这个minHeight和minWidth有一个算法,公式是 cells * 74  -2。
上面红色标明的就是指定它的config。

其次,在config(是一个activity)里的onCreate里面,先要得到widget的id
       this.m_appWidgetId =getIntent().getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
       if (AppWidgetManager.INVALID_APPWIDGET_ID == m_appWidgetId)
       {
           setResult(RESULT_CANCELED);
           finish();
       }

这个id后在后面用到。

在结束这个config时,要把这个id设置到intent里
       // 更新widget,说白了就是得到一个RemoteView,把其中的view设置成你要的数据。
       // ...

       Intent intent = new Intent();
       intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,m_appWidgetId);
       setResult(resultCode, intent);
       finish();


写得有点麻烦,我直接放代码了吧,如果大家有什么不明白的,可以给我发邮件,我之前写了几个widget,基本上对widget还算明白。

-------------------------------------------------------------------------------------------------------------

PictureFrameProvider.java

public class PictureFrameProvider extends AppWidgetProvider
{
    publicstatic RemoteViews buildUpdateViews(Context context, intappWidgetId)
    {
       PictureDataUtility helper = new PictureDataUtility(context);
       Bitmap bitmap = helper.getPhoto(appWidgetId);
       RemoteViews views = null;
       
       if (null != bitmap)
       {
           views = new RemoteViews(context.getPackageName(),R.layout.picture_frame);
           views.setImageViewBitmap(R.id.photo, bitmap);
       }
       
       helper.close();
       
       return views;
    }
   
    publicstatic RemoteViews buildUpdateViews(Context context, intappWidgetId, Bitmap bitmap)
    {
       if (null == bitmap)
       {
           return null;
       }
       
       PictureDataUtility helper = new PictureDataUtility(context);
       helper.setPhoto(appWidgetId, bitmap);
       
       RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.picture_frame);
       views.setImageViewBitmap(R.id.photo, bitmap);
       helper.close();
       
       return views;
    }
   
    publicstatic void updateWidget(Context context, int appWidgetId, Bitmapbitmap)
    {
       RemoteViews views = buildUpdateViews(context, appWidgetId,bitmap);
       if (null != views)
       {
           int[] specificAppWidget = new int[] { appWidgetId };
           AppWidgetManager appWidgetManager =AppWidgetManager.getInstance(context);
           appWidgetManager.updateAppWidget(specificAppWidget, views);
       }
    }
   
    public voidonUpdate(Context context, AppWidgetManager appWidgetManager, int[]appWidgetIds)
    {
       for (int appWidgetId : appWidgetIds)
       {
           int[] specificAppWidget = new int[] { appWidgetId };
           RemoteViews views = buildUpdateViews(context, appWidgetId);
           appWidgetManager.updateAppWidget(specificAppWidget, views);
       }
    }
}

-----------------------------------------------------------------------------------------------------------------

这个就是widget所对应的xml定义,它定义了widget长什么样。

<?xml version="1.0"encoding="utf-8"?>
<FrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="212px"
   android:layout_height="148px"
   android:background="@drawable/appwidget_bg_land">
   <FrameLayout
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:paddingLeft="17px"
          android:paddingTop="16px"
          android:paddingRight="15px"
          android:paddingBottom="15px">
      <ImageView
          android:id="@+id/photo"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:scaleType="centerCrop"
          android:cropToPadding="true" />
   </FrameLayout>             
</FrameLayout>

-----------------------------------------------------------------------------------------------------------------

PictureFrameConfig.java

public class PictureFrameConfig extends Activity implementsMediaSelectView.IMediaSelectCallback
{
    publicstatic final String RETURN_DATA = "cropped_data";
    publicstatic final int REQUEST_CROP_PICTURE = 0x02;
   
    private intm_appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
   
   @Override
    public voidonCreate(Bundle savedInstanceState)
    {
       super.onCreate(savedInstanceState);

       MediaSelectView mediaView = new MediaSelectView(this);
       mediaView.findMedias();
       mediaView.showButtons(false);
       mediaView.setMediaCallback(this);
       
       this.setContentView(mediaView);
       this.m_appWidgetId =getIntent().getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,m_appWidgetId);
       if (AppWidgetManager.INVALID_APPWIDGET_ID == m_appWidgetId)
       {
           setResult(RESULT_CANCELED);
           finish();
       }
    }

   @Override
    public voidonCancelClick(View v)
    {
    }

   @Override
    public voidonDoneClick(View v)
    {
    }

   @Override
    public voidonItemClick(int position, View v, ImageInfo data)
    {
       Intent intent = new Intent(this, PictureFrameCropper.class);
       intent.setData(data.imageUri);
       startActivityForResult(intent, REQUEST_CROP_PICTURE);
    }
   
   @Override
    protectedvoid onActivityResult(int requestCode, int resultCode, Intentdata)
    {
       if (REQUEST_CROP_PICTURE == requestCode&&AppWidgetManager.INVALID_APPWIDGET_ID != m_appWidgetId)
       {
           resultCode = RESULT_OK;
           Bitmap bitmap =BitmapUtility.byteArrayToBitmap(data.getByteArrayExtra(RETURN_DATA));
           PictureFrameProvider.updateWidget(this, m_appWidgetId,bitmap);
       }
       else
       {
           resultCode = RESULT_CANCELED;
       }
       
       Intent intent = new Intent();
       intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,m_appWidgetId);
       setResult(resultCode, intent);
       finish();
    }
}

-----------------------------------------------------------------------------------------------------------------
manifest定义

<?xml version="1.0"encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
   package="com.lee.demo.picture" android:versionCode="1"
   android:versionName="1.0">
   <application android:icon="@drawable/icon"android:label="@string/app_name"
      android:theme="@android:style/Theme.Light">
      <activityandroid:name="com.lee.demo.activity.PictureFrameConfig"
         android:label="@string/picture_list_title">
         <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <actionandroid:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
         </intent-filter>
      </activity>

      <activityandroid:name="com.lee.demo.activity.PictureFrameCropper"
         android:label="@string/picture_crop_title">
      </activity>

      <receiverandroid:name="com.lee.demo.provider.PictureFrameProvider">
         <intent-filter>
            <actionandroid:name="android.appwidget.action.APPWIDGET_UPDATE"></action>
         </intent-filter>
         <meta-data android:name="android.appwidget.provider"android:resource="@xml/picture_widget_provider"/>
      </receiver>
   </application>
   <uses-sdk android:minSdkVersion="7"/>
</manifest>