代码之家  ›  专栏  ›  技术社区  ›  dfilkovi

小部件上的方向更改按钮没有响应后

  •  11
  • dfilkovi  · 技术社区  · 16 年前

    我在一个小部件上有两个按钮可以改变小部件中的某些项目,如果在电话上改变了方向,按钮什么也不做。我读 http://developer.android.com/guide/topics/resources/runtime-changes.html 但这都是关于活动,而不是小部件。

        @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) 
    {
        RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
    
        Intent active = new Intent(context, TvWidget.class);
        active.setAction(ACTION_WIDGET_RECEIVER);
        mDbHelper = new DbAdapter(context);
        fillChannelList(context, appWidgetIds[appWidgetIds.length-1]);
        Set<Integer> keys = channelsImages.keySet();
        Iterator<Integer> iter = keys.iterator();
        while(iter.hasNext())  
        {
            if(channelId == 0) 
            {
                channelId = iter.next();
                break;
            }
        }
        SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
        Editor edit = settings.edit();
        edit.putInt("channelId", channelId);
        edit.putInt("appWidgetIds", appWidgetIds[appWidgetIds.length-1]);
        edit.commit();
        active.putExtra("net.aerosoftware.tvvodic.appWidgetIds", appWidgetIds);
        PendingIntent actionPendingIntent = PendingIntent.getBroadcast(context, 0, active, 0);
        remoteViews.setOnClickPendingIntent(R.id.button_next, actionPendingIntent);
    
        Intent refresh = new Intent(context, TvWidget.class);
        refresh.setAction(ACTION_WIDGET_REFRESH);
        refresh.putExtra("net.aerosoftware.tvvodic.appWidgetIds", appWidgetIds);
        PendingIntent refreshPendingIntent = PendingIntent.getBroadcast(context, 0, refresh, 0);
        remoteViews.setOnClickPendingIntent(R.id.button_refresh, refreshPendingIntent);
    
        updateView(context);
        appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
        super.onUpdate(context, appWidgetManager, appWidgetIds);
    }
    
    4 回复  |  直到 9 年前
        1
  •  12
  •   jagsaund    16 年前

    我建议创建一个服务(可能在AppWidgetProvider中对此进行子类化),并重写onConfigurationChanged()方法。使用该服务将允许您将业务逻辑委托给该服务来处理、构建和更新小部件。它还允许您管理旋转。如果您正在执行任何阻塞操作,那么该服务将是生成线程并将结果返回到主UI线程以避免ANR的好地方。

    我建议如下:

    public class MyWidget extends AppWidgetProvider
    {
        @Override
        public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
        {
            context.startService(new Intent(context, MyUpdateService.class));
        }
    
        public static class MyUpdateService extends Service
        {
            @Override
            public void onStart(Intent intent, int startId)
            {
                super.onStart(intent, startId);
                // Update the widget
                RemoteView remoteView = buildRemoteView(this);
    
                // Push update to homescreen
                pushUpdate(remoteView);
    
                // No more updates so stop the service and free resources
                stopSelf();
            }
    
            public RemoteViews buildRemoteView(Context context)
            {
                RemoteView updateView = null;
    
                updateView = new RemoteViews(context.getPackageName(), R.layout.my_widget_layout);
                // Your code to build and update the remote view
    
    
                return updateView;
            }
    
            @Override
            public void onConfigurationChanged(Configuration newConfig)
            {
                int oldOrientation = this.getResources().getConfiguration().orientation;
    
                if(newConfig.orientation != oldOrientation)
                {
                    // Update the widget
                    RemoteView remoteView = buildRemoteView(this);
    
                    // Push update to homescreen
                    pushUpdate(remoteView);
                }
            }
    
            private void pushUpdate(RemoteView remoteView)
            {
                ComponentName myWidget = new ComponentName(this, MyWidget.class);
                AppWidgetManager manager = AppWidgetManager.getInstance(this);
                manager.updateAppWidget(myWidget, updateViews);
            }
        }
    }
    

    还可以查看此链接: http://android-developers.blogspot.com/2009/04/introducing-home-screen-widgets-and.html

    另外,一定要指出您有兴趣在清单中接收有关轮值更改的通知。类似这样的事情会奏效: android:configchanges=“键盘隐藏方向” 在您的服务声明中声明。

    希望有帮助!

        2
  •  2
  •   Tim Cooper    14 年前

    每当您更新小部件的外观(使用活动或广播接收器[应用程序小部件提供程序])时,您还必须为单击处理程序重新分配所有挂起的内容,然后调用 updateAppWidget() 正常情况下。

    实例与 setTextViewText() :

    // This will update the Widget, but cause it to
    // stop working after an orientation change.
    updateWidget()
    {
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
    remoteViews.setTextViewText(R.id.widget_text_view, "Updated widget");
    
    appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
    }
    
    
    // This is the correct way to update the Widget,
    // so that it works after orientation change.
    updateWidget()
    {
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
    remoteViews.setTextViewText(R.id.widget_text_view, "Updated widget");
    
    Intent intent = new Intent(context, MyWidgetActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, ...);
    remoteViews.setOnClickPendingIntent(R.id.widget_click_button, pendingIntent);
    
    appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
    }
    
        3
  •  0
  •   Jimmy    14 年前

    问题可能是因为小部件上有两个按钮,这会导致一些问题。请参见这里:

    http://permalink.gmane.org/gmane.comp.handhelds.android.devel/98008

    或

    http://groups.google.com/group/android-developers/browse_thread/thread/578a4429c369c27c/273a53a96ddd10c5?lnk=gst&q=Widget+does+not+respond+when+phone+orientation+changes#273a53a96ddd10c5

    但还不清楚真正的解决方案是什么(不需要创建后台服务的解决方案)。

        4
  •  0
  •   Aksiom    10 年前

    如果你使用

    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
    

    要更改远程视图对象内特定视图的某些状态,您还需要更改其他视图,因为方向更改事件将只记住用于更新小部件的最后一个远程视图对象。它将使用上次使用的远程视图对象重新创建小部件。这就是为什么您总是需要更新RemoteView对象内的所有视图,以及视图的所有侦听器的原因。

    其余的将由操作系统自动处理。