Ответ 1
Это помогло мне: Android-виджет ImageButton теряет изображение при повороте экрана
Короче, вам нужно зарегистрировать клики (views.setOnClickPendingIntent), прежде чем КАЖДЫЙ вызовите awm.updateAppWidget
У меня очень простое приложение виджета, состоящее из LinearLayout
с фоном и ImageButton
.
В методе AppWidgetProvider
onUpdate()
я регистрирую нажатие кнопки для трансляции намерения. Когда виджет сначала загружается, все работает нормально, и щелчок захватывается. Проблема возникает, когда экран поворачивается, и щелчок никогда не захватывается снова, даже если экран повернут назад.
Что мне нужно сделать, чтобы перерегистрировать клик, когда экран вращается?
ниже - некоторые сегменты кода, которые я использую.
AppWidgetProvider
@Override
public void onReceive(Context context, Intent intent)
{
super.onReceive(context, intent);
if(intent.getAction().equals("test.CLICK"))
{
CallTestMethod(context);
}
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
final int N = appWidgetIds.length;
// Perform this loop procedure for each App Widget that belongs to this provider
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
RemoteViews views=new RemoteViews(context.getPackageName(), R.layout.widget);
Intent clickintent=new Intent("test.CLICK");
PendingIntent pendingIntentClick=PendingIntent.getBroadcast(context, 0, clickintent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.change_mode, pendingIntentClick);
SetInitialLayout(context);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
манифеста
<receiver android:name=".Widget" android:label="@string/widget_name">
<intent-filter>
<action android:name="android.appwidget.action.ACTION_APPWIDGET_CONFIGURE" />
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="test.CLICK" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_mode_switcher" />
</receiver>
Разметка
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widget_layout"
android:layout_width="140dip"
android:layout_height="140dip"
android:scaleType="fitCenter"
android:orientation="vertical"
android:background="@drawable/background">
<ImageButton
android:id="@+id/change_mode"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitCenter"
android:orientation="vertical"
android:src="@drawable/none_selected"
android:background="@null"
android:clickable="true" />
</LinearLayout>
Спасибо вам за вашу помощь!
Это помогло мне: Android-виджет ImageButton теряет изображение при повороте экрана
Короче, вам нужно зарегистрировать клики (views.setOnClickPendingIntent), прежде чем КАЖДЫЙ вызовите awm.updateAppWidget
Я использовал решение, которое требует службы на widgetapp, потому что оно может обрабатывать изменения ориентации в widgetapp. К сожалению, onReceive или onUpdate не вызваны изменениями ориентации, но служба onConfigurationChanged вызывает вызов. Вам нужно постоянно работать с вашим сервисом для определения этих ориентаций. Когда служба обнаруживает изменение ориентации, вы переходите к изменению удаленного вида.
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
context.startService(new Intent(context, MyUpdateService.class));
}
Это класс обслуживания, который необходимо реализовать. Вы можете посмотреть это, если вам нужна дополнительная информация об услуге. http://android-developers.blogspot.com/2009/04/introducing-home-screen-widgets-and.html
public static class MyUpdateService extends Service
{
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
// Update the widget
RemoteViews remoteView = buildRemoteView(this);
// Push update to homescreen
pushUpdate(remoteView);
}
public RemoteViews buildRemoteView(Context context)
{
int layoutID = R.layout.widget;
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
layoutID = R.layout.widget_landscape;
}
//Here is where you set your onclick listeners again since the remote views need to be refreshed/recreated
RemoteViews updateView = new RemoteViews(context.getPackageName(),layoutID);
// Create an Intent to launch ExampleActivity
Intent intent = new Intent(this, yourAndroidActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
intent, 0);
updateView.setOnClickPendingIntent(R.id.yourClickableViewHere, pendingIntent);
return updateView;
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
RemoteViews remoteView = buildRemoteView(this);
// Push update to home screen
pushUpdate(remoteView);
}
private void pushUpdate(RemoteViews updateViews)
{
ComponentName myWidget = new ComponentName(this, YourAppWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
//This is where you can update your remoteViews
updateViews.setTextViewText(R.id.YOUR_TEXTVIEW_ON_WIDGET, "" + "TEXT THAT WILL SHOW UP");
manager.updateAppWidget(myWidget, updateViews);
}
}
}
Как я понимаю, Android на самом деле убивает и воссоздает вашу активность каждый раз, когда экран вращается. Yuck, я знаю.
Так или иначе, я подозреваю, что если вы поставили логические операторы во всех обратных вызовах жизненного цикла, вы обнаружите, что обновление вызывается только один раз. Вероятно, вам придется обрабатывать прослушивание кликов в другом обратном вызове. Я не мог сказать вам, какой из них не будет проверять какой-либо справочный материал. Я оставлю это как упражнение для читателя.
Сено вы используете
андроид: configChanges = "keyboardHidden | ориентация"
с вашей деятельностью в файле Androidmanifest.
Я новичок в android, но я уверен, что этот способ работы будет работать.
@Override
public void onReceive(Context context, Intent intent)
{
super.onReceive(context, intent);
if(intent.getAction().equals("test.CLICK"))
{
getIntent().putExtra("Just received click", true);
CallTestMethod(context);
}
}
Затем в onCreate вы можете увидеть, если он должен воссоздать событие click, проверив getIntent().getBooleanExtra("Just received click", false)
(false ссылается на значение по умолчанию. Если этот код возвращает true, то приведенный выше код сделал это задание, и вы должны воссоздать событие click )
Это должно работать, потому что объект намерения (и его дополнительные) сохраняется, даже если ваше приложение временно убито. Цель будет принимать любые дополнительные Serializable.