首页 文章

自定义呈现Android应用小部件

提问于
浏览
7

我正在为Android制作一个应用程序小部件,由于由图形等自定义元素组成,它必须呈现为位图 .

但是,我在这个过程中遇到了一些障碍 .

1) Is there any way to find the maximum available space for an app widget? (OR: Is it possible to calculate the dimensions correctly for the minimum space available in WVGA (or similar wide) cases?

我不知道如何计算app小部件的最大可用空间 . 使用传统的app小部件,可以使用fill_parent,并且将使用所有空间 . 但是,在将窗口小部件呈现为位图并避免拉伸时,必须计算正确的尺寸 . 文档概述了如何计算最小尺寸,但对于诸如WVGA之类的情况,横向模式中将存在未使用的空间 - 导致窗口小部件看起来比其他自然伸展的窗口小部件更短 .

float density = getResources().getDisplayMetrics().density;
int cx = ((int)Math.ceil(appWidgetInfo.minWidth / density) + 2) / 74;
int cy = ((int)Math.ceil(appWidgetInfo.minHeight / density) + 2) / 74;
int portraitWidth = (int)Math.round((80.0f * cx - 2.0f) * density);
int portraitHeight = (int)Math.round((100.0f * cy - 2.0f) * density);
int landscapeWidth = (int)Math.round((106.0f * cx - 2.0f) * density);
int landscapeHeight = (int)Math.round((74.0f * cy - 2.0f) * density);

计算cx和cy给出水平和垂直单元格的数量 . 从计算的dpi减去-2(例如74 * cy-2)是为了避免产生的像素数向下舍入的情况 . (例如,在Nexus One的横向模式下,高度为110,而不是111(74 * 1.5) .

2)将位图分配给ImageView(用作RemoteViews的一部分)以查看图像时,有两种方法:

2.1)通过使用setImageViewUri,并将位图保存为PNG文件 . 然后使用ContentProvider中的openFile()实现提供映像:

@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException
    // Code to set up imageFileName
    File file = new File(getContext().getCacheDir(), imageFileName);
    return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
}

这是有效的,这是我目前正在使用的方法 . 但是,如果我将ImageView的scaleType设置为“center”,文档应该将其设置为“在视图中居中,但不执行缩放”,则图像会被错误地缩放 . 将位图的密度设置为DENSITY_NONE或getResources() . getDisplayMetrics() . densityDpi在将位图保存到PNG时没有任何区别,当ImageView加载文件时似乎会忽略它 . 结果是由于某些dpi问题,图像缩小 . 这似乎描述了这种情况:

http://code.google.com/p/android/issues/detail?id=6957&can=1&q=widget%20size&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars

因为无法使用scaleType:center,所以我发现工作的唯一方法是将ImageView的layout_width和layout_height静态设置为给定的dpis数,然后将位图渲染为相同的dpi . 这需要使用scaleType:fitXY . 这种方法有效,但它是一个非常静态的设置 - 它不适用于可调整大小的3.1 app小部件(我还没有测试过,但除非在每次调整大小时都调用onUpdate(),否则这是真的) .

Is there any way to load an image to an ImageView unscaled, or is this impossible due to a bug in the framework?

2.1)直接使用setImageViewBitmap . 使用此方法和位图上的Bitmap.DENSITY_NONE设置,可以显示图像而无需正确缩放 . 这种方法的问题在于如何通过IPC机制设置大图像是有限的:

http://groups.google.com/group/android-developers/browse_thread/thread/e8d84920b999291f/d12eb1d0eaca93ac#01d5c89e5e7b4060

(不允许更多链接)http://groups.google.com/group/android-developers/browse_thread/thread/b11550601e6b1dd3#4bef4fa8908f7e6a

我试图通过将小部件分成可以在100x100像素块中设置的图像矩阵来试图解决这个问题 . 这确实允许更大的小部件工作,但最终变得非常沉重并且在大型小部件上失败(4x4) .

很抱歉很长的帖子 . 我试图在尝试使用位图呈现的应用小部件时解释一些不同的问题 . 如果有人尝试过相同的问题并找到了解决这些问题的更多解决方案,或者有任何有用的评论,我们将非常感激 .

1 回答

  • 0

    对我们来说类似情况的一种方法是将我们的图形生成为9补丁png,实际的图形部分作为可伸缩的中心矩形,以及 Headers 文本和指示图标(我们不希望所有图形都伸出来形状)和边框效果,放置在图像的外部矩形上 .

相关问题