Android widget 用法总结

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

运行效果图:


图1. 选择 Picture Frame


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


图3. 选择要剪切的图片部分


图4. 点击 Save 按钮后的界面


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


图6. 换屏幕显示方向后,得到的界面。


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

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, AppWidgetManager appWidgetManager, 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一般要每次把数据结存起来,可以存到数据库中,也可以存到share preference里面,因为在android重启后,它要能正确加载数据。

4,widget的处理流程(有config)
1)怎么启动config,也就是说,怎么说这个widget与这个config相关联?
2)config结束后,怎么把数据更新到widget里面?
首先,应该在res/xml新建一个appwidget-provider的.xml文件。这个文件就指定了这个widget的一些属性:

<appwidget-provider xmlns: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
{
    public static RemoteViews buildUpdateViews(Context context, int appWidgetId)
    {
        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;
    }
   
    public static RemoteViews buildUpdateViews(Context context,
        int appWidgetId, 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;
    }
   
    public static void updateWidget(Context context, 
        int appWidgetId, Bitmap bitmap)
    {
        RemoteViews views = buildUpdateViews(context, appWidgetId, bitmap);
        if (null != views)
        {
            int[] specificAppWidget = new int[] { appWidgetId };
            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
            appWidgetManager.updateAppWidget(specificAppWidget, views);
        }
    }
   
    public void onUpdate(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"?>
<FrameLayout xmlns: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 implements
    MediaSelectView.IMediaSelectCallback
{
    public static final String RETURN_DATA = "cropped_data";
    public static final int REQUEST_CROP_PICTURE = 0x02;
   
    private int m_appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
   
    @Override
    public void onCreate(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 void onCancelClick(View v)
    {
    }

    @Override
    public void onDoneClick(View v)
    {
    }

    @Override
    public void onItemClick(int position, View v, ImageInfo data)
    {
        Intent intent = new Intent(this, PictureFrameCropper.class);
        intent.setData(data.imageUri);
        startActivityForResult(intent, REQUEST_CROP_PICTURE);
    }
   
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        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"?>
<manifest xmlns: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">
        <activity android:name="com.lee.demo.activity.PictureFrameConfig"
            android:label="@string/picture_list_title">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
            </intent-filter>
        </activity>


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


        <receiver android:name="com.lee.demo.provider.PictureFrameProvider">
            <intent-filter>
                <action android: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>


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AndroidWidget是指可以被放置在桌面或者其他应用中的小部件,比如常见的时钟、天气、日历等等。在Android中,Widget的布局可以使用XML文件来进行定义,与普通的布局定义类似,可以使用各种属性来设置Widget的样式和行为。 在Widget的XML布局文件中,可以使用View类中定义的许多属性来控制Widget的样式和行为,比如: 1. android:id:设置Widget的ID,可以在代码中通过findViewById()方法来获取对应的View对象。 2. android:layout_width、android:layout_height:设置Widget的宽度和高度,可以使用具体数值或者match_parent、wrap_content等特殊值。 3. android:layout_gravity:设置Widget在父布局中的对齐方式,比如center、left、right等等。 4. android:padding、android:paddingLeft、android:paddingRight等:设置Widget的内边距,用于控制Widget内部内容的显示位置。 5. android:background:设置Widget的背景颜色或者背景图片。 6. android:clickable、android:longClickable:设置Widget是否可以被点击或者长按。 7. android:focusable、android:focusableInTouchMode:设置Widget是否可以获取焦点,用于控制Widget是否可以响应键盘事件等。 8. android:visibility:设置Widget是否可见,可以使用值为visible、invisible、gone。 除了以上列出的属性之外,还有许多其他的属性可以用于控制Widget的样式和行为,具体可以查看Android官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值