`
yuanlanjun
  • 浏览: 1184426 次
文章分类
社区版块
存档分类
最新评论

Android Widget日历 完整示例分析

 
阅读更多
第六部分 Widget日历
本例实现了Widget日历,用来显示当前的日期,时间等信息。要学习开发Widget开发,需要了解AppWidget的框架结构。基于该框架,开发者可以在Ophone及模拟器上开发"外形"
类似传统的Widget小应用程序,并将其嵌入到其他应用中。
注意:Widget设计好UI后根据需要来完成更新,如果程序不需要使用定时来更新AppWidget,则最好不要使用定时更新,因为它会增加电量和CUP资源的开销。我们可以定义一个线程,当需要
时才更新,这样可以让Widget达到最高效率
AppWidget框架主要包括以下类:
AppWidgetProvider: 该类继承自BroadcastReceiver,在AppWidget应用update、enable、disable、deleted时接受通知。其中,onUpdate、onReceive用来接收更新通知。
AppWidgetProviderInfo:该类主要用于AppWidget的大小、更新频率和初始界面等信息,以XML文件形式存在于res/xml目录下。
AppWidgetManager:该类负则管理AppWidget,及向AppWidgetProvider发送通知。
RemoteViews:一个可以在其他应用进程中运行的类,是构造AppWidget的核心。

Widget开发流程
res.layout.widget_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="146dp"
android:minWidth="146dp"
android:background="@drawable/bgblack"
android:id="@+id/Base"
>
<LinearLayout//需要3个TextView来显示日期
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center"
android:paddingTop="5dip"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Month"
android:layout_gravity="center"
android:textStyle="bold"
android:textSize="18sp"
android:textColor="#FFFFFF"
></TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/Date"
android:textStyle="bold"
android:textSize="70sp"
android:textColor="#FFFFFF"
></TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/WeekDay"
android:layout_gravity="center"
android:textSize="15sp"
android:textStyle="bold"
android:textColor="#FFFFFF"
></TextView>
</LinearLayout>
</LinearLayout>

res.xml.widget.xml
<?xml version="1.0" encoding="utf-8"?>//一个能反映出AppWidgetProviderInfo信息的布局文件。AppWidget的像素大小取决于它所占方块多少(计算公式(块数*74)-2),因此
取高度为146像素,宽度是146像素
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/widget_layout" //设置AppWidget的布局文件为widget_layout布局
android:minWidth="146dip"
android:minHeight="146dip"
android:updatePeriodMillis="3600000">
</appwidget-provider>

//res.xml.widget_small.xml
//<?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="72dip"
//android:minHeight="72dip"
//android:updatePeriodMillis="3600000">
//</appwidget-provider>

//res.layout.widget_layout_small.xml
//<?xml version="1.0" encoding="utf-8"?>
//<LinearLayout
//xmlns:android="http://schemas.android.com/apk/res/android"
//android:orientation="vertical"
//android:layout_width="wrap_content"
//android:layout_height="wrap_content"
//android:minHeight="72dip"
//android:minWidth="72dip"
//android:background="@drawable/bgblacksmall"
//android:id="@+id/SmallBase"
//>
//<LinearLayout
//android:layout_width="wrap_content"
//android:layout_height="wrap_content"
//android:orientation="vertical"
//android:layout_gravity="center"
//android:paddingTop="5dip"
//>
//<TextView
//android:layout_width="wrap_content"
//android:layout_height="wrap_content"
//android:id="@+id/Month"
//android:layout_gravity="center"
//android:textStyle="bold"
//android:textSize="12sp"
//android:gravity="center"
//android:textColor="#FFFFFF"
//></TextView>
//<TextView
//android:layout_width="wrap_content"
//android:layout_height="wrap_content"
//android:layout_gravity="center"
//android:id="@+id/Date"
//android:textStyle="bold"
//android:textSize="30sp"
//android:textColor="#FFFFFF"
//></TextView>
//</LinearLayout>
//</LinearLayout>

public class TodayDate extends AppWidgetProvider{//当我们添加AppWidget应用或自动定时更新时,AppWidgetManager会广播动作名字是"android.appwidget.action.APPWIDGET_UPDATE"
的Intent,当onReceive()方法没有被重载时,onUpdate方法会接收到这些广播的Intent。类似BroadcastReceiver类,我们可以
重载AppWidgetProvider的onReceive方法,并在其中指定想要接收的Intent
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){
RemoteViews updateView = buildUpdate(context);
appWidgetManager.updateAppWidget(appWidgetIds, updateView);
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
private String[] months = {"一月", "二月", "三月", "四月","五月", "六月", "七月", "八月","九月", "十月", "十一月", "十二月"};
private String[] days = {"星期日", "星期一", "星期二", "星期三","星期四", "星期五", "星期六"};
private RemoteViews buildUpdate(Context context){
RemoteViews updateView = null;
Time time = new Time();
time.setToNow();
String month = months[time.month] + " " + time.year;
updateView = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
updateView.setTextViewText(R.id.Date, new Integer(time.monthDay).toString());
updateView.setTextViewText(R.id.Month, month);
updateView.setTextViewText(R.id.WeekDay, days[time.weekDay]);
Intent launchIntent = new Intent();
launchIntent.setComponent(new ComponentName("com.android.calendar", "com.android.calendar.LaunchActivity"));
launchIntent.setAction(Intent.ACTION_MAIN);
launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
PendingIntent intent = PendingIntent.getActivity(context, 0, launchIntent, 0);
updateView.setOnClickPendingIntent(R.id.Base, intent);
return updateView;
}
}

//public class TodayDateSmall extends AppWidgetProvider{
//public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
//RemoteViews updateView = buildUpdate(context);
//appWidgetManager.updateAppWidget(appWidgetIds, updateView);
//super.onUpdate(context, appWidgetManager, appWidgetIds);
//}
//private String[] months = {"一月", "二月", "三月", "四月","五月", "六月", "七月", "八月","九月", "十月", "十一月", "十二月"};
//private RemoteViews buildUpdate(Context context) {
//RemoteViews updateView = null;
//Time time = new Time();
//time.setToNow();
//String month = months[time.month];
//updateView = new RemoteViews(context.getPackageName(), R.layout.widget_layout_small);
//updateView.setTextViewText(R.id.Date, new Integer(time.monthDay).toString());
//updateView.setTextViewText(R.id.Month, month);
//Intent launchIntent = new Intent();
//launchIntent.setComponent(new ComponentName("com.android.calendar", "com.android.calendar.LaunchActivity"));
//launchIntent.setAction(Intent.ACTION_MAIN);
//launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
//launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
//PendingIntent intent = PendingIntent.getActivity(context, 0, launchIntent, 0);
//updateView.setOnClickPendingIntent(R.id.SmallBase, intent);
//return updateView;
//}
//}

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>//因为使用了receiver及"adroid.appwidget.action.APPWIDGET_UPDATE"所以需要声明权限
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yarin.android.TodayDate"
android:versionCode="1"
android:versionName="1.0">
<application
android:icon="@drawable/icon"
android:label="@string/app_name">
<receiver
android:label="@string/app_name"
android:name=".TodayDate">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"></action>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget">
</meta-data>
</receiver>
<receiver
android:label="@string/app_name_small"
android:name=".TodayDateSmall">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"></action>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_small">
</meta-data>
</receiver>
</application>
<uses-sdk android:minSdkVersion="5" />
</manifest>

续:
1、上例中只是更新显示了一个界面,在Widget中同样可以通过setOnClickPendingIntent方法来监听一个事件的处理,下面代码中当我们点击了"widget_button"按钮时,会弹出Toast提示
public class widget extends AppWidgetProvider{
public void onReceive(Context context, Intent intent){
super.onReceive(context,intent);
if(intent.getAction().equals("com.android.myapp.widget.CLICK")){
Toast.makeText(context ,"It works!!", Toast.LENGTH_SHORT).show();
}
}
public void onUpdate(Context context,AppWidgetManager mgr, int[] appWidgetIds){
final int N = appWidgetIds.length;
for(int i=0; i<N; i++){
int [] appWidgetId = appWidgetIds;
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.main);
Intent clickintent = new Intent("com.android.myapp.widget.CLICK");
PendingIntent pendingIntentClick = PendingIntent.getBroadcast(context, 0,clickintent,0);
views.setOnClickPendingIntent(R.id.widget_butt,PendingIntentClick);
mrg.updateAppWidget(appWidgetId,views);
}
}
}
2、在Widget中启动一个Activity,
RemoteViews rv = new RemoteViews(context.getPackageName(),R.layout.mywidget);
Intent intentActivity = new Intent(context, MusicPlayer.class);//此处启动一个音乐播放界面
PendingIntent pendingIntentActivity = PendingIntent.getActivity(context,0,intentActivity,0);
rv.setOnClickPendingIntent(R.id.button,pendingIntentActivity);
appWidgetManager.updateAppWidget(appWidgetId,rv);
context.startActivity(intentActivity);//当点击"button"按钮时启动自动Activity
3、Wdiget启动Service
RemoteViews rv = new RemoteViews(context.getPackageName(),R.layout.mywidget);
Intent intentService = new Intent("Service名字");
context.startService(intentService);
appWidgetManager.updateAppWidget(appWdigetgetId,rv);

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics