亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

Android中的AppWidget入門教程

2020-04-11 11:38:32
字體:
來源:轉載
供稿:網友

什么是AppWidget?AppWidget就是我們平常在桌面上見到的那種一個個的小窗口,利用這個小窗口可以給用戶提供一些方便快捷的操作。本篇打算從以下幾個點來介紹AppWidget:

1.如何創建一個簡單的AppWidget
2.如何使得AppWidget與客戶端程序交互

創建簡單的AppWidget

在介紹之前給大家看一下程序運行的最后結果和項目結構圖,以便大家有個整體的印象。

運行結果圖:

項目結構圖:

第一步:

首先在res文件夾下新建一個名字為xml的文件夾,然后在xml目錄下創建一個名為appwidget01的xml文件(如上圖所示)。這個appwidget01中的內容如下:

復制代碼 代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:minWidth = "294dp"
  android:minHeight = "72dp"
  android:updatePeriodMillis = "86400000"
  android:initialLayout = "@layout/appwidgetlayout"
  >
</appwidget-provider>

這個xml是用來描述你所要創建的appWidget的一些描述信息的,比如高度、寬度、刷新間隔、布局文件等等。僅僅這個描述文件還不夠,我們看到的appWidget可都是有界面元素的呀,比如說文本,圖片,按鈕等等,這些東西的定義都需要放到layout文件夾下面。這個文件就是上面代碼中寫到的那個appwidgetlayout。

第二步:

在layout文件夾下面新建一個appwidgetlayout.xml文件,在這個文件中描述了appWidget的控件和布局等等信息,就和我們平常創建的一個activity的布局文件沒什么兩樣,因為只是簡單的演示,所以僅用一個文本和一個按鈕。xml的內容如下:

復制代碼 代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent">
    <TextView android:id="@+id/txtapp" android:text="test" android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:background="#ffffff"></TextView>
    <Button android:id="@+id/btnSend" android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:text="Send"></Button>
</LinearLayout>

第三步:

既然appWidget中存在按鈕等等控件,那么就肯定少不了處理這些控件事件的處理代碼啦。這些代碼被放在一個繼承于AppWidgetProvider的類中,在本例子中我新建了一個AppWidget的類,該類繼承于AppWidgetProvider,以后所有的AppWidget上面的控件事件都會在這個類中處理??匆幌骂惖膬热荩?/p>

復制代碼 代碼如下:

public class AppWidget extends AppWidgetProvider
{
 
    private final String broadCastString = "com.qlf.appWidgetUpdate";
    
    /**
     * 刪除一個AppWidget時調用
     * */
    @Override
    public void onDeleted(Context context, int[] appWidgetIds)
    {
        super.onDeleted(context, appWidgetIds);
    }
 
    /**
     * 最后一個appWidget被刪除時調用
     * */
    @Override
    public void onDisabled(Context context)
    {
        super.onDisabled(context);
    }
 
    /**
     * AppWidget的實例第一次被創建時調用
     * */
    @Override
    public void onEnabled(Context context)
    {
        super.onEnabled(context);
    }
 
    /**
     * 接受廣播事件
     * */
    @Override
    public void onReceive(Context context, Intent intent)
    {
 
             super.onReceive(context, intent);
    }
 
    /**
     * 到達指定的更新時間或者當用戶向桌面添加AppWidget時被調用
     * */
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds)
    {
 
                 
    }
    
}

各個方法的作用大家一看上面的注釋就明白了。我們暫時不需要實現里面的方法。

第四步:

在AndroidManifest.xml中定義一些創建AppWidget必要的東西,先看代碼:

復制代碼 代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.qlf.widget" android:versionCode="1" android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MainActivity" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name="AppWidget">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE"></action>
            </intent-filter>
            <meta-data android:name="android.appwidget.provider"
                android:resource="@xml/appwidget01" />
        </receiver>
    </application>
    <uses-sdk android:minSdkVersion="8" />
</manifest>

可以看到我們在配置文件里面定義了一個receiver,他的名字是上面創建處理控件代碼的那個類,下面那個intent-filter中的action是系統自帶的用于更新所有appwidget的廣播動作。然后meta-data標簽是一個描述我們創建appwidget的元數據,那個android:name="android.appwidget.provider"是固定的,android:resource="@xml/appwidget01"指定創建的appWidget的描述信息的位置。這樣程序就知道到哪里去初始化這些appWidget啦。

經過上面四個步驟,我想您已經能夠成功在桌面上添加小工具了,效果就是我們最前面發出的樣子。

AppWidget與程序交互

前面我們只是簡單的介紹了如何創建一個appWidget,但是目前這個appWidget還沒有任何的交互功能。下面我們介紹一下appWidget如何與程序進行交互。首先要介紹一個對象,這個對象在appwidget和程序的交互中很重要,他就是RemoteViews。因為appwidget運行的進程和我們創建的應用不在一個進程中,所以我們也就不能像平常引用控件那樣來獲得控件的實例。這個時候RemoteViews出場了,從字面上看他的意思是遠程的視圖,也就是說通過這個東西我們能夠獲得不在同一進程中的對象,這也就為我們編寫appwidget的處理事件提供了幫助。我們使用一下代碼來創建一個RemoteViews :

復制代碼 代碼如下:

RemoteViews remoteViews  = new RemoteViews(context.getPackageName(),R.layout.appwidgetlayout);
 
remoteViews.setOnClickPendingIntent(R.id.btnSend, pendingIntent);  //為小工具上的按鈕綁定事件

可以看到上面又出現了一個陌生的對象pendingIntent,這個又是用來干嘛的呢?我們知道在一般的程序中綁定按鈕的點擊事件是直接在實現了OnClickListener接口的類中中完成的。不過因為appwidget并不在我們應用的進程中,所以當然他也訪問不到我們在應用中設置的onclick代碼啦。而PendingIntent就是被用來解決這個問題的。PendingIntent可以看成是一個特殊的Intent,如果我們把Intent看成一封信,那么PendingIntent就是一封被信封包裹起來的信。這封信在remoteViews.setOnClickPendingIntent()中被“郵寄”到了appwidget, 當appwidget中的按鈕單擊時他知道將這封信打開,并執行里面的內容。這樣就避免了直接從appwidget中執行本地代碼。我們來看看PendingIntent是如何定義的:

復制代碼 代碼如下:

//創建一個Intent對象
Intent intent = new Intent();
intent.setAction(broadCastString);
 
//這一步相當于寫信,說明這個信的作用到底是什么,在這里表示將發送一個廣播
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

有了上面的介紹,我們在創建appwidget的交互應用時就簡單不少了。我們剩下要做的工作就是在appwidget在創建的時候調用上面說到的方法為appwidget中的控件綁定事件,也就是在AppWidget類下的onUpdate方法中完成這個過程。

復制代碼 代碼如下:

/**
* 到達指定的更新時間或者當用戶向桌面添加AppWidget時被調用
* */
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds)
{
 
        //創建一個Intent對象
        Intent intent = new Intent();
        intent.setAction(broadCastString);
 
 
        //設置pendingIntent的作用
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
        RemoteViews remoteViews  = new RemoteViews(context.getPackageName(),R.layout.appwidgetlayout);
       
 
        //綁定事件
        remoteViews.setOnClickPendingIntent(R.id.btnSend, pendingIntent);
        
        //更新Appwidget
        appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
}

通過上面的代碼我們就為button按鈕綁定了一個事件,這個事件的作用是發送一個廣播便于其他應用接收、更新信息。這是appwidget發送廣播,那么appwidget如何接受來自其他程序發送的廣播呢?這就是public void onReceive(Context context, Intent intent)的功能啦。這個方法會接收來自其他應用發出的廣播,我們只要在這個程序中過濾我們需要的廣播就能響應其他應用的操作來更新appwidget的信息了。要注意的是,因為appwidget運行的進程和我們創建的應用不在一個進程中的限制,所以更新的appwidget的時候也要通過遠程對象來操作,具體代碼如下:

復制代碼 代碼如下:

/**
   * 接受廣播事件
   * */
  @Override
  public void onReceive(Context context, Intent intent)
  {
      if (intent.getAction().equals(broadCastString))
      {              
          //只能通過遠程對象來設置appwidget中的控件狀態
          RemoteViews remoteViews  = new RemoteViews(context.getPackageName(),R.layout.appwidgetlayout);
 
         //通過遠程對象將按鈕的文字設置為”hihi”
          remoteViews.setTextViewText(R.id.btnSend, "hihi");  
           
          //獲得appwidget管理實例,用于管理appwidget以便進行更新操作
          AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
          
          //相當于獲得所有本程序創建的appwidget
          ComponentName componentName = new ComponentName(context,AppWidget.class);
          
          //更新appwidget
          appWidgetManager.updateAppWidget(componentName, remoteViews);
      }
      super.onReceive(context, intent);
  }

總結下就是appwidget上的操作都必須借助遠程對象來操作。最后看一下運行的圖片吧:

按之前:

按之后:

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品在线小视频| 久久久久久久久久久网站| 日韩欧美在线中文字幕| 富二代精品短视频| 色中色综合影院手机版在线观看| 成人观看高清在线观看免费| 亚洲精品国产精品乱码不99按摩| 久久国产加勒比精品无码| 日本精品免费一区二区三区| 国内精品视频在线| 欧美一级视频免费在线观看| 亚洲国产第一页| 日韩欧美国产成人| 97av视频在线| 国模精品视频一区二区| 国产精品自产拍在线观看| 国产欧美韩国高清| 久久久精品电影| 久热精品视频在线免费观看| 色综合男人天堂| 国产福利精品在线| www亚洲欧美| 国产成一区二区| 欧美亚洲国产视频小说| 日本成人激情视频| 亚洲一区二区福利| 中文字幕亚洲激情| 亚洲永久在线观看| 伊人久久大香线蕉av一区二区| 91牛牛免费视频| 最近2019中文字幕mv免费看| 久久久久免费精品国产| 久久成年人免费电影| 国产午夜精品一区二区三区| 51精品国产黑色丝袜高跟鞋| 欧美大尺度在线观看| 亚洲iv一区二区三区| 亚洲天堂2020| 欧美人在线观看| 亚洲欧美视频在线| 亚洲视频网站在线观看| 色视频www在线播放国产成人| 国产精品wwww| 91精品国产91久久久久久最新| 久久伊人精品一区二区三区| 欧美专区在线播放| 成人性生交xxxxx网站| 国产精品亚洲精品| 亚洲一区二区三| 亚洲淫片在线视频| 在线激情影院一区| 国产一区深夜福利| 96pao国产成视频永久免费| 欧美另类精品xxxx孕妇| 国产剧情久久久久久| 国产欧美va欧美va香蕉在| 欧美xxxx18国产| 亚洲天堂第一页| 色综合久综合久久综合久鬼88| 亚洲综合日韩中文字幕v在线| 精品国偷自产在线| 久久久999国产| 久久99精品国产99久久6尤物| 国语自产精品视频在免费| 国产成人精品一区二区在线| 亚洲最大的av网站| 亚洲成年人在线| 欧美精品video| 国产精品黄色影片导航在线观看| 91九色国产视频| 久久精品2019中文字幕| 国产亚洲美女精品久久久| 成人免费午夜电影| 国产69精品久久久久9| 欧美福利视频在线| 亚洲视频在线观看视频| 久久五月天综合| 亚洲小视频在线| 国产精品夜色7777狼人| 久久久久久91香蕉国产| 国产精品偷伦视频免费观看国产| 亚洲精品在线91| 久久精品福利视频| 久久九九有精品国产23| 欧美风情在线观看| 欧美激情视频网站| 亚洲国产精彩中文乱码av在线播放| 亚洲国产欧美一区二区丝袜黑人| 精品女同一区二区三区在线播放| 日本精品久久久久久久| 色综合天天综合网国产成人网| 欧美日韩成人免费| 国内精品在线一区| 91国偷自产一区二区三区的观看方式| 亚洲欧美三级伦理| 日韩中文字幕网址| 亚洲第一网中文字幕| 日韩亚洲成人av在线| 国产欧美 在线欧美| 欧美中文在线观看国产| 欧美在线不卡区| 3344国产精品免费看| 亚洲第一精品夜夜躁人人爽| 欧美精品一本久久男人的天堂| 欧美激情精品久久久久久久变态| 久久精品国产一区二区电影| 成人福利免费观看| 国产精品九九久久久久久久| 国产精品久久久久999| 在线观看欧美成人| 国色天香2019中文字幕在线观看| 欧美肥婆姓交大片| 亚洲成avwww人| 久久久久久国产精品久久| 亚洲va欧美va在线观看| 亚洲护士老师的毛茸茸最新章节| 国产亚洲a∨片在线观看| 国产一区二区丝袜高跟鞋图片| 国产精品电影在线观看| 色99之美女主播在线视频| 91精品免费久久久久久久久| 日韩欧美aⅴ综合网站发布| 日韩福利在线播放| 午夜精品久久久99热福利| 欧美亚洲第一页| 岛国av在线不卡| 狠狠躁18三区二区一区| 青青草原成人在线视频| 在线播放精品一区二区三区| 亚洲老司机av| 国产欧美久久久久久| 国产精品视频一区二区高潮| 人人爽久久涩噜噜噜网站| 久久精品在线视频| 欧美黄网免费在线观看| 日韩精品免费综合视频在线播放| 国产欧美日韩综合精品| 亚洲男女自偷自拍图片另类| xxx成人少妇69| 久久亚洲电影天堂| 一区国产精品视频| 亚洲免费影视第一页| 亚洲欧美一区二区三区在线| 91最新在线免费观看| 91精品国产91久久久久久久久| 97色在线视频观看| 北条麻妃一区二区三区中文字幕| 国产精品免费视频久久久| 日韩中文字幕网址| 俺去啦;欧美日韩| 97国产真实伦对白精彩视频8| 中文综合在线观看| 一区二区三区无码高清视频| 尤物tv国产一区| 亚洲第一区第一页| 91精品视频在线免费观看| 91久久久久久久久久久久久| 成人福利免费观看| 亚洲欧洲日本专区| 欧美午夜www高清视频| 一区二区欧美日韩视频| 日韩有码片在线观看| 精品国产成人av| 欧美片一区二区三区|