`
Arthur_Wen
  • 浏览: 29960 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Android 2.2新增Widget之ProtipWidget源码

阅读更多
一开始,对widget一点不懂,自学了很长时间,才刚刚入门,这是在网上找的资料,觉得很好,分享给大家
[url]
http://www.android123.com.cn/yuanmaxiazai/564.html
[/url]

在Android 2.2 SDK中我们可能首次启动模拟器可以看到和以前不一样的是多出了一个绿色的小机器人提示信息,Google给我们了演示了Android中如何通过RemoteView和简单的图片轮换方式实现动画效果在桌面小工具中,appWidget的基类时AppWidgetProvider类,不过Widget本身的生命周期管理并非Activity,相对于的而是BroadcastReceiver广播方式处理的,Android 2.2新增的Widget的实现大家可以从中学习到很多有用的知识。

public class ProtipWidget extends AppWidgetProvider {
    public static final String ACTION_NEXT_TIP = "com.android.misterwidget.NEXT_TIP"; //定义action切换到下一条提示
    public static final String ACTION_POKE = "com.android.misterwidget.HEE_HEE"; //唤醒小机器人

    public static final String EXTRA_TIMES = "times";

    public static final String PREFS_NAME = "Protips";
    public static final String PREFS_TIP_NUMBER = "widget_tip";

    private static Random sRNG = new Random(); //轮换图片用到的,生成一个静态的随机数生成器

    private static final Pattern sNewlineRegex = Pattern.compile(" *\\n *");
    private static final Pattern sDrawableRegex = Pattern.compile(" *@(drawable/[a-z0-9_]+) *");   

    // 初始化时Droid是眼睛没有睁开,同时没有信息提示
    private int mIconRes = R.drawable.droidman_open;
    private int mMessage = 0;

    private AppWidgetManager mWidgetManager = null;
    private int[] mWidgetIds;
    private Context mContext;

    private CharSequence[] mTips;

    private void setup(Context context) {
        mContext = context;
        mWidgetManager = AppWidgetManager.getInstance(context);
        mWidgetIds = mWidgetManager.getAppWidgetIds(new ComponentName(context, ProtipWidget.class));

        SharedPreferences pref = context.getSharedPreferences(PREFS_NAME, 0);
        mMessage = pref.getInt(PREFS_TIP_NUMBER, 0);

        mTips = context.getResources().getTextArray(R.array.tips);

        if (mTips != null) {
            if (mMessage >= mTips.length) mMessage = 0;
        } else {
            mMessage = -1;
        }

    }

    public void goodmorning() {  //Android开发网提示线程中轮换图片,使用了500,200,100等这样的0.5秒休眠,0.2秒休眠实现了动画的间隔效果
        mMessage = -1;
        try {
            setIcon(R.drawable.droidman_down_closed);
            Thread.sleep(500);
            setIcon(R.drawable.droidman_down_open);
            Thread.sleep(200);
            setIcon(R.drawable.droidman_down_closed);
            Thread.sleep(100);
            setIcon(R.drawable.droidman_down_open);
            Thread.sleep(600);
        } catch (InterruptedException ex) {
        }
        mMessage = 0;
        mIconRes = R.drawable.droidman_open;
        refresh();
    }

    @Override
    public void onReceive(Context context, Intent intent) { //上面android123已经讲到了,appWidget是基于broadcastreceiver类的,所以说需要响应onReceive通过action来驱动事件。
        setup(context);

        if (intent.getAction().equals(ACTION_NEXT_TIP)) {
            mMessage = getNextMessageIndex();
            SharedPreferences.Editor pref = context.getSharedPreferences(PREFS_NAME, 0).edit();
            pref.putInt(PREFS_TIP_NUMBER, mMessage);
            pref.commit();
            refresh();
        } else if (intent.getAction().equals(ACTION_POKE)) {
            blink(intent.getIntExtra(EXTRA_TIMES, 1));
        } else if (intent.getAction().equals(AppWidgetManager.ACTION_APPWIDGET_ENABLED)) {
            goodmorning();
        } else {
            mIconRes = R.drawable.droidman_open;
            refresh();
        }
    }

    private void refresh() {  //管理如果有多个本widget执行需要逐个更新
        RemoteViews rv = buildUpdate(mContext);
        for (int i : mWidgetIds) {
            mWidgetManager.updateAppWidget(i, rv);
        }
    }

    private void setIcon(int resId) {
        mIconRes = resId;
        refresh();
    }

    private int getNextMessageIndex() {
        return (mMessage + 1) % mTips.length;
    }

    private void blink(int blinks) {
            if (mMessage < 0) return;

     //Android123提示大家比较有意思的就是小绿人眼睛的一开一闭,这里使用的是图片轮换方式来实现动画效果,在appWidget中我们可以用的控件十分少

        setIcon(R.drawable.droidman_closed); 
        try {
            Thread.sleep(100);
            while (0<--blinks) {
                setIcon(R.drawable.droidman_open);
                Thread.sleep(200);
                setIcon(R.drawable.droidman_closed);
                Thread.sleep(100);
            }
        } catch (InterruptedException ex) { }
        setIcon(R.drawable.droidman_open);
    }

    public RemoteViews buildUpdate(Context context) {
        RemoteViews updateViews = new RemoteViews(
            context.getPackageName(), R.layout.widget); //映射布局,widget.xml文件的源码在下面可以找到

        // 按下bubble的事件,对应action_next_tip动作
        Intent bcast = new Intent(context, ProtipWidget.class);
        bcast.setAction(ACTION_NEXT_TIP);
        PendingIntent pending = PendingIntent.getBroadcast(
            context, 0, bcast, PendingIntent.FLAG_UPDATE_CURRENT);
        updateViews.setOnClickPendingIntent(R.id.tip_bubble, pending);

       //这里为action_poke
        bcast = new Intent(context, ProtipWidget.class);
        bcast.setAction(ACTION_POKE);
        bcast.putExtra(EXTRA_TIMES, 1);
        pending = PendingIntent.getBroadcast(
            context, 0, bcast, PendingIntent.FLAG_UPDATE_CURRENT);
        updateViews.setOnClickPendingIntent(R.id.bugdroid, pending);

        // Tip bubble text
        if (mMessage >= 0) {
            String[] parts = sNewlineRegex.split(mTips[mMessage], 2);
            String title = parts[0];
            String text = parts.length > 1 ? parts[1] : "";

            // Look for a callout graphic referenced in the text
            Matcher m = sDrawableRegex.matcher(text);
            if (m.find()) {
                String imageName = m.group(1);
                int resId = context.getResources().getIdentifier(

                    imageName, null, context.getPackageName());
                updateViews.setImageViewResource(R.id.tip_callout, resId);
                updateViews.setViewVisibility(R.id.tip_callout, View.VISIBLE);
                text = m.replaceFirst("");
            } else {
                updateViews.setImageViewResource(R.id.tip_callout, 0);
                updateViews.setViewVisibility(R.id.tip_callout, View.GONE);
            }

            updateViews.setTextViewText(R.id.tip_message, 
                text);
            updateViews.setTextViewText(R.id.tip_header,
                title);
            updateViews.setTextViewText(R.id.tip_footer, 
                context.getResources().getString(
                    R.string.pager_footer,
                    (1+mMessage), mTips.length));
            updateViews.setViewVisibility(R.id.tip_bubble, View.VISIBLE);
        } else {
            updateViews.setViewVisibility(R.id.tip_bubble, View.INVISIBLE);
        }

        updateViews.setImageViewResource(R.id.bugdroid, mIconRes);

        return updateViews;
    }
}

有关AndroidManifest.xml中详细的recevier代码如下
<receiver android:name=".ProtipWidget" android:label="@string/widget_name">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <action android:name="com.android.protips.NEXT_TIP" />
                <action android:name="com.android.protips.HEE_HEE" />
            </intent-filter>
            <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_build" />
        </receiver>

有关res/xml/widget_build.xml的代码如下

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="294dip"
    android:minHeight="72dip"
    android:updatePeriodMillis="0"
    android:initialLayout="@layout/widget" />

有关res/layout/widget.xml的代码如下,注意下面使用了布局文件套嵌的include方式

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/widget"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="5dip"
    >

    <include layout="@layout/droid" />
    <include layout="@layout/bubble" />
</RelativeLayout>


有关res/layout/droid.xml的代码如下

 <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/bugdroid"
    android:src="@drawable/droidman_down_closed"
    android:scaleType="center"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true"
    />


有关res/layout/bubble.xml的代码如下

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tip_bubble"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_toLeftOf="@+id/bugdroid"
    android:layout_centerVertical="true"
    android:gravity="center_vertical|left"
    android:layout_marginRight="2dip"
    android:visibility="invisible"
    android:background="@drawable/droid_widget"
    android:focusable="true"
    >
    <TextView
        android:layout_width="0dip"
        android:layout_height="0dip"
        android:layout_alignParentTop="true"
        android:layout_marginTop="-100dip"
        android:text="@string/widget_name"
        />
    <TextView
        android:layout_width="0dip"
        android:layout_height="0dip"
        android:layout_alignParentTop="true"
        android:layout_marginTop="-90dip"
        android:text="@string/tts_pause"
        />
    <TextView
        android:id="@+id/tip_footer"
        style="@style/TipText.Footer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginRight="1dip"
        />
    <ImageView
        android:id="@+id/tip_callout"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:gravity="center"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:layout_above="@id/tip_footer"
        android:visibility="gone"
        android:padding="4dip"
        />
    <TextView
        android:id="@+id/tip_header"
        style="@style/TipText.Header"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_toLeftOf="@id/tip_callout"
        android:layout_alignWithParentIfMissing="true"
        android:layout_marginTop="0dip"
        android:layout_marginLeft="3dip"
        />
    <TextView
        android:id="@+id/tip_message"
        style="@style/TipText.Message"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/tip_header"
        android:layout_alignLeft="@id/tip_header"
        android:layout_alignRight="@id/tip_header"
        android:layout_marginTop="1dip"
        />
</RelativeLayout>


有关上面bubble.xml中的drawable对象droid_widget的代码如下

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/droid_widget_pressed" />
    <item android:state_focused="true" android:state_window_focused="true" android:drawable="@drawable/droid_widget_focused" />
    <item android:state_focused="true" android:state_window_focused="false" android:drawable="@drawable/droid_widget_normal" />
    <item android:drawable="@drawable/droid_widget_normal" />
</selector>
分享到:
评论

相关推荐

    android2.2 view widget源码

    这里我们深入探讨Android 2.2版本的View和Widget的源码,以及与之相关的List Adapter、Scroll和Animation等概念。 首先,`View`类是Android UI的基本构建块,它代表屏幕上的一个矩形区域,可以接收触摸事件并进行...

    android2.2中午widget文档(chm)

    android的中文API文档 电子书形式的,不能复制,是图片版 主要是几种常用的widget组件

    Android2.2 widget小程序

    《Android2.2小部件(Widget)开发详解》 Android平台的小部件(Widget)是其桌面环境中的一个重要组成部分,允许用户在主屏幕上放置各种应用程序的功能快捷方式或动态展示信息。本教程将深入探讨如何在Android 2.2...

    Android 2.2 Launcher源码

    《深入剖析Android 2.2 Launcher源码》 在Android操作系统中,Launcher是用户与系统交互的首要界面,它承担着应用启动、桌面布局管理、快捷方式创建等核心功能。对于开发者来说,理解Launcher的源码是提升Android...

    Android2.2 r1 API中文文档——CheckBox.doc

    java.lang.Object ↳ android.view.View ↳ android.widget.TextView ↳ android.widget.Button ↳ android.widget.CompoundButton ↳ android.widget.CheckBox ``` 这意味着`CheckBox`不仅具备按钮的属性,还包含`...

    Android 2.2系统性能提升测试.doc

    1. **程序安装到内存卡**:Android 2.2最大的亮点之一是允许应用程序直接安装到SD卡上,这样极大地扩展了手机的存储空间,让用户可以下载和安装更多的应用。 2. **USB/Wi-Fi热点功能**:Froyo添加了USB和Wi-Fi热点...

    Android 2.2 绿色机器人源代码

    对于那些面临AppWidget在屏幕旋转时数据丢失或事件处理失效问题的开发者来说,深入理解Android 2.2的源代码至关重要。Android AppWidget是可以在主屏幕上显示小型应用程序组件的系统服务,它为用户提供了一种与应用...

    android widget 开发实例源码

    本教程将深入探讨如何使用Android Widget,通过提供的源码实例,涵盖了一系列基本到高级的组件,包括Button、Chronometer、Clock、DateTime、Edit、Gallery、Grid、Misc、Popup、Progress、Spinner和Video。...

    android Launcher添加widget源码

    通过分析JYCLauncher的源码,我们可以深入了解Android自定义Launcher中添加Widget的细节,以及如何实现动态添加功能。这不仅可以帮助开发者理解Android系统的内部工作原理,还能为开发具有独特特性的Launcher应用...

    android 源码 android Widget开发案例 eclipse项目 直接导入

    这个“android 源码 android Widget开发案例 eclipse项目 直接导入”是一个很好的学习资源,帮助开发者深入理解如何构建和定制Widget。通过Eclipse IDE可以直接导入该项目,快速开始学习。 首先,我们需要了解...

    Android 天气预报加widget源码

    接下来,我们将详细探讨这个"Android天气预报加Widget源码"所涵盖的关键知识点。 首先,我们要理解Android天气预报应用的核心在于获取天气数据。这通常通过调用第三方天气API来实现,如OpenWeatherMap或AccuWeather...

    Android应用源码之Android小部件AppWidget.zip项目安卓应用源码下载

    Android应用源码之Android小部件AppWidget.zip项目安卓应用源码下载Android应用源码之Android小部件AppWidget.zip项目安卓应用源码下载 1.适合学生毕业设计研究参考 2.适合个人学习研究参考 3.适合公司开发项目技术...

    android2.2phone 打电话简单入门实例

    import android.widget.Button; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { private Button buttonCall; @Override protected void ...

    Android应用源码之android Widget小组件开发.zip项目安卓应用源码下载

    Android应用源码之android Widget小组件开发.zip项目安卓应用源码下载Android应用源码之android Widget小组件开发.zip项目安卓应用源码下载 1.适合学生毕业设计研究参考 2.适合个人学习研究参考 3.适合公司开发项目...

    android 数字时钟widget 源码

    这里我们深入探讨一下"android 数字时钟widget 源码"的相关知识点,以及如何实现这一功能。 首先,让我们了解什么是Android Widget。Android Widget是Android应用程序的一部分,可以在用户的主屏幕上提供快捷方式或...

    Android应用源码之android Widget小组件开发-IT计算机-毕业设计.zip

    总之,这个"Android应用源码之android Widget小组件开发"项目提供了宝贵的实践经验,对于想要深入了解Android平台、尤其是移动应用毕业设计的学生来说,是一个非常有价值的资源。通过研究源码,你可以更好地掌握...

    Android 仿Facebook滑动菜单-支持android 2.2

    这个压缩包文件“slidingMenu”提供了一种实现这一功能的解决方案,适用于Android 2.2及更高版本的系统。接下来,我们将详细讨论如何理解和实现这样一个滑动菜单。 首先,滑动菜单通常指的是侧滑抽屉(Sliding ...

    Android2.2—API中文文档

    它的继承结构是java.lang.Object -&gt; android.view.View -&gt; android.widget.TextView。TextView有许多子类,包括Button、CheckedTextView和Chronometer等,这些子类都扩展了TextView的功能。例如,EditText则是一个可...

Global site tag (gtag.js) - Google Analytics