Android開發(fā)5:應(yīng)用程序窗口小部件App Widgets的實(shí)現(xiàn)(附demo)
前言
本次主要是實(shí)現(xiàn)一個(gè)Android應(yīng)用,實(shí)現(xiàn)靜態(tài)廣播、動(dòng)態(tài)廣播兩種改變 widget內(nèi)容的方法,即在上篇博文中實(shí)驗(yàn)的基礎(chǔ)上進(jìn)行修改,所以此次實(shí)驗(yàn)的重點(diǎn)是AppWidget小部件的實(shí)現(xiàn)啦~
首先,我們簡(jiǎn)單說(shuō)一下Widget是一個(gè)啥玩意~
應(yīng)用程序窗口小部件(Widget)是微小的應(yīng)用程序視圖,可以被嵌入到其它應(yīng)用程序中(比如桌面)并接收周期性的更新。你可以通過(guò)一個(gè)App Widget provider來(lái)發(fā)布一個(gè)Widget。可以容納其它App Widget的應(yīng)用程序組件被稱為App Widget宿主。
Widget是在桌面上的一塊顯示信息的東西,也通過(guò)單擊Widget跳轉(zhuǎn)到一個(gè)程序里面。而系統(tǒng)自帶的程序,典型的Widget是music,這個(gè)Android內(nèi)置的音樂播放小程序。這個(gè)是典型的Widget+app應(yīng)用。就是一個(gè)程序既可以通過(guò)Widget啟動(dòng),也可以通過(guò)App啟動(dòng)。Widget就是一個(gè)AppWidgetProvider+一個(gè)UI界面顯示(預(yù)先綁定了好多Intent),界面上的信息可以通過(guò)程序控制而改變,單擊Widget,上的控件只能激發(fā)發(fā)送一個(gè)Intent,或發(fā)出一個(gè)Service的啟動(dòng)通知。而AppWidgetProvider可以攔截這個(gè)Intent,而進(jìn)行相應(yīng)的處理(比如顯示新的信息)。
基礎(chǔ)知識(shí)
為了創(chuàng)建一個(gè)App Widget,你需要下面這些:
AppWidgetProviderInfo 對(duì)象
描述一個(gè)App Widget元數(shù)據(jù),比如App Widget的布局,更新頻率,以及AppWidgetProvider 類。這應(yīng)該在XML里定義。
AppWidgetProvider 類的實(shí)現(xiàn)
定義基本方法以允許你編程來(lái)和App Widget連接,這基于廣播事件。通過(guò)它,當(dāng)這個(gè)App Widget被更新,啟用,禁用和刪除的時(shí)候,你都將接收到廣播通知。
視圖布局
為這個(gè)App Widget定義初始布局,在XML中。
另外,你可以實(shí)現(xiàn)一個(gè)App Widget配置活動(dòng)。這是一個(gè)可選的活動(dòng)Activity,當(dāng)用戶添加App Widget時(shí)加載并允許他在創(chuàng)建時(shí)來(lái)修改App Widget的設(shè)置。
widget 的添加:長(zhǎng)按菜單鍵,點(diǎn)擊 widgets 選項(xiàng)。找到對(duì)應(yīng)的 widget 將其拖入桌面。對(duì) 于不同的 API 版本顯示會(huì)稍有不同。
典型的 Android Widget 有三個(gè)主要組件,一個(gè)邊框、一個(gè)框架和圖形控件以及其他元素。 在 Android Studio 中創(chuàng)建 Widget 類后,會(huì)直接生成相關(guān)文件。

