`
yunshangbuhe
  • 浏览: 223146 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多
面便签软件是android上常用软件的一种,比如比较早的Sticky Note,就曾非常流行,

Sticky Note的介绍可以参见 http://www.tompda.com/c/article/11778/

而实际上使用android平台对widget开发的支持,桌面便签类软件是非常易于开发的。

本文通过逐步实现一个简单的桌面便签软件,和大家分享进行widget开发的过程和方法。


--------------------------------------------------------------------------------

1.MyNote的最终实现效果
为了提起大家阅读本文的兴趣,先介绍一下最终实现的效果。

首先可以通过桌面增加我们的MyNote小部件,如下图所示:



图中的“我的便签”就是我们之后将要开发的便签程序。

点击后启动添加日志界面,如下图所示:



输入便签内容后,可以点击下面所列的四种图标之一作为便签图标。

比如点击第一个后,桌面上就会添加一个便签:



点击桌面上的便签,可以再次对便签内容进行修改,并更换图标。

桌面上可以同时存在多个便签,并可以分别进行修改。

如下图所示,我们将刚才创建的便签的图标修改一下,并新增了一个便签:



每个便签的内容都是分别独立保存的,可以随时点击桌面图标修改。


--------------------------------------------------------------------------------

2.开发方式
开发的目的和追求的效果已经十分清楚了,首先我们确定一下开发方式。

在本文中,将采取一种渐进式的开发,也就是说不会一口气从头做到尾。

而是分为好几个阶段。每个阶段都完成一定的目标,然后下个阶段增加更多的功能,

每个阶段都离最终目标更进一步,OK,你可以说这是一次敏捷开发

第一个阶段,首先我们会搭建一个widget原型程序,

它是完全可以运行的,可以创建桌面widget。

第二个阶段,我们改进 widget 配置Activity 部分的实现

使其具备创建便签的功能

第三个阶段,我们改进 widget 点击响应部分的实现,

使其具备修改便签的功能


--------------------------------------------------------------------------------

3.搭建widget原型程序
本节我们会做一个最简单的widget程序原型,但是它是可以运行的。

一般来说 widget 程序由以下部分组成:

a. AppWidgetProvider 的实现

b. widget外观布局定义文件

c. 新增widget时的配置Activity的实现(可选)

d. widget 参数配置文件

以下分别讲解

a. AppWidgetProvider 的实现
首先我们新建一个android工程起名为MyNote,然后修改 MyNote.java 的代码,

使MyNote继承自 AppWidgetProvider ,并重写 onUpdate 和 onDeleted 方法。

其中onUpdate 会在widget创建及被更新时调用, onDeleted 会在widget被删除时调用。

目前我们不需要在这里实现任何功能,只是简单的记录日志以便我们观察其运行,编写好的代码如下:

view plaincopy to clipboardprint?
package com.silenceburn;  
 
import android.appwidget.AppWidgetManager;  
import android.appwidget.AppWidgetProvider;  
import android.content.Context;  
import android.util.Log;  
 
public class MyNote extends AppWidgetProvider {  
    /** Called when the activity is first created. */ 
      
    final String mPerfName = "com.silenceburn.MyColorNoteConf";  
 
    @Override 
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,  
            int[] appWidgetIds) {  
        // TODO Auto-generated method stub  
        final int N = appWidgetIds.length;  
        for (int i = 0; i < N; i++) {  
            int appWidgetId = appWidgetIds[i];  
            Log.i("myLog", "this is [" + appWidgetId + "] onUpdate!");  
 
        }  
    }  
 
    @Override 
    public void onDeleted(Context context, int[] appWidgetIds) {  
        // TODO Auto-generated method stub  
        final int N = appWidgetIds.length;  
        for (int i = 0; i < N; i++) {  
            int appWidgetId = appWidgetIds[i];  
            Log.i("myLog", "this is [" + appWidgetId + "] onDelete!");  
        }  
    }  
 

package com.silenceburn;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.util.Log;

public class MyNote extends AppWidgetProvider {
/** Called when the activity is first created. */

final String mPerfName = "com.silenceburn.MyColorNoteConf";

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
Log.i("myLog", "this is [" + appWidgetId + "] onUpdate!");

}
}

@Override
public void onDeleted(Context context, int[] appWidgetIds) {
// TODO Auto-generated method stub
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
Log.i("myLog", "this is [" + appWidgetId + "] onDelete!");
}
}

}

b. widget外观布局定义文件
我们需要为widget编写一个外观布局文件,在本示例中,布局非常简单,只需要一个imageView即可

编写好的 my_note_widget.xml 文件如下:

view plaincopy to clipboardprint?
<?xml version="1.0" encoding="utf-8"?> 
<ImageView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/my_widget_img" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:src="@drawable/sketchy_paper_008" 
    android:clickable="true"/> 
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/my_widget_img"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/sketchy_paper_008"
    android:clickable="true"/>

这里用到了一个外部图片 sketchy_paper_008.png,来源于网络,感谢图片原作者。

可以到 http://dryicons.com/free-icons/preview/sketchy-paper-icons/ 打包下载。

(  注意下载下来的包中的文件名可能和我写的程序中的命名有差异,请注意自行调整。)

c. 新增widget时的配置Activity的实现(可选)
android平台为widget提供一个配置界面的功能,我们可以自定义一个Activity,

在widget参数配置文件中配置好相关参数后,此Activity会在用户新增widget时自动调用。

一般来说,这个配置界面的作用是用户新建widget时,让用户配置widget的一些属性,比如颜色、大小等等。

但是在我们的这个示例程序中,我们用它来当做创建便签的地方!

不过本节只是先实现一个原型程序,所以暂时不做处理,我们只是新建一个Activity即可。

新建名为MyNoteConf的Activity,重写onCreate方法,在OnCreate方法中,

由于这个Activity是由系统在新增widget时自动调用的,

所以我们可以用getIntent获取到传入的widgetId。可以判断其是否是一个有效的widgetId,

最后我们必须返回一个RESULT_OK的Intent,并结束当前Activity,系统才会认为配置成功,在桌面上放置这个widget。

如果返回RESULT_CANCELED,系统会认为配置失败,终止widget的创建过程。

编写好的MyNoteConf的代码如下:

view plaincopy to clipboardprint?
package com.silenceburn;  
 
import android.app.Activity;  
import android.appwidget.AppWidgetManager;  
import android.content.Intent;  
import android.os.Bundle;  
import android.util.Log;  
 
public class MyNoteConf extends Activity {  
      
    int mAppWidgetId;  
      
    @Override 
    protected void onCreate(Bundle savedInstanceState) {  
        // TODO Auto-generated method stub  
        super.onCreate(savedInstanceState);  
          
        Log.i("myLog"," on WidgetConf ... ");  
          
        setResult(RESULT_CANCELED);  
          
        // Find the widget id from the intent.  
        Intent intent = getIntent();  
        Bundle extras = intent.getExtras();  
        if (extras != null) {  
            mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,  
                    AppWidgetManager.INVALID_APPWIDGET_ID);  
        }  
 
        // If they gave us an intent without the widget id, just bail.  
        if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {  
            finish();  
        }  
          
        // return OK  
        Intent resultValue = new Intent();  
        resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,  
                mAppWidgetId);  
          
        setResult(RESULT_OK, resultValue);  
        finish();  
    }  

package com.silenceburn;

import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

public class MyNoteConf extends Activity {

int mAppWidgetId;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);

Log.i("myLog"," on WidgetConf ... ");

setResult(RESULT_CANCELED);

// Find the widget id from the intent.
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
}

// If they gave us an intent without the widget id, just bail.
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
}

// return OK
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
mAppWidgetId);

setResult(RESULT_OK, resultValue);
finish();
}
}

d. widget 参数配置文件
最后我们需要编写一个widget参数配置文件,将布局文件、配置Activity关联起来。

我们在res下新建目录xml,在xml目录下新增文件 my_note_widget.xml ,编写如下:

view plaincopy to clipboardprint?
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" 
    android:minWidth="72dp" android:minHeight="72dp" 
    android:updatePeriodMillis="86400000" android:initialLayout="@layout/my_note_widget" 
    android:configure="com.silenceburn.MyNoteConf"> 
</appwidget-provider> 
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="72dp" android:minHeight="72dp"
android:updatePeriodMillis="86400000" android:initialLayout="@layout/my_note_widget"
android:configure="com.silenceburn.MyNoteConf">
</appwidget-provider>

其中 minWidth minHeight 用来指定widget的大小,如果我们只占用一个格子,也就是俗称的1X1,

那么72dp的长宽是android平台推荐的一个最佳实践值。

然后用 initialLayout 参数关联了我们编写好的 layout 文件,

用 configure 参数关联了我们编写好的配置用Activity:MyNoteConf,

此外还有一个参数 updatePeriodMills 指定widget的刷新周期,

从省电角度考虑,一般都把此值设置的比较大,如果一定要对widget做周期性的事情,可以使用AlarmManager。

至此所有widget的要素都已经准备好,我们运行一下来看看吧。


--------------------------------------------------------------------------------

4.运行widget原型程序
为了运行widget,我们还需要修改一下 AndroidManifest.xml 来声明我们的widget。

声明一个receiver,过滤 android.appwidget.action.APPWIDGET_UPDATE ,

并且用metadata关联到我们自己编写的 appWidgetProvider 实现。

声明一个activity关联到我们的配置类 MyNoteConf,过滤 android.appwidget.action.APPWIDGET_CONFIGURE。

最后修改一下应用图标,此图标会出现在系统的新增widget列表中。

编写好的AndroidManifest.xml 如下:

view plaincopy to clipboardprint?
<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.silenceburn" android:versionCode="1" android:versionName="1.0"> 
    <application android:icon="@drawable/sketchy_paper_008" 
        android:label="@string/app_name"> 
        <receiver android:name=".MyNote"> 
            <intent-filter> 
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
            </intent-filter> 
            <meta-data android:name="android.appwidget.provider" 
                android:resource="@xml/my_note_widget" /> 
        </receiver> 
 
        <activity android:name=".MyNoteConf"> 
            <intent-filter> 
                <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" /> 
            </intent-filter> 
        </activity> 
    </application> 
</manifest>  
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.silenceburn" android:versionCode="1" android:versionName="1.0">
<application android:icon="@drawable/sketchy_paper_008"
android:label="@string/app_name">
<receiver android:name=".MyNote">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/my_note_widget" />
</receiver>

<activity android:name=".MyNoteConf">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
</application>
</manifest> 

至此原型程序全部开发完成,运行一下看看效果吧!

在桌面上长点,可以选择我们刚刚写的原型widget“MyNote”了,

选择后出现我们定义的配置界面MyNoteConf,

但是由于我们在onCreate中finish了,所以是一闪而过的。

之后MyNote就出现在桌面上了。

我们可以随便拖动它,或者把它丢进垃圾箱,观察一下日志输出。


--------------------------------------------------------------------------------

上半部分总结
上半部分主要完成了一个widget的原型,它没有任何业务功能,

但是已经是一个可以运行的骨架了。

在下半部分中我们为它添加血和肉,让它真正具备业务功能。

希望大家喜欢这种先写骨架,再逐步丰富的开发方式

下半部分已出炉 android widget 开发实例 : 桌面便签程序的实现详解和源码 (下)

地址是:http://blog.csdn.net/silenceburn/archive/2010/12/23/6094705.aspx



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/silenceburn/archive/2010/12/23/6093074.aspx
分享到:
评论

相关推荐

    Widget

    Widget

    widget 介绍:比较全面介绍widget由来的资料

    比较全面介绍widget由来的资料 Widget是一种小插件,通常以小窗或小框的形式出现在网页、系统桌面、手机等地方。Widget通常使用的是HTML、Javascript、Flash或者iframe方式嵌入。一个界面可以有多个widget,通过不同...

    比较全面介绍widget由来的资料

    Widget是一种小插件,通常以小窗或小框的形式出现在网页、系统桌面、手机等地方。Widget通常使用的是HTML、Javascript、Flash或者iframe方式嵌入。一个界面可以有多个widget,通过不同的widget可以在一个界面上分别...

    Android之AppWidget(桌面小部件)开发浅析

    什么是AppWidget AppWidget 即桌面小部件,也叫桌面控件,就是能直接显示在Android系统桌面上的小程序,先看图:   图中我用黄色箭头指示的即为AppWidget,一些用户使用比较频繁的程序,可以做成AppWidget,这样能...

    Flutter中获取屏幕及Widget的宽高示例代码

    我们平时在开发中的过程中通常都会获取屏幕或者 widget 的宽高用来做一些事情,在 Flutter 中,我们有两种方法来获取 widget 的宽高。 MediaQuery 一般情况下,我们会使用如下方式去获取 widget 的宽高: final ...

    andriod的一个桌面Widget 一个MP3播放器

    这是一个MP3程序,这个程序不仅仅带Activity,还有一个桌面Widget,同时是可以运行的源代码。可以通过桌面Widget控制后台音乐的播放,也可以点击Widget上面的LOGO进入应用程序。 涉及到了,一个基本的widget程序的大...

    基于Android的Widget开发

    本文主要介绍了桌面动态图库APP Widget设计过程。在设计之前,首先根据UI设计的原则,给出了合理的需求分析,确定了软件要实现的功能要求。然后根据功能要求,阐述了Widget的框架设计,包括桌面布局设计、实现Widget...

    SP Widget 软件使用手册

    SP Widget 软件使用手册 SP Widget 将提供 SILICON POWER 存储装置更多实用的软件功能,帮助您随时 能轻易地执行个人数据的备份加密。 有了 SP Widget,您将可使用 SILICON POWER 移动存储装置执行如下工作: 「我...

    Widget介绍.rar

    Widget由来、发展、用途、示例、开发 Widget是一种小插件,通常以小窗或小框的形式出现在网页、系统桌面、手机等地方。Widget通常使用的是HTML、Javascript、Flash或者iframe方式嵌入。一个界面可以有多个widget,...

    appWidget启动Activity

    使用appWidget启动一个Activity

    WordPress对侧栏widget进行缓存的插件

    众所周知WP-Cache和WP Super Cache这两款页面缓存插件可以加速网页的显示,今天介绍一款插件,可以缓存WP边栏(SideBar),同样起到加速页面显示的作用,wp widget cache这款插件就是对侧栏的widget进行缓存,提高侧栏...

    Picture Frame Widget 实例源码

    1,这个例子演示了怎么创建一个widget(有config的情况)。 2,主要功能有: 1)能从SDCard中找到图片或视频(media)。 2)能选择一张图片并截取其中一部分,截取的这部分将最终显示到widget上面。 3)点击widget能...

    做一个自己的Widget引擎-移动互联网hot

    微技,基于Web的小应用,可以脱离通常的web浏览器页面,... 由于Mobile Widget兼具C/S与B/S优点的特性,一经引起了第三方厂商和运营商的关注,即:打造一个跨手机平台的Widget Engine,把握又一个移动互联网应用入口。

    Android天气预报widget的设计与实现毕业论文

    第4章 天气预报WIDGET的设计 19 4.1 网络功能实现 19 4.1.1 标准Java接口 19 4.1.2 Apache接口 20 4.1.3 使用Java接口连接网络 23 4.2 XML解析的实现 23 4.3 制作WIDGET应用程序 27 4.3.1 源文件组织 29 4.3.2 类...

    Qt界面 获取widget位置大小并与其他widget切换位置大小

    点击按钮实现不同widget间切换位置大小

    android axure widget包

    自己从网上下载的PS做的axure的 widget ,发上来跟大家分享一下

    Qt StackWidget切换动画

    QStackedWidget切换widget时的动画

    webwidget_scroller_tab

    webwidget_scroller_tab,tab选项卡代码

    Qt5以上动态添加子widget

    qt5 动态添加子widget

    widget现状分析报告(移动widget)

    widget现状分析报告,分析当前widget的现状,并对运营商的widget提出建议

Global site tag (gtag.js) - Google Analytics