RemoteView基础知识(一)

RemoteView

  • 字面意思可以翻译为远程view,该view运行于其他进程中,主要是系统进程,多用于通知栏和桌面widget中,当view运行在其他进程的时候 我们无法像在Activity中那样直接更新view,为了能够跨进程更新view,RomoteView提供了一系列的set方法

    RemoteView在通知栏中的应用简单举例

    1. 使用系统默认样式弹出一个通知栏
    Notification notification = new Notification();
    notification.icon = R.mipmap.ic_launcher;
    notification.tickerText = "hello world";
    notification.when = System.currentTimeMillis()+1000;
    notification.flags = Notification.FLAG_AUTO_CANCEL;
    Intent intent = new Intent(this,xxx.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
    notification..setLatestEventInfo(this,"","",pendingIntent);
    NotificationManager manager =(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
    manager.notify(1,notification);
    2. 自定义样式的通知栏
    
    Notification notification = new Notification();
    notification.icon = R.mipmap.ic_launcher;
    notification.tickerText = "hello world";
    notification.when = System.currentTimeMillis()+1000;
    notification.flags = Notification.FLAG_AUTO_CANCEL;
    Intent intent = new Intent(this,xxx.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
    RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.xxx);
    remoteViews.setTextViewText(R.id.xx,"xxx");
    remoteViews.setImageViewResource(R.id.xx,R.mipmap.xx);
    PendingIntent openActivityPendingIntent = PendingIntent.getActivity(this,0,new Intent(this,xxx.class),PendingIntent.FLAG_UPDATE_CURRENT);
    remoteViews.setOnClickPendingIntent(R.id.xxx,openActivityPendingIntent);
    notification.contentView = remoteViews;
    notification.contentIntent = pendingIntent;
    NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
    manager.notify(2.notification);

    RemoteViews的使用很简单,只需要提供当前应用的包名和布局文件的资源id即可创建一个RemoteViews对象,更新RemoteViews的方法比较复杂,因为RemoteViews运行在系统的进程中 我们无法直接访问里面的view 所以必须通过,RemoteViews提供的一系列方法来更新view

    remoteViews.setTextViewText(R.id.xx,"");//参数分别为TextView的id和要设置的文本
    
    remoteViews.setImageViewResource(R.id.xx,R.mipmap.xx);//参数分别为ImageView的id和要设置的图片的资源id
        remoteViews.setOnClickPendingIntent(R.id.xx,pendingIntent);//参数分别为要加点击事件的控件的id和pendingIntent
    

    RomoteViews在桌面小部件中的应用

    1. AppWidgetProvider是Android提供的用于实现桌面小部件的类,其本质是一个广播,继承自BroadcaseReceiver

      具体使用步骤可分为以下几步

      1. 定义小部件界面
        在layout中定义widget.xml文件
      2. 定义小部件配置信息
        在res/xml文件夹中定义appwidget_info.xml文件

        
        <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
        android:minWidth="84dp"
        android:minHeight="84dp"
        android:updatePeriodMillis="86400000"
        android:previewImage="@mipmap/ic_launcher"
        android:initialLayout="@layout/widget"
        android:resizeMode="horizontal|vertical"
        android:widgetCategory="home_screen|keyguard"
        android:initialKeyguardLayout="@layout/widget">
        
        
        appwidget-provider>
      3. 定义小部件的实现类

        package com.zzp.example.remoteviews;
        import android.app.PendingIntent;
        import android.appwidget.AppWidgetManager;
        import android.appwidget.AppWidgetProvider;
        import android.content.Context;
        import android.content.Intent;
        import android.widget.RemoteViews;
        
        import com.zzp.example.R;
        
        /**
         *桌面小部件的实现类 具体使用方法参见本包中的ReadMe文件
         */
        public class MyAppWidgetProvider extends AppWidgetProvider{
            private static final String TAG = "MyAppWidgetProvider";
            public static final String CLICK_ACTION = "";
        
            public MyAppWidgetProvider(){
                super();
            }
        
        
            /**
             *当该窗口小部件第一次添加到桌面的时候调用该方法
             *添加多次 但只会调用一次
             *@param context
             */
            @Override
            public void onEnabled(Context context) {
                super.onEnabled(context);
            }
        
            /**
             *小部件被添加或者更新的时候回调用该方法
             *小部件的更新时机由updatePeriodMills来制定 每个周期都会自动更新一次
             *@param context
             *@param appWidgetManager
             *@param appWidgetIds
             */
            @Override
            public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
                super.onUpdate(context, appWidgetManager, appWidgetIds);
                int count = appWidgetIds.length;
                for(int i = 0;iint appWidgetId = appWidgetIds[i];
                    //更新桌面小部件
                    onWidgetUpdate(
                    context,appWidgetManager,appWidgetId);
                }
            }
        
            /**
             *更新桌面小部件
             *@param context
             *@param appWidgetManager
             *@param appWidgetId
             */
            private void onWidgetUpdate(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
                RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget);
        
                //定义桌面小部件单击事件要发送的广播
                Intent intent = new Intent();
                intent.setAction(CLICK_ACTION);
                PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0,intent,0);
                remoteViews.setOnClickPendingIntent(
                R.id.iamgeView1,pendingIntent);
                appWidgetManager.updateAppWidget(
                appWidgetId,remoteViews);
        
            }
        
            /**
             *每删除一个桌面小部件就会调用一次
             *@param context
             *@param appWidgetIds
             */
            @Override
            public void onDeleted(Context context, int[] appWidgetIds) {
                super.onDeleted(context, appWidgetIds);
            }
        
            /**
             *当最后一个桌面小部件被删除的时候会调用该方法 只会调用一次
             *@param context
             */
            @Override
            public void onDisabled(Context context) {
                super.onDisabled(context);
            }
        
            /**
             *这是广播的内置方法 用于分发具体的事件给其他方法
             *@param context
             *@param intent
             */
            @Override
            public void onReceive(Context context, Intent intent) {
                super.onReceive(context, intent);
                //这里是判断我们自己定义的action 做对应的事情 比如被单击了要做什么事情
                if(intent.getAction().equals(CLICK_ACTION)){
                    //doSomething
                }
            }
        }
        
      4. 在AndroidManifest中声明小部件

        <receiver android:name=".remoteviews.MyAppWidgetProvider">
            <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/appwidget_info" />
        
            <intent-filter>
                <action android:name="xxx" />
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                
            intent-filter>
        receiver>

参考资料:Android开发艺术探索

你可能感兴趣的:(Android)