首先,在應(yīng)用程序AndroidManifest.xml文件中聲明AppWidgetProvider 類,比如:
<receiver Android:name="ExampleAppWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/example_appwidget_info" />
</receiver>
<receiver>元素需要android:name屬性,它指定了App Widget使用的AppWidgetProvider 。
<intent-filter> 元素必須包括一個(gè)含有android:name屬性的<action>元素。該元素指定AppWidgetProvider接受ACTION_APPWIDGET_UPDATE 廣播。這是唯一你必須顯式聲明的廣播。當(dāng)需要的時(shí)候,AppWidgetManager 會(huì)自動(dòng)發(fā)送所有其他App Widget廣播給AppWidgetProvider。
<meta-data> 元素指定了AppWidgetProviderInfo 資源并需要以下屬性:
- android:name – 指定元數(shù)據(jù)名稱。
- android:resource – 指定AppWidgetProviderInfo 資源路徑。
1. Widget 布局文件 widget_demo.xml,布局中有一個(gè) ImageView,一個(gè) TextView。 要求:文字顏色為紅色,大小為 20dp,整體背景為透明。最后效果如下:
2.增加AppWidgetProviderInfo元數(shù)據(jù)
AppWidgetProviderInfo定義一個(gè)App Widget的基本特性,比如最小布局尺寸,初始布局資源,刷新頻率,以及(可選的)創(chuàng)建時(shí)加載的一個(gè)配置活動(dòng)。使用單獨(dú)的一個(gè)<appwidget-provider>元素在XML資源里定義AppWidgetProviderInfo 對(duì)象并保存到項(xiàng)目的res/xml/目錄下。
Widget 內(nèi)容提供者文件 widget_demo_info.xml,編輯該文件,設(shè)置其大小屬性和布 局,如下圖:
其中,minWidth 為最小寬度,minHeight 為最小高度,initialLayout 為初始布局。
3. 修改 WidgetDemo.java 代碼,重寫 onUpdate 方法,為 Widget 添加事件,使得能夠返 回主頁(yè)面。
這里需要使用到一種用戶程序訪問(wèn)主屏幕和修改特定區(qū)域內(nèi)容的方法:RemoteView 架 構(gòu) 。RemoteView 架構(gòu)允許用戶程序更新主屏幕的 View,點(diǎn)擊 Widget 激活點(diǎn)擊事件,Android 會(huì)將其轉(zhuǎn)發(fā)給用戶程序,由 AppWidgetProviders 類處理,使得用戶程序可更新主 屏幕 Widget。

