gpt4 book ai didi

android - 旋转屏幕后找不到微调器

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:15:16 24 4
gpt4 key购买 nike

我正在使用“fragment ”来获得包含两个“fragment ”的布局,因此我的类扩展了“fragment ”。

我在左边的“fragment ”上加载了一个“ListView”,在右边的“fragment ”上我有另一个修改过的“ListView”。在这里,我有一个“微调器”,我必须更改它的颜色。

我有这个代码:

private void loadSpinner(int value) {
//Not relevant code

adapter = new ArrayAdapter<CharSequence>(getActivity().getApplicationContext(), android.R.layout.simple_spinner_item, data);

adapter.setDropDownViewResource(R.layout.spinner);

spinner.setAdapter(adapter);
}

@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String value = parent.getItemAtPosition(position).toString();

((TextView) parent.getChildAt(0)).setTextColor(getResources().getColor(R.color.black));

//Some code
}

上面的代码按预期工作 UNTIL 我旋转了设备的屏幕。在这里,我在 ((TextView) parent.getChildAt(0)).setTextColor(getResources().getColor(R.color.black)); 处得到了一个nullpointerexception >.

如果我评论上面的行,因为我在旋转屏幕之前保存状态,在我旋转屏幕之后,我的数据被恢复并且所有工作都按预期进行除了打开的微调器颜色较浅,因此很难看清。

我知道我可以创建自己的“微调器”布局并解决这个问题,但我想知道如何解决这个问题。

最佳答案

屏幕旋转后,您的 Spinner View 还没有附加 subview (您可以通过调用 parent.getChildCount() 来验证),因此您的 parent .getChildAt(0) 返回 null,导致 NPE

说明

Activity 创建后,Android 通过调用 onMeasure() 然后为布局层次结构中的每个 View 调用 onLayout() 来显示其内容。

Spinner 将创建其 subview ,用来自适配器的数据填充,并在调用 onLayout() 期间附加,如您所愿 see here .

因此,通常对于您的 Spinner,您将具有顺序:onMeasure -> onLayout -> onItemSelected
由于 onLayoutonItemSelected 之前被调用 - 在初始 Activity 启动期间一切正常。

现在,让我们看看旋转屏幕时会发生什么:

在 Activity 被销毁之前,它的 onSavedInstanceState 被调用,它将调用传播到 SpinneronSavedInstanceState ,它将保存当前选定的位置。

旋转后,您的 Activity 会重新创建,然后调用其 onRestoreInstanceState

当调用 Activity#onRestoreInstanceState 时,它最终会调用 Spinner 的 onRestoreInstanceState。 ,其中包含以下代码:

    SavedState ss = (SavedState) state;
//...some code
if (ss.selectedId >= 0) {
mDataChanged = true;
//...some more code
}

如您所见,如果微调器的先前状态是用 onSavedInstanceState 保存的,它将始终设置 mDataChanged 标志.

然后,onMeasure()被调用,它有以下代码:

    if (mDataChanged) {
handleDataChanged();
}

实现handleDataChanged () 最终会调用 fireOnSelected (), 触发 Spinner 的 onItemSelected

因此 onItemSelectedonMeasure 期间被调用,在 onLayout 之前被调用。
如上所述,Spinner 在其 onLayout 被调用之前没有子项。

希望问题现在已经清楚了。

解决方法

要确认该行为并解决 NPE,您只需在 Activity 中为 onSavedInstanceState/onRestoreInstanceState 提供空实现(无需调用 super 实现):

@Override 
protected void onSaveInstanceState(Bundle outState) { /* do nothing */ }

这会阻止设置 mDataChanged 并且 onMeasure 不会触发 fireOnSelected

额外说明

绝对不建议在重写onSavedInstanceState/onRestoreInstanceState 时不调用 Activity super. 实现,至少你将无法自动保存内部 View (包括微调器)的状态。
我鼓励您这样做只是为了验证上面解释的行为并查看 NPE 是否消失。

更好的解决方案是为 .xml 布局中的微调项定义具有所需颜色的 TextView,并将其用于为微调器构建 ArrayAdapter

关于android - 旋转屏幕后找不到微调器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20830606/

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