AndroidWidget 桌面小控件 ; 完成效果 : 桌面展示 : xx年 xx月 xx日 xx时 xx分 xx秒
实现效果:
部分属性解释:
textSize:设置显示文字大小
textColor:设置显示文字的字体颜色
Gravity:设置文字位置
有关AndroidManager的部分知识点:
我们Android平台是一个又一个的Activity组成的,每一个Activity有一个或者多个View构成。所以说,当我们想显示一个界面的时候,我们首先想到的是建立一个Activity,然后所有的操作在Activity里面实现,或者是一个Dialog或者Toast。这种方式固然简单,但是在有些情况下,我们要求的只是简单的显示,用Activity显然是多余,这个时候,我们如何处理呢?
原来,整个Android的窗口机制是基于一个叫做 WindowManager,这个接口可以添加view到屏幕,也可以从屏幕删除view。它面向的对象一端是屏幕,另一端就是View,直接忽略我们以前的Activity或者Dialog之类的东东。其实我们的Activity或者Diolog底层的实现也是通过WindowManager,这个 WindowManager是全局的,整个系统就是这个唯一的东东。它是显示View的最底层了。
写一个简单的代码:
WindowManager mWm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
Button view = new Button(this);
view.setText("window manager test!");
WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
mWm.addView(view, mParams);
一般在刚开始开发android时,会犯一个错误,即在View的构造函数中获取getWidth()和getHeight(),当一个view对象创建时,android并不知道其大小,所以getWidth()和getHeight()返回的结果是0,真正大小是在计算布局时才会计算,所以会发现一个有趣的事,即在onDraw( ) 却能取得长宽的原因。 width = activity.getWindowManager().getDefaultDisplay().getWidth(); height = activity.getWindowManager().getDefaultDisplay().getHeight();
首先配置一个XML文件,在res/Layout下进行创建,这个XML文件用于显示我们需要显示的内容
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/widget_tv"
android:textSize="20sp"
android:textColor="#fff"
/>
</LinearLayout>
然后在主类中开启一个服务,进行时间的更新
package com.example.android_todaywidget;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
//继承AppWidgetProvider进行对小控件操作
public class WidgetProvider extends AppWidgetProvider {
private static final String TAG = "I Love---->";
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.i(TAG, "I Love---->Receive");
super.onReceive(context, intent);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
/*@Override
public void onDeleted(Context context, int[] appWidgetIds) {
// TODO Auto-generated method stub
super.onDeleted(context, appWidgetIds);
}*/
//开启服务的方法
@Override
public void onEnabled(Context context) {
// TODO Auto-generated method stub
super.onEnabled(context);
//关闭服务器
Intent service = new Intent();
context.startService(service);
}
//最后一个移除控件的方法
@Override
public void onDisabled(Context context) {
// TODO Auto-generated method stub
super.onDisabled(context);
//开启服务器
Intent service = new Intent();
context.stopService(service);
}
}
以下是更新时间的服务代码(Service)
package com.example.android_todaywidget;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import android.annotation.SuppressLint;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Intent;
import android.os.IBinder;
import android.widget.RemoteViews;
public class UpdateService extends Service {
private Timer time;
private RemoteViews remoteViews;
private SimpleDateFormat dateFormat;
//Widget的管理者
private AppWidgetManager manager;
//ConponentName(组建名称):是用来打开其他应用程序中的Activity或者服务的
private ComponentName provider;
@SuppressLint("SimpleDateFormat")
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
//定义时间获取类来获取对应的时间信息
time = new Timer();
dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
//getInstance()静态方法,通过类名进行调用
manager = AppWidgetManager.getInstance(getApplicationContext());
provider = new ComponentName(getApplicationContext(), WidgetProvider.class);
//延时操作
time.schedule(new TimerTask() {
//延时过程中应该做什么动作
@Override
public void run() {
updateView();
}
}, 0, 1000);//1000的意思是1秒
}
//这个方法的意思是对时间进行更新,并且在组件上进行更新
public void updateView(){
//远程视图App Widget中的视图都是通过RemoteViews来实现的。
remoteViews = new RemoteViews(getPackageName(), R.layout.time_widget_layout);
remoteViews.setTextViewText(R.id.widget_tv, dateFormat.format(new Date()));
/**
* SimpleDateFormat 允许以为日期-时间格式化选择任何用户指定的方式启动。 但是,希望用 DateFormat
* 中的 getTimeInstance、 getDateInstance 或 getDateTimeInstance
* 创建一个日期-时间格式化程序。
* 每个类方法返回一个以缺省格式化方式初始化的日期/时间格式化程序。
* 可以根据需要用 applyPattern 方法修改格式化方式。
*/
manager.updateAppWidget(provider, remoteViews);
}
//服务用完之后要进行关闭
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
// 取消时间,并且干为空
time.cancel();
time = null;
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}