使用ImageView的Android Widget是不可见的,直到我开始移动它

时间:2013-05-24 04:52:33

标签: java android widget

我有一个ImageView的小部件,其源代码我设置了用户设备上图像的URI。我在小部件提供程序的RemoteViews.setImageViewUri()中使用onUpdate进行了设置。最奇怪的事情正在发生:当小部件在我的主屏幕上静止时,我无法看到小部件或图像,但是当我拿起它并开始移动它时,图像就出现了!

以下是一些说明这一点的屏幕截图:

enter image description here enter image description here

这是小部件的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/picture_widget_parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="@dimen/widget_margin" >

    <ImageView
        android:id="@+id/the_picture"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:contentDescription="@string/image_content_description"
        android:scaleType="centerCrop" />

</RelativeLayout>

这是我的AppWidgetProvider:

public class WidgetProvider extends AppWidgetProvider {

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        super.onUpdate(context, appWidgetManager, appWidgetIds);

        updateAllWidgets(context, appWidgetManager, appWidgetIds);
    }

    private void updateAllWidgets(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        PuppyFramePersistenceManager persistenceManager = new PuppyFramePersistenceManager(context);

        for(int i = 0; i < appWidgetIds.length; i++) {
            int appWidgetId = appWidgetIds[i];

            RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.puppyframe_widget);
            Intent configIntent = new Intent(context, AlbumsActivity.class);

            Uri.withAppendedPath(Uri.parse("pw" + i + "://widget/id/"), String.valueOf(appWidgetId));
            configIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);

            PendingIntent configPendingIntent = PendingIntent.getActivity(context, 0, configIntent, 0);
            remoteViews.setOnClickPendingIntent(R.id.picture_widget_parent, configPendingIntent);

            String currentAlbumId = persistenceManager.getCurrentAlbumIdForAppWidgetId(appWidgetId);
            if(currentAlbumId != null) {
                Uri imageUri = Uri.parse(persistenceManager.getAlbumWithId(currentAlbumId).getImagePaths().get(0));
                remoteViews.setImageViewUri(R.id.the_picture, imageUri);
            }

            appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
        }
    }
}

这是我的AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.boztalay.puppyframe"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <activity android:name="com.boztalay.puppyframe.configuration.albums.AlbumsActivity" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
            </intent-filter>
        </activity>

        <activity android:name="com.boztalay.puppyframe.configuration.editalbum.EditAlbumActivity" />

        <receiver android:name="com.boztalay.puppyframe.widget.PuppyFrameWidgetProvider" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/puppyframe_info" />
        </receiver>

        <service android:name="com.boztalay.puppyframe.widget.ScreenOnService"></service>
    </application>

</manifest>

最后,这是我的小部件提供商信息:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="40dp"
    android:minHeight="40dp"
    android:minResizeWidth="40dp"
    android:minResizeHeight="40dp"
    android:updatePeriodMillis="21600000"
    android:initialLayout="@layout/puppyframe_widget"
    android:configure="com.boztalay.puppyframe.configuration.albums.AlbumsActivity"
    android:resizeMode="horizontal|vertical"
    android:widgetCategory="home_screen">
</appwidget-provider>

谢谢!

2 个答案:

答案 0 :(得分:1)

AppWidgetManagerAppWidgetProvider互动的方式并未记录在案。该文档声称,如果您有配置活动,则不会调用onUpdate

实际上,在配置活动开始之前调用onUpdate。活动结束时不会调用它。查看您的onUpdate,如果尚未配置appwidget,则会显示ImageView为空。即使没有看到你的配置活动,我想这是怎么回事:

  • AppWidgetManager创建新窗口小部件并调用onUpdate。由于尚未配置新窗口小部件,因此不要将ImageView设置为图像。
  • 配置活动会运行并设置RESULT_OK。现在已配置窗口小部件,但尚未再次更新,因此ImageView仍为空白。
  • 当您调整窗口小部件或移动窗口小部件时,AppWidgetManager会再次调用onUpdate。这次,您的代码会读取窗口小部件配置并设置ImageView。现在,小部件显示所选图像。

答案是,当您的配置活动完成后,它应该向您的AppWidgetProvider发送一个意图,让它再次更新。然而,这不是灵丹妙药,因为AppWidgetProvider中还有其他错误。例如,如果在配置活动运行时进行方向更改,重新启动它,AppWidgetProvider即使在完成并返回RESULT_OK后,也会从屏幕上隐藏appwidget。显示启动器时再次更改方向(在配置活动完成后)会使appwidget显示。

我之所以知道这一点的原因是我在撰写类似应用时遇到了同样的问题,如果你正在努力解决这个问题,这可能会对你有所帮助。 Showr 在主屏幕或锁定屏幕上显示图像。可以从设备上的其他应用程序(例如图库)中选择图像,从URL下载或从RSS或Atom订阅源更新图像。它甚至可以将图像缩放到合适的大小,并可以裁剪它们以适应appwidget。这是一个free download from Google Play

答案 1 :(得分:0)

问题最终与图像的大小有关。使用手机相机拍摄的非常大的图像会导致此错误。但随着手机上的小手机,他们看起来很好。我必须做的是实际调整大小并缓存太大的图像,我认为这是手机屏幕分辨率的75%。