pendingIntent是一種特殊的 Intent。主要的區(qū)別在于 Intent 的執(zhí)行立刻的,而 pendingIntent 的執(zhí)行不是立刻的。本次使用方法類的靜態(tài)方法為 getActivity(Context, int, Intent, int),對(duì)應(yīng) Intent 的跳轉(zhuǎn)到一個(gè) activity 組件的操作。
使用AppWidgetProvider類
你必須通過(guò)在清單文件中使用<receiver>元素來(lái)聲明你的AppWidgetProvider 類實(shí)現(xiàn)為一個(gè)廣播接收器(參見上面的Declaring an App Widget in the Manifest)。
AppWidgetProvider 類擴(kuò)展BroadcastReceiver 為一個(gè)簡(jiǎn)便類來(lái)處理App Widget廣播。AppWidgetProvider只接收和這個(gè)App Widget相關(guān)的事件廣播,比如這個(gè)App Widget被更新,刪除,啟用,以及禁用。當(dāng)這些廣播事件發(fā)生時(shí),AppWidgetProvider 將接收到下面的方法調(diào)用:
onUpdate(Context, AppWidgetManager, int[])
這個(gè)方法調(diào)用來(lái)間隔性的更新App Widget,間隔時(shí)間用AppWidgetProviderInfo 里的updatePeriodMillis屬性定義(參見添加AppWidgetProviderInfo元數(shù)據(jù))。這個(gè)方法也會(huì)在用戶添加App Widget時(shí)被調(diào)用,因此它應(yīng)該執(zhí)行基礎(chǔ)的設(shè)置,比如為視圖定義事件處理器并啟動(dòng)一個(gè)臨時(shí)的服務(wù)Service,如果需要的話。但是,如果你已經(jīng)聲明了一個(gè)配置活動(dòng),這個(gè)方法在用戶添加App Widget時(shí)將不會(huì)被調(diào)用,而只在后續(xù)更新時(shí)被調(diào)用。配置活動(dòng)應(yīng)該在配置完成時(shí)負(fù)責(zé)執(zhí)行第一次更新。(參見下面的創(chuàng)建一個(gè)App Widget配置活動(dòng)Creating an App Widget Configuration Activity。)
onDeleted(Context, int[])
當(dāng)App Widget從宿主中刪除時(shí)被調(diào)用。
onEnabled(Context)
當(dāng)一個(gè)App Widget實(shí)例第一次創(chuàng)建時(shí)被調(diào)用。比如,如果用戶添加兩個(gè)你的App Widget實(shí)例,只在第一次被調(diào)用。如果你需要打開一個(gè)新的數(shù)據(jù)庫(kù)或者執(zhí)行其他對(duì)于所有的App Widget實(shí)例只需要發(fā)生一次的設(shè)置,那么這里是完成這個(gè)工作的好地方。
onDisabled(Context)
當(dāng)你的App Widget的最后一個(gè)實(shí)例被從宿主中刪除時(shí)被調(diào)用。你應(yīng)該在onEnabled(Context)中做一些清理工作,比如刪除一個(gè)臨時(shí)的數(shù)據(jù)庫(kù)。
onReceive(Context, Intent)
這個(gè)接收到每個(gè)廣播時(shí)都會(huì)被調(diào)用,而且在上面的回調(diào)函數(shù)之前。你通常不需要實(shí)現(xiàn)這個(gè)方法,因?yàn)槿笔〉腁ppWidgetProvider 實(shí)現(xiàn)過(guò)濾所有App Widget 廣播并恰當(dāng)?shù)恼{(diào)用上述方法。
注意: 在Android 1.5中, 有一個(gè)已知問(wèn)題,onDeleted()方法在該調(diào)用時(shí)不被調(diào)用。為了規(guī)避這個(gè)問(wèn)題,你可以像Group post中描述的那樣實(shí)現(xiàn)onReceive() 來(lái)接收這個(gè)onDeleted()回調(diào)。
最重要的AppWidgetProvider 回調(diào)函數(shù)是onUpdated(), 因?yàn)樗窃诿總€(gè)App Widget添加進(jìn)宿主時(shí)被調(diào)用的(除非你使用一個(gè)配置活動(dòng))。如果你的App Widget 要接受任何用戶交互事件,那么你需要在這個(gè)回調(diào)函數(shù)中注冊(cè)事件處理器。如果你的App Widget不創(chuàng)建臨時(shí)文件或數(shù)據(jù)庫(kù),或者執(zhí)行其它需要清理的工作,那么onUpdated() 可能是你需要定義的唯一的回調(diào)函數(shù)。
4.重寫 onReceive 方法
在 Widget 類中重寫 onReceive 方法,這里需要使用到 RemoteView 以及 Bundle。當(dāng)接 收到對(duì)應(yīng)廣播時(shí)進(jìn)行數(shù)據(jù)處理。 
if 條件語(yǔ)句中主要用到的函數(shù)為:setTextViewText、setImageViewResource。 之后使用 AppWidgetManager 類對(duì) Widget 進(jìn)行更新。
實(shí)驗(yàn)內(nèi)容
實(shí)現(xiàn)一個(gè) Android 應(yīng)用,實(shí)現(xiàn)靜態(tài)廣播、動(dòng)態(tài)廣播兩種改變 widget 內(nèi)容的方法。在上次實(shí) 驗(yàn)的基礎(chǔ)上進(jìn)行修改,所以一些關(guān)于靜態(tài)動(dòng)態(tài)廣播的內(nèi)容會(huì)簡(jiǎn)略。
具體要求:
(1)該界面為應(yīng)用啟動(dòng)后看到的界面。

widget 初始情況如下

(2)點(diǎn)擊靜態(tài)注冊(cè)按鈕,跳轉(zhuǎn)至如下界面?! ?br />

