应用小挂件(也叫做窗口小挂件)在android1.5的时候被第一次引出,后来再android3.0和android3.1中得到了极大的发展,他们可以展示一些应用的常用信息或者一些相关的信息到桌面上,标准的Android系统镜像中有很多自带的创口小挂件,例如:闹钟、音乐等

Figure 1. Example app widgets in Android 4.0.

本文将描述怎么去设计小挂件,以便于能很好的与其他挂件搭配的很默契,同时也会介绍一些小技巧。

AppWidget 剖析

一个典型的android挂件将会包含三个组件部分:一个边界框、一个挂件图形控件、其他的元素。挂件包含了一部分安卓 View 控件的子集,他支持:textlabel、button、image。其他可用的组件见API Guide部分的Creating the app widget layout(见左侧)

一个设计很好的挂件将会在边界框、框架之间留出一些外部边界,在内部的边界框中会留出一些内部边界。(也就是留出一些padding与margin)。如下图所示:

Figure 2. Widgets generally have margins between the bounding box and frame,and padding between the frame and widget control

Note:

在android4.0中,挂件将自动的与边框之间将上margin。

为你的挂件决定大小

每一个挂件都必须指定minWidth 和 minHeight他表示默认最少需要多少的空间展示。当用户添加挂件到他的主屏幕时,通常占用的空间会大于你给的这两个值。Android的主屏幕提供给用户一种方格子的可用空间来放置应用图标或者桌面挂件。这种矩阵方格子在不同的设备上有不同的格式。比如说:一般手持设备提供4 X 4的格子。但是平板设备可以通过8 X 7的格子。当你的挂件被添加的时候,他将会根据minWidth和minHeight指定的宽高自动拉伸去占据最少的格子。使用.9.png图片作为背景和使用可伸展的布局可使你的挂件布局能很好的适配设备的主屏幕格子,以达到很好的使用体验。

你设置的宽度、高度,或者说margin宽度都会有可能运行到不同的设备上,你可以使用下面列出的每个小格子占据的空间的数据来大致的估算你的挂件的最小尺寸。

最佳实践是将你的minWidth与minHeight设置相对保守,定义最小尺寸是可以使你的挂件渲染出很好的默认状态。

比如说:假设你有个音乐播放器的挂件,他用作显示当前正在播放的专辑以及名字,我们就只需要一个播放按钮、一个下一曲按钮。

Figure 3.An example music player widget.

你最小的高度就应该为你的两个文本控件的高度+文本之间的margin高度和padding高度。你的最小宽度就应该为播放按钮最短宽度+ 下一曲按钮的最短宽度 + 文本的最短宽度(比如说最长10个字符)+水平的一些margin和padding距离

Figure4. Example sizes and margins for minWidth/minHeight calculations.We chose 144dp as an example good minimum width for the text labels.

最后的结果如下:

minWidth = 144dp + (2 × 8dp) + (2 × 56dp) = 272dp

minHeight = 48dp + (2 × 4dp) = 56dp

如果你使用的.9.png图片与内容有固有的padding距离,你也需要加上.

可调节大小的挂件

在android 3.1以后,挂件在水平方向与竖直方向都可以被调节大小,意味着:minWidth和minHeight的值将变成挂件默认大小的值,你可以使用minResizeWidth和minResizeHeight来表示挂件真正的最小值,小于这个值时,控件将变得模糊和不可用。

特别是那些基于ListView或者GridView的集合类特征的挂件

为你的挂件添加margin(外边界宽度)

正如前面提到的,android4.0将可以为主屏幕的挂件自动添加小号、标准的外边界宽度(margin)。对于那些系统版本号在14或者以上的来说,为了平衡主屏幕的视觉,我们不推荐你再额外的添加margin到你的挂件外部。

当然,对于那个更早一些的版本,添加自己的margin也不复杂,具体在API Guide中有介绍到。

设计挂件的布局和背景图片

很多挂件都只有一个固定的矩形背景或者圆角矩形的形状。其实最好的方法是使用.9.png图片来定义。(具体怎么使用.9.png图片,很简单这里不翻译了,自己去找资料学习)

对于挂件的内容部分,你应该使用可伸缩的布局方式。例如:RelativeLayout、LinearLayout、或者FrameLayout。这样可以让你的布局文件去适应很多种不同的屏幕尺寸。

下面是一个关于音乐播放的挂件的布局例子。他包含了一个文本域、一个暂停按钮、一个、下一曲按钮,他的margin取决于系统。

android:layout_width="match_parent"

android:layout_height="match_parent"

android:padding="@dimen/widget_margin">

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="horizontal"

android:background="@drawable/my_widget_background">

android:id="@+id/song_info"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1" />

android:id="@+id/play_button"

android:layout_width="@dimen/my_button_width"

android:layout_height="match_parent" />

android:id="@+id/skip_button"

android:layout_width="@dimen/my_button_width"

android:layout_height="match_parent" />

如果你看了上面的例子和说明,你也可以开始做一个有弹性的布局

Figure 6. Excerpt flexible layouts and attributes.

使用挂件模板包

当你要开始设计一个新的挂件或者更新现有的挂件,你可以先看一下下面的设计模板。下面的包是可以下载的,他包含了.9.png背景图片和XML和一些针对不同像素密度的PS文件

下面是一个实例源代码

/*

* Copyright (C) 2009 The Android Open Source Project

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

package com.example.android.wiktionary;

import com.example.android.wiktionary.SimpleWikiHelper.ApiException;

import com.example.android.wiktionary.SimpleWikiHelper.ParseException;

import android.app.PendingIntent;

import android.app.Service;

import android.appwidget.AppWidgetManager;

import android.appwidget.AppWidgetProvider;

import android.content.ComponentName;

import android.content.Context;

import android.content.Intent;

import android.content.res.Resources;

import android.net.Uri;

import android.os.IBinder;

import android.text.format.Time;

import android.util.Log;

import android.widget.RemoteViews;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

/**

* Define a simple widget that shows the Wiktionary "Word of the day." To build

* an update we spawn a background {@link Service} to perform the API queries.

*/

public class WordWidget extends AppWidgetProvider {

/**

* Regular expression that splits "Word of the day" entry into word

* name, word type, and the first description bullet point.

*/

public static final String WOTD_PATTERN =

"(?s)\\{\\{wotd\\|(.+?)\\|(.+?)\\|([^#\\|]+).*?\\}\\}";

@Override

public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

Log.d("WordWidget.UpdateService", "onUpdate()");

// To prevent any ANR timeouts, we perform the update in a service

context.startService(new Intent(context, UpdateService.class));

}

public static class UpdateService extends Service {

@Override

public void onStart(Intent intent, int startId) {

Log.d("WordWidget.UpdateService", "onStart()");

// Build the widget update for today

RemoteViews updateViews = buildUpdate(this);

Log.d("WordWidget.UpdateService", "update built");

// Push update for this widget to the home screen

ComponentName thisWidget = new ComponentName(this, WordWidget.class);

AppWidgetManager manager = AppWidgetManager.getInstance(this);

manager.updateAppWidget(thisWidget, updateViews);

Log.d("WordWidget.UpdateService", "widget updated");

}

@Override

public IBinder onBind(Intent intent) {

return null;

}

/**

* Build a widget update to show the current Wiktionary

* "Word of the day." Will block until the online API returns.

*/

public RemoteViews buildUpdate(Context context) {

// Pick out month names from resources

Resources res = context.getResources();

String[] monthNames = res.getStringArray(R.array.month_names);

// Find current month and day

Time today = new Time();

today.setToNow();

// Build the page title for today, such as "March 21"

String pageName = res.getString(R.string.template_wotd_title,

monthNames[today.month], today.monthDay);

String pageContent = null;

try {

// Try querying the Wiktionary API for today's word

SimpleWikiHelper.prepareUserAgent(context);

pageContent = SimpleWikiHelper.getPageContent(pageName, false);

} catch (ApiException e) {

Log.e("WordWidget", "Couldn't contact API", e);

} catch (ParseException e) {

Log.e("WordWidget", "Couldn't parse API response", e);

}

RemoteViews views = null;

Matcher matcher = null;

Prefs prefs = new Prefs(this);

if (pageContent == null) {

// could not get content, use cache

// could be null

pageContent = prefs.getPageContent();

}

if (pageContent != null) {

// we have page content

// is it valid?

matcher = Pattern.compile(WOTD_PATTERN).matcher(pageContent);

}

if (matcher != null && matcher.find()) {

// valid content, cache it

// ensure that latest valid content is

// always cached in case of failures

prefs.setPageContent(pageContent);

// Build an update that holds the updated widget contents

views = new RemoteViews(context.getPackageName(), R.layout.widget_word);

String wordTitle = matcher.group(1);

views.setTextViewText(R.id.word_title, wordTitle);

views.setTextViewText(R.id.word_type, matcher.group(2));

views.setTextViewText(R.id.definition, matcher.group(3).trim());

// When user clicks on widget, launch to Wiktionary definition page

String definePage = String.format("%s://%s/%s", ExtendedWikiHelper.WIKI_AUTHORITY,

ExtendedWikiHelper.WIKI_LOOKUP_HOST, wordTitle);

Intent defineIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(definePage));

PendingIntent pendingIntent = PendingIntent.getActivity(context,

0 /* no requestCode */, defineIntent, 0 /* no flags */);

views.setOnClickPendingIntent(R.id.widget, pendingIntent);

} else {

// Didn't find word of day, so show error message

views = new RemoteViews(context.getPackageName(), R.layout.widget_message);

views.setTextViewText(R.id.message, context.getString(R.string.widget_error));

}

return views;

}

}

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

android窗口小挂件,Android小挂件(APP Widgets)设计指导相关推荐

  1. 计算机课app开发,毕业设计(论文)-基于Android的《计算机网络基础》课程App的设计与开发.doc...

    Hebei Normal University of Science & Technology专业: Hebei Normal University of Science & Tech ...

  2. Android期末项目:美食点餐APP的设计与实现

    目录 1 项目基本信息 1.1 项目名称 1.2 开发运行环境 1.3 使用的核心类及组件 2 项目需求分析 2.1 APP管理员 2.2 APP用户 3 项目开发过程 3.1 APP功能模块 3.2 ...

  3. android窗口速度条,android 改变ViewPager切换页面时的速度

    声明:引自http://zhidao.baidu.com/link?url=9YCi4uGUki-xgV6d8_ZN5N1Jq9-eRw4efaiwvC6_aehw62IoskmrrS1ew1Cm11 ...

  4. android窗口动画体系,Android 7.1 GUI系统-窗口管理WMS-动画的执行(七)

    前面只是动画资源的加载过程,下面看下动画是怎么执行起来的? 前面在分析窗口申请的过程中,分析过relayoutWindow中的调用performSurfacePlacement,在这个函数的最后调用了 ...

  5. [内附完整源码和文档] 基于Android的移动手机端五子棋游戏APP的设计与实现

    一.项目概述 近年来,随着安卓手机的普及,安卓游戏成为广大用户关注的方向.五子棋作为一个棋类竞技运动,在民间十分流行,为了熟悉五子棋规则及技巧,以及研究简单的人工智能,决定用Java开发五子棋游戏,主 ...

  6. 【android开发】桌面小挂件( APP Widgets )

    APP小挂件指的是一个小型的应用View控件,他可以嵌入到其他应用程序中(比如说桌面),并接受定期的更新.你可以通过Widget Provider来自己发布一个.一个可以持有其他App小挂件的应用组件 ...

  7. Android -窗口小部件开发(App Widgets) 3部分

    原文地址:http://blog.csdn.net/iefreer/article/details/4626274. (一) 应用程序窗口小部件App Widgets 应用程序窗口小部件(Widget ...

  8. Android开发之APP打开小程序后小程序无法返回APP,无法打开APP,launchApp无法返回app的原因

    Android打开小程序可以看我上篇文章介绍:Android打开小程序 我这边已经成功打开小程序了参数也传递过去了,现在就是无论如何点击返回APP都没有反应,也没用走微信页面WXEntryActivi ...

  9. android微信风格,Android开发实现模仿微信小窗口功能【Dialog对话框风格窗口】

    本文实例讲述了Android开发实现模仿微信小窗口功能.分享给大家供大家参考,具体如下: 运用方法: 将显示窗口的风格 设置为对话框风格即可 具体效果: 具体实现: 首先我们先定义布局文件: andr ...

最新文章

  1. cygwin中 unable get setup.ini from... 的错误问题
  2. 后端:Spring IOC 知识点总结,写得太好了!
  3. 【APICloud系列|28】 UIChatBox 模块(聊天输入框)的实现
  4. css —— 图片环绕+首行缩进
  5. 手机上python编程工具3和3h有区别吗_Python 高级 3
  6. python的基本语术_一起学python-彻底掌握专业术语“变量”的概念
  7. 《『若水新闻』客户端开发教程》——04.设计新闻分类UI(2)
  8. 第18章 检测点模型
  9. dell-inspiron-5439 uefi 黑苹果_follow me 跟我一起学黑苹果原版安装
  10. 基于多时相Landsat影像的树种分类
  11. 如何在CAD中实现影像与矢量叠加套合(四参数法)
  12. 系统集成项目管理工程师计算题(进度管理总浮动时间、自由浮动时间、工期)
  13. 国内比较优秀的.net论坛源代码收集
  14. 项目管理的49个过程整理
  15. 圣诞来了 h5游戏风靡朋友圈了
  16. 《统计学基于R》第一章 数据与R
  17. 计算机软件编程与嵌入式软件编程区别,简单看懂什么是单片机编程与嵌入式系统...
  18. EduCoder-Web程序设计基础 -web编程训练-html5-文档头部-第2关:元信息的设置
  19. phase portrait 如果爱情像数学一样
  20. vue 项目中实现pdf预览 pdf打印 pdf下载

热门文章

  1. Python的raise用法
  2. Restful API use in Laravel
  3. mysql初始化root密码_MySQL初始化root密码的正确操作流程
  4. 设计模式学习笔记(四)封装、继承、多态、抽象能解决什么问题?
  5. 为什么不用python做大数据_光环大数据告诉你为什么说:人生苦短,我用Python
  6. Python实现关联规则推荐
  7. python马尔可夫链_用Python实现马尔可夫链蒙特卡罗
  8. mysql srid_如何修改Postgresql中空间字段的SRID
  9. 烙铁头氧化,不粘锡,变黑
  10. mysql 1261 load data_mysql load data 导入数据