gpt4 book ai didi

Android Widget 在方向改变时被破坏

转载 作者:行者123 更新时间:2023-11-29 16:02:15 25 4
gpt4 key购买 nike

应用程序的快速说明。这是一个简单的小部件,其中 4 个值通过 SharedPreferences 保存。唯一的 Activity View 是设置首选项的地方。完成后,将保存变量,并更新小部件。小部件每 90,000 毫秒自行更新一次。这一切都很好。我遇到的问题是方向改变时。当发生这种情况时,小部件将被销毁,然后重新制作。我得到的是原始 XML,其中变量文本字段设置为默认值。它会保持这种状态,直到下一次手动或自动更新。

编辑:这个问题现在有了很大的改变。我得到的两个回复指出了一些错误的地方。阅读所有评论以了解所有这些。在最后一次尝试在 list 中植入标签之后,我得到了更糟糕的结果。该程序根本无法运行。

我将使用提供该想法的同一答案中的最后一句话。我的 onUpdate() 一定有问题。这是整个类的代码:

public class WatchWidget extends AppWidgetProvider
{

public void onCreate(Context context, Bundle savedInstanceState)
{

RemoteViews remoteViews;
remoteViews = new RemoteViews( context.getPackageName(), R.layout.main );
remoteViews.setTextViewText( R.id.widget_elapsedtime, "Time");

}

@Override
public void onUpdate( Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
{
super.onUpdate(context, appWidgetManager, appWidgetIds);
RemoteViews remoteViews;
ComponentName watchWidget;
DateFormat format = SimpleDateFormat.getTimeInstance( SimpleDateFormat.MEDIUM, Locale.getDefault() );

remoteViews = new RemoteViews( context.getPackageName(), R.layout.main );
watchWidget = new ComponentName( context, WatchWidget.class );
//remoteViews.setTextViewText( R.id.widget_textview, "" + format.format( new Date()));

//widget_date
Calendar c = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy");
String formattedDate = df.format(c.getTime());
//remoteViews.setTextViewText( R.id.widget_date, formattedDate);

SharedPreferences prefs = context.getSharedPreferences("qsPrefs", context.MODE_PRIVATE);
String sdayTextEdit = prefs.getString("dayTextEdit", "23");
//String sdayTextEdit ="23";
String smonthTextEdit = prefs.getString("monthTextEdit", "3");
String syearTextEdit = prefs.getString("yearTextEdit", "2014");
String scostTextEdit = prefs.getString("costTextEdit", "8.5");
String spacksTextEdit = prefs.getString("packsTextEdit", ".95");


//Starting day
Calendar pastdate = Calendar.getInstance();
//int inputDay = 25;
int inputDay = Integer.valueOf(sdayTextEdit);
int inputMonth = 2; //starts at 0
inputMonth = Integer.valueOf(smonthTextEdit);
int inputMonthAdj = inputMonth-1;
int inputYear = 2014;
inputYear = Integer.valueOf(syearTextEdit);
pastdate.set(Calendar.DAY_OF_MONTH, inputDay);
pastdate.set(Calendar.MONTH, inputMonthAdj);
pastdate.set(Calendar.YEAR, inputYear);
double packsPer = .95;
packsPer = Double.parseDouble(spacksTextEdit.toString());
double perPack = 8.57;
perPack = Double.parseDouble(scostTextEdit.toString());

inputMonthAdj = inputMonth;
remoteViews.setTextViewText( R.id.widget_date, "From: " + inputMonthAdj +"/"+ inputDay +"/"+ inputYear );

SfinalDate = "From: " + inputMonthAdj +"/"+ inputDay +"/"+ inputYear;


Calendar today = Calendar.getInstance();
DecimalFormat dform = new DecimalFormat("0.00");

long dateDiff = today.getTimeInMillis() - pastdate.getTimeInMillis();

long resultDays = dateDiff / (24*60*60*1000);
remoteViews.setTextViewText( R.id.widget_elapsedtime, ""+ resultDays);

double savedmoney = packsPer * perPack * resultDays;
String finalMoney = dform.format(savedmoney);
remoteViews.setTextViewText( R.id.widget_savedmoney, "$"+ finalMoney);

double notSmoked = resultDays * 20 * packsPer;
int finalNotSmoked = (int) Math.round(notSmoked);
remoteViews.setTextViewText( R.id.widget_cigsnot, ""+ finalNotSmoked);

SfinalMoney = "$"+ finalMoney;
SfinalNS = ""+ finalNotSmoked;
SfinalDays = ""+ resultDays;

appWidgetManager.updateAppWidget( watchWidget, remoteViews );

//Show Prefs screen
Intent intent = new Intent(context, preferences.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.main);
views.setOnClickPendingIntent(R.id.LinearLayout01, pendingIntent);
appWidgetManager.updateAppWidget( watchWidget, views );
}

}

已发布...可能有一些额外的行试图设置不再相关的内容。但是那里的代码是有效的。 onUpdate() 以自动间隔 (90000ms) 触发。启动以设置首选项的 Activity 也会在关闭时进行调用,这也可以很好地更新它。这就是让我相信整个虚空一定没问题的原因。但一定有什么地方不对劲。因为当屏幕方向改变时,onUpdate() 不会运行。而且,再次,根据第二个答案,它不应该无论如何,因为系统应该保留它自己的用户界面。但事实并非如此。

最佳答案

您尝试执行的操作适用于 Activity 但不适用于 BroadcastReceiver。 AppWidgetProvider 是一个 BroadcastReceiver,没有您试图覆盖的方法(onSaveInstanceState、onRestoreInstanceState)。如果您将@Override 注释添加到它告诉您的方法

The method xyz() of type YourWidgetProvider must override or implement a supertype method

那是因为 AppWidgetProvider 类没有 onSaveInstanceState 或 onRestoreInstanceState 方法,您无法覆盖不存在的方法。只需删除 @Override 注释即可消除编译错误,但您只需添加一个从未调用的方法(当然除非您自己执行,但那毫无意义)。

解决此问题的方法是监听应用程序中的配置更改并向小部件广播 ACTION_APPWIDGET_UPDATE。

向您的应用添加应用程序类

public class MyApplication extends Application {

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);

// create intent to update all instances of the widget
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, MyWidgetProvider.class);

// retrieve all appWidgetIds for the widget & put it into the Intent
AppWidgetManager appWidgetMgr = AppWidgetManager.getInstance(this);
ComponentName cm = new ComponentName(this, MyWidgetProvider.class);
int[] appWidgetIds = appWidgetMgr.getAppWidgetIds(cm);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);

// update the widget
sendBroadcast(intent);
}
}

只要发生配置更改,就会调用该方法,其中之一是方向更改。您可以通过仅在方向改变时进行广播来改进方法,而不是例如系统语言的改变。该方法基本上向您的小部件的所有实例发送更新广播(用您为小部件提供程序使用的任何名称替换 MyWidgetProvider)。

在 list 中定义 MyApplication

<application
android:name="yourpackagename.MyApplication"
android:description="@string/app_name"
android:label="@string/app_name"
android:icon="@drawable/app_icon">

<!-- here go your Activity definitions -->

</application>

重要只有在横向和纵向使用不同布局时才需要这样做。否则没有必要,因为 Android 负责保存和恢复小部件的 ui 状态。如果你得到一个带有默认值的小部件,那么你在 onUpdate 方法中做错了。现在我查看了您的 onUpdate 方法,发现有一个主要问题(还有其他问题,但我只会指出肯定会破坏您的小部件的那个)。

在使用初始化的 TextView 调用 updateAppWidget 之后创建新的 RemoteView:

appWidgetManager.updateAppWidget( watchWidget, remoteViews );

//Show Prefs screen
Intent intent = new Intent(context, preferences.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

// this line gets rid of all the work you have done above
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.main);

views.setOnClickPendingIntent(R.id.LinearLayout01, pendingIntent);
appWidgetManager.updateAppWidget( watchWidget, views );

因此,在创建 View 并设置值之后,您将其全部丢弃并创建新的 RemoteView,其中显然具有空的/未初始化的 TextView。也没有必要调用 appWidgetManager.updateAppWidget 两次,每次 onUpdate 调用一次就足够了。所以你要做的是:

remoteViews.setTextViewText( R.id.widget_cigsnot, ""+ finalNotSmoked);

SfinalMoney = "$"+ finalMoney;
SfinalNS = ""+ finalNotSmoked;
SfinalDays = ""+ resultDays;

//Show Prefs screen
Intent intent = new Intent(context, preferences.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
remoteViews.setOnClickPendingIntent(R.id.LinearLayout01, pendingIntent);
appWidgetManager.updateAppWidget( appWidgetIds, remoteViews );

请注意,我使用的是 updateAppWidget(int[] appWidgetIds, RemoteViews views) 而不是 updateAppWidget(ComponentName provider, RemoteViews views) 因为它允许您只更新某些小部件实例并且您不需要保存的 ComponentName你的另一行代码。

关于Android Widget 在方向改变时被破坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23198473/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com