點(diǎn)擊表單項(xiàng)目。如 banana。widget 會(huì)發(fā)生對(duì)應(yīng)變化。點(diǎn)擊 Widget 上的圖片可以跳轉(zhuǎn)回主頁(yè)面
(3)點(diǎn)擊動(dòng)態(tài)注冊(cè)按鈕,跳轉(zhuǎn)至如下界面。 實(shí)現(xiàn)以下功能:
a)可以編輯廣播的信息,點(diǎn)擊 Send 按鈕發(fā)送廣播。
b)設(shè)置一個(gè)按鈕進(jìn)行廣播接收器的注冊(cè)與注銷。
c)廣播接收器若已被注冊(cè),發(fā)送出的廣播信息能夠及時(shí)更新桌面上 Widget 上文字內(nèi)容及 更新為默認(rèn) dynamic 圖片。
d)點(diǎn)擊 Widget 上的圖片可以跳轉(zhuǎn)回主頁(yè)面。

實(shí)驗(yàn)步驟
首先,在Android Studio中創(chuàng)建Widget類,直接生成相關(guān)文件,其中包括界面布局XML文件、widget的provider文件信息(xml)以及在項(xiàng)目的AndroidMenifest.xml文件中添加了一個(gè)receiver標(biāo)簽,需要我們添加過(guò)濾更新事件,并需要指向之前創(chuàng)建的Widget類。
AndroidMenifest.xml文件中,intent-filter中過(guò)濾了APPWIDGET_UPDATE事件,這個(gè)事件是由系統(tǒng)觸發(fā)的更新事件,每個(gè)widget必須包含這個(gè)事件;meta-data標(biāo)簽描述的是widget的配置文件指向,該文件描述了widget的一些基本信息(其中由于需要在靜態(tài)注冊(cè)中實(shí)現(xiàn),intent-filter中也過(guò)濾了staticreceiver):
<receiver
android:name=".MyAppWidget"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
<action android:name="com.example.yanglh6.myapplication4.staticreceiver" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/my_app_widget_info"/>
</receiver>
接下來(lái)根據(jù)要求編寫widget的provider文件信息(xml),minWidth和minHeight是widget的最小寬度和高度,這個(gè)值是一個(gè)參考值,系統(tǒng)會(huì)根據(jù)實(shí)際情況進(jìn)行改變,initialLayout屬性指明widge的視圖布局文件,updatePeriodMillis屬性是widget每隔多久更新一次的時(shí)間,單位為毫秒:
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:initialKeyguardLayout="@layout/my_app_widget" android:initialLayout="@layout/my_app_widget" android:minHeight="55dp" android:minWidth="200dp" android:previewImage="@drawable/example_appwidget_preview" android:resizeMode="horizontal|vertical" android:updatePeriodMillis="86400000" android:widgetCategory="home_screen"></appwidget-provider>
接下來(lái)就是界面布局,在這個(gè)示例中需要一個(gè)ImageView控件和一個(gè)TextView控件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <ImageView android:id="@+id/WidgetImage" android:layout_width="60dp" android:layout_height="60dp" android:gravity="center" android:src="@mipmap/apple"/> <TextView android:id="@+id/WidgetName" android:layout_width="wrap_content" android:layout_height="60dp" android:textColor="@color/red" android:textSize="20dp" android:layout_toRightOf="@+id/WidgetImage" android:text="Apple" android:gravity="center"/> </RelativeLayout>
布局文件實(shí)現(xiàn)了一個(gè)如下圖的布局:

然后在Widget中,重寫onUpdate方法,為Widget添加事件,使得能夠返回主頁(yè)面。這里需要使用到一種用戶程序訪問(wèn)主屏幕和修改特定區(qū)域內(nèi)容的方法RemoteView架構(gòu)。RemoteView架構(gòu)允許用戶程序更新主屏幕的View,點(diǎn)擊 Widget激活點(diǎn)擊事件,Android會(huì)將其轉(zhuǎn)發(fā)給用戶程序,由AppWidgetProviders類處理,使得用戶程序可更新主屏幕Widget。
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
Intent clickInt = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, clickInt, 0);
RemoteViews view = new RemoteViews(context.getPackageName(),R.layout.my_app_widget);
view.setOnClickPendingIntent(R.id.WidgetImage, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, view);
}
接下來(lái)在Widge類中重寫onReceive方法,這里需要使用到RemoteView以及Bundle。當(dāng)接收到對(duì)應(yīng)廣播時(shí)進(jìn)行數(shù)據(jù)處理(由于我們?cè)贏ndroidMenifest.xml文件中注冊(cè)時(shí)將APPWIDGET_UPDAT事件和staticreceiver都指向Widge類,所以在這里我們StaticReceiver類刪掉,將里面對(duì)OnReceive函數(shù)重寫的部分添加在Widget類中):
@Override
public void onReceive(Context context, Intent intent) {
Log.i("debug", intent.toString());
super.onReceive(context, intent);
RemoteViews view = new RemoteViews(context.getPackageName(),R.layout.my_app_widget);
Bundle bundle = intent.getExtras();
String widgetName = bundle.getString("name");
int widgetImage = bundle.getInt("ItemImage");
if (intent.getAction().equals("com.example.yanglh6.myapplication4.staticreceiver")) {
view.setTextViewText(R.id.WidgetName, widgetName);
view.setImageViewResource(R.id.WidgetImage, widgetImage);
AppWidgetManager appWidgetManager=AppWidgetManager.getInstance(context);
appWidgetManager.updateAppWidget(new ComponentName(context, MyAppWidget.class), view);
Bitmap bitmap= BitmapFactory.decodeResource(context.getResources(),bundle.getInt("ItemImage"));
int imageId = (int) bundle.get("ItemImage");
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(context);
builder.setContentTitle("靜態(tài)廣播")
.setContentText(bundle.getString("name"))
.setLargeIcon(bitmap)
.setSmallIcon(imageId)
.setTicker("您有一條新消息")
.setAutoCancel(true);
Intent Intent1 = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, Intent1, 0);
builder.setContentIntent(pendingIntent);
Notification notify = builder.build();
notificationManager.notify(0, notify);
}
}
單獨(dú)把Widget部分onReceive方法的重寫列出:
public void onReceive(Context context, Intent intent) {
Log.i("debug", intent.toString());
super.onReceive(context, intent);
RemoteViews view = new RemoteViews(context.getPackageName(),R.layout.my_app_widget);
Bundle bundle = intent.getExtras();
String widgetName = bundle.getString("name");
int widgetImage = bundle.getInt("ItemImage");
if (intent.getAction().equals("com.example.yanglh6.myapplication4.staticreceiver")) {
view.setTextViewText(R.id.WidgetName, widgetName);
view.setImageViewResource(R.id.WidgetImage, widgetImage);
AppWidgetManager appWidgetManager=AppWidgetManager.getInstance(context);
appWidgetManager.updateAppWidget(new ComponentName(context, MyAppWidget.class), view);
}
}
對(duì)于動(dòng)態(tài)注冊(cè)來(lái)說(shuō),不需要在AndroidMenifest.xml添加receiver,但在DynamicActivity中進(jìn)行注冊(cè):
dynamicReceiver = new DynamicReceiver();
IntentFilter dynamic_filter = new IntentFilter();
dynamic_filter.addAction("com.example.yanglh6.myapplication4.dynamicreceiver");
registerReceiver(dynamicReceiver, dynamic_filter);
所以動(dòng)態(tài)注冊(cè)時(shí)只能在DynamicReceiver中對(duì)Onreceive函數(shù)進(jìn)行重寫,完成Widget的更新(與靜態(tài)注冊(cè)類似):
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("com.example.yanglh6.myapplication4.dynamicreceiver")) {
Bundle bundle = intent.getExtras();
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), bundle.getInt("ItemImage"));
int imageId = bundle.getInt("ItemImage");
RemoteViews view = new RemoteViews(context.getPackageName(),R.layout.my_app_widget);
String widgetName = bundle.getString("name");
view.setTextViewText(R.id.WidgetName, widgetName);
view.setImageViewResource(R.id.WidgetImage, imageId);
AppWidgetManager appWidgetManager=AppWidgetManager.getInstance(context);
appWidgetManager.updateAppWidget(new ComponentName(context, MyAppWidget.class), view);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(context);
builder.setContentTitle("動(dòng)態(tài)廣播")
.setContentText(widgetName)
.setLargeIcon(bitmap)
.setSmallIcon(imageId)
.setTicker("您有一條新消息")
.setAutoCancel(true);
Intent mIntent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, mIntent, 0);
builder.setContentIntent(pendingIntent);
Notification notify = builder.build();
notificationManager.notify(0, notify);
}
}
完成實(shí)驗(yàn)~
運(yùn)行截圖

注意事項(xiàng)
自己要充分理解AndroidMenifest.xml各部分的含義以及Android的機(jī)制,在AndroidMenifest.xml的注冊(cè)和指向必須清晰。
對(duì)于靜態(tài)來(lái)說(shuō),在sendBroadcast(intent)實(shí)現(xiàn)后,在AndroidMenifest.xml找到intent注冊(cè)時(shí)的receiver并指向?qū)?yīng)的廣播接收函數(shù),在這個(gè)函數(shù)中實(shí)現(xiàn)各個(gè)事件;對(duì)于動(dòng)態(tài)來(lái)說(shuō),由于在DynamicActivity中進(jìn)行注冊(cè),在那時(shí)可以定義指向的動(dòng)態(tài)廣播接收類。
源碼下載
注
本實(shí)驗(yàn)實(shí)驗(yàn)環(huán)境:
操作系統(tǒng) Windows 10
實(shí)驗(yàn)軟件 Android Studio 2.2.1
虛擬設(shè)備:Galaxy_Nexus
API:21
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android學(xué)習(xí)之BottomSheetDialog組件的使用
BottomSheetDialog是底部操作控件,可在屏幕底部創(chuàng)建一個(gè)支持滑動(dòng)關(guān)閉視圖。本文將通過(guò)示例詳細(xì)講解它的使用,感興趣的小伙伴可以了解一下2022-06-06
Android中RecyclerView拖拽、側(cè)刪功能的實(shí)現(xiàn)代碼
這篇文章主要介紹了Android中RecyclerView拖拽、側(cè)刪功能的實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-09-09
android PopupWindow 和 Activity彈出窗口實(shí)現(xiàn)方式
本人小菜一個(gè)。目前只見過(guò)兩種彈出框的實(shí)現(xiàn)方式,第一種是最常見的PopupWindow,第二種也就是Activity的方式是前幾天才見識(shí)過(guò),需要的朋友可以參考下2012-11-11
Android鬧鐘機(jī)制實(shí)現(xiàn)定時(shí)任務(wù)功能
這篇文章主要為大家詳細(xì)介紹了Android鬧鐘機(jī)制實(shí)現(xiàn)定時(shí)任務(wù)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
關(guān)于Android內(nèi)存緩存LruCache的使用及其源碼解析
LruCache作為內(nèi)存緩存,使用強(qiáng)引用方式緩存有限個(gè)數(shù)據(jù),當(dāng)緩存的某個(gè)數(shù)據(jù)被訪問(wèn)時(shí),它就會(huì)被移動(dòng)到隊(duì)列的頭部,本文詳細(xì)介紹了關(guān)于Android內(nèi)存緩存LruCache的使用及其源碼解析,需要的朋友可以參考下2023-05-05
Android SQLite數(shù)據(jù)庫(kù)操作代碼類分享
這篇文章主要介紹了Android SQLite數(shù)據(jù)庫(kù)操作代碼類分享,本文直接給出實(shí)現(xiàn)代碼和使用代碼,需要的朋友可以參考下2015-03-03
anndroid使用ViewPager實(shí)現(xiàn)三個(gè)fragment切換
這篇文章主要介紹了anndroid使用ViewPager實(shí)現(xiàn)三個(gè)fragment切換,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04

