Android的widget初入门径

1.什么事widget
  widget就是android中的小插件或者控件,像音乐播放器为我们提供的播放音乐时候在主页显示上曲、暂停、下一曲的控件,像天气APP提供可以显示天气的控件等等。Android手机可以长按桌面空白部分就可以看到预览的各个APP提供的控件,长按控件拖动到你想放的位置就能用啦。android四大组建Activity(活动)、Service(服务)、ContentProvider(数据提供)、BroadcastProvider(广播)。widget继承BroadcastProvider(广播)本质上是一个广播。

2.widget能干什么事
  widget是一个小控件,主要是以控件形式显示在锁屏页面或者系统启动时候进入的界面(我把他称为桌面)。想象一下你听着歌,当你亮屏时候看到了是歌曲封面和歌词这就是widget在锁屏时候用处。

3.怎么用widget

  3.1首先建一个继承AppWidgetProvider自己的类MyAppWidgetProvider

public class MyAppWidgetProvider extends AppWidgetProvider {

    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context,intent);
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        super.updateAppWidget(appWidgetIds, views);
    }

    @Override
    public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) {
        super.onAppWidgetOptionsChanged(context, 
    }

    @Override
    public void onDeleted(Context context, int[] appWidgetIds) {
        super.onDeleted(context, appWidgetIds);
    }

    @Override
    public void onEnabled(Context context) {
        super.onEnabled(context);
    }

    @Override
    public void onDisabled(Context context) {
        super.onDisabled(context);
    }

    @Override
    public void onRestored(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
        super.onRestored(context, oldWidgetIds, newWidgetIds);
    }
}

  顾名思义就知道这几个方法干什么用的,详细讲解看下面。

3.2在AndroidManifest.xml中注册我们新建的widget(广播)

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

            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <action android:name="Widget_Button_Click"/>
            </intent-filter>
        </receiver>

  标签就是注册BroadcastProvider(广播)的,widget本质是广播所以要在配置文件中注册,android:name=“.MyAppWidgetProvider”指的就是我们刚刚建立的类MyAppWidgetProvider。

  

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/widget_layout"
    android:minWidth="300dp"
    android:minHeight="250dp"
    android:updatePeriodMillis="6890000"
    android:previewImage="@drawable/map">
</appwidget-provider>

标签提供配置widget信息。

android:initialLayout=“”提供我们widget显示效果,上文配置的widget显示效果是layout文件夹下面widget_layout.xml文件控制。

android:minWidth控制显示组件最小宽度

android:minHeight控制widget组件最小高度

android:updatePeriodMillis控制widget更新频率单位是毫秒

android:previewImage控制长按桌面空白处调出控件添加按钮时组件显示的样子。上文组件显示的是在drawable文件下面的一张名map.png的图片

更多具体标签下属性设置感兴趣可以自行百度。

3.3编写widget显示的文件widget_layout.xml

  在layout文件下面新建widget_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
                      android:layout_width="390dp"
                      android:layout_height="177dp"
                      android:layout_gravity="center"
                      android:gravity="center">

        <ImageButton
            android:id="@+id/MapWidgetButton"
            android:layout_width="390dp"
            android:layout_height="177dp"
            android:paddingLeft="37dp"
            android:background="@drawable/map">
        </ImageButton>

</FrameLayout>

  此文件是显示一个能响应事件的图片。这之后你的widget就能显示在安卓桌面上啊。当然只有能显示而已,但是并不能响应事件,不要急,一口吃不成胖子,前面挖的坑会一一填上。

4.讲解MyAppWidgetPrivoder类中各个方法
  4.1方法讲解

public class MyAppWidgetProvider extends AppWidgetProvider {  
    private static final String CLICK_NAME_ACTION = "com.terry.action.widget.click";  
    public static final String TAG = "widget";   
    public static  RemoteViews rv;  
    /**  
     * 更新(Widget的更新与Activity不同,必须借助于RemoteViews和AppWidgetMananger。)  
     */    
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){    
          Log.i(TAG, "onUpdate");  
          int N = appWidgetIds.length; // 可能启动了多个Widget,appWidgetIds记录了这些Widget的ID    
          for(int i=0; i<N; i++){   
              int appWidgetId = appWidgetIds[i];  
              rv = new RemoteViews(context.getPackageName(), R.layout.main);  
              Intent intentClick = new Intent(CLICK_NAME_ACTION);  
              PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,  
                      intentClick, 0);  
              rv.setOnClickPendingIntent(R.id.TextView01, pendingIntent);  
              appWidgetManager.updateAppWidget(appWidgetId, rv);  
          }     
    }    
    /**  
     * 第一个Widget组件启动时触发  
     */    
    public void onEnabled(Context context){    
          Log.i(TAG, "onEnabled");    
    }    
    /**  
     * 最后一个Widget组件关闭时触发  
     */    
    public void onDisabled(Context context){    
          Log.i(TAG, "onDisabled");    
    }    
    /**  
     * 任一Widget组件被删除时触发  
     */    
    public void onDeleted(Context context, int[] appWidgetIds){    
          Log.i(TAG, "onDeleted");    
    }    
    /**  
     * 以上函数触发前会先触发该函数,一般不需要重写  
     */    
    public void onReceive(Context context, Intent intent){    
          Log.i(TAG, "onReceive");    
          super.onReceive(context, intent);    
          if (rv == null) {  
              rv = new RemoteViews(context.getPackageName(), R.layout.main);  
          }  
          if (intent.getAction().equals(CLICK_NAME_ACTION)) {  
              rv.setTextViewText(R.id.TextView01, context.getResources()  
                      .getString(R.string.load));  
          }  
          AppWidgetManager appWidgetManger = AppWidgetManager.getInstance(context);  
          int[] appIds = appWidgetManger.getAppWidgetIds(new ComponentName(context, widgetProvider.class));  
          appWidgetManger.updateAppWidget(appIds, rv);  
    }       

  onReceive()方法接受各个方法消息并处理
  onUpdate()当第一个widget创建时执行本方法,widget更新时执行本方法。
   onDeleted()方法,任意一个widget被删除时候执行此方法
   onEnabled()方法,当第一个widget被创建时候,执行此方法
   onDisabled()方法,当最后一个widget被执行时候执行此方法
  无论怎么样onReceive()方法总会执行的,去看下AppWidgetProvider类源代码,onReceive()更像是个控制中心,根据不同的方法执行结果调用不同方法。比如:当onUpdate()方法被执行会发出一个android.appwidget.action.APPWIDGET_UPDATE的action给onUpdate()接收到action调用相应的方法。所以在自己类MyAppWidgetProvider的onReceive()方法中一定要在方法最后面加上super.onReceive();否则除了onReceive()方法外其他方法都不能执行。

  之前有人问为什么不在android中是用spring。spring的最重要之一就是aop解耦,而android已经为了开发者提供了四大组件,已经解耦。这四大组件是由android系统控制执行时间和顺序而不是由开发者,和javaWEB中的servlet一样是由服务器控制执行。只需要记住四大组件类提供方法的执行顺序和功能,如果提供的类不能满足需求就去继承重写你想要的方法。有什么不懂得去看官方API和源代码,大部分问题都能解决。

4.2如何获取视图并对它操作
  widget本质上是在另一个进程中运行,不能用findViewById()方法获得widget视图对象。android为我们提供了remoteView类来获取不是本进程视图对象并对操作。

 RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
        Intent intent = new Intent();                                                           //定义intent
        intent.setAction(ACTION);
        PendingIntent pendingIntentOne = PendingIntent.getBroadcast(context, 0, intent, 0);     //用PendingIntent将Intent包裹起来
        views.setOnClickPendingIntent(R.id.MapWidgetButton, pendingIntentOne);     

  本例中通过RemoteView获得视图对象views,创建Intent对象写入ACTION并用篇PendingIntent包裹Intent,给图片按钮添加事件,通过ACTION传给onRecive()方法,onRecive()接到广播后执行对应的方法。

世界未亡,死不投降

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值