关于RemoteView的一点愚见(实现桌面小部件)

RemoteView中的应用除了有通知栏的自定义之外,还有桌面小部件也是通过RemoteView以及AppWidgetProvider来完成的。

实际上AppWidgetProvider是一个广播,即继承于BroadcastReceiver。

public class AppWidgetProvider extends BroadcastReceiver

那么我们其实可以将AppWidgetProvider当成一个特殊的BroadcastReceiver就可以了。

让我们来自定义一个桌面小部件:
首先现在res/layout/ 下创建一个xml文件,命名为appwidget.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>

接着我们在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/appwidget"
    android:minHeight="84dp"
    android:minWidth="84dp"
    android:updatePeriodMillis="86400000" >

</appwidget-provider>

在上面第一个属性是指小工具使用的初始化布局。第二属性和第三个属性是指最小的宽高,最后一个属性是指更新周期,每隔这么多秒就会被触发。

下面是实现类,要继承于AppWidgetProvider:

public class AppProvider extends AppWidgetProvider{
    public static final String TAG = "MyAppProvider";
    public static final String CLICK_ACTION = "com.example.remoteview.action.CLICK";

    public AppProvider(){
        super();
    }

    //同样是要重写onReceive()
    @Override
    public void onReceive(final Context context,Intent intent){
        super.onReceive(context, intent);
        Log.e(TAG, "action = " + intent.getAction());
        if(intent.getAction().equals(CLICK_ACTION)){
            Toast.makeText(context, "click it", Toast.LENGTH_SHORT).show();
            new Thread(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    //建立Bitmap
                    Bitmap srcBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon1);
                    //声明AppWidgetManager
                    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
                    for(int i = 0;i < 37;i++){
                        //控件图片旋转360度
                        float degree = (i * 10)%360;
                        RemoteViews remoteView = new RemoteViews(context.getPackageName(),R.layout.appwidget);
                        remoteView.setImageViewBitmap(R.id.imageView1,rotateBitmap(context,srcBitmap,degree));
                        Intent intentClick = new Intent();
                        intentClick.setAction(CLICK_ACTION);
                        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentClick, 0);
                        remoteView.setOnClickPendingIntent(R.id.imageView1,pendingIntent);
                        //updateAppWidget将会调用onUpdate
                        appWidgetManager.updateAppWidget(new ComponentName(context, AppProvider.class),remoteView);
                        SystemClock.sleep(30);
                    }
                }
            }).start();
        }
    }

    @Override
    public void onUpdate(Context context,AppWidgetManager appWidgetManager,int[] appWidgetIds){
        super.onUpdate(context, appWidgetManager, appWidgetIds);
        Log.e(TAG, "onUpdate");

        final int counter = appWidgetIds.length;
        Log.e(TAG, "COUNTER = " + counter);
        for(int i = 0;i < counter; i++){
            int appWidgetId = appWidgetIds[i];
            onWidgetUpdate(context,appWidgetManager,appWidgetId);
        }
    }
    //更新部件函数
    private void onWidgetUpdate(Context context,AppWidgetManager appWidgetManager,int appWidgetId){
        RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.appwidget);
        Intent intentClick = new Intent();
        intentClick.setAction(CLICK_ACTION);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentClick, 0);
        //桌面小部件将会被点击触发,发送PendingIntent
        remoteViews.setOnClickPendingIntent(R.id.imageView1, pendingIntent);
        appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
    }

    //变换Bitmap的矩阵
    private Bitmap rotateBitmap(Context context,Bitmap srcBitmap,float degree){
        Matrix matrix = new Matrix();
        matrix.reset();
        matrix.setRotate(degree);
        Bitmap tmpBitmap =  Bitmap.createBitmap(srcBitmap,0,0,srcBitmap.getWidth(),srcBitmap.getHeight(),matrix,true);
        return tmpBitmap;

    }
}

对了,别忘记了还有继承于BroadcastReceiver我们还是需要注册,注册有点点不一样。如下:

<receiver android:name=".AppProvider">
            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/appwidget_provider_info">

            </meta-data>
            <intent-filter>
                <action android:name="com.example.remoteview.action.CLICK"/>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
            </intent-filter>

        </receiver>

第一个Action用来标识点击行为,第二个Action是声明为AppWidget必须存在的action。

这样就完成了桌面小工具的实现了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值