找不到微调旋转屏幕后, [英] Can't find spinner after rotating the screen
问题描述
我用片段
来获得与两个片段布局
所以我的课扩展片段
。
I'm using Fragments
to obtain a layout with two fragments
so my class extends Fragments
.
我在左侧加载列表视图
片段
键,右侧片段
我又修改列表视图
。在这里,我有一个微调
,我必须改变它的颜色。
I'm loading a listview
on the left fragment
and on the right fragment
I have another modified listview
. Here, i have a spinner
that I have to change it's color.
我有这个code:
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
}
在code以上工作正常的到我转动我的设备的屏幕。在这里,我发现了一个 NullPointerException异常
在((TextView中)parent.getChildAt(0))。setTextColor(getResources()的getColor(R。 color.black));
The code above is working as expected UNTIL I rotate the screen of my device. Here, I'm getting a nullpointerexception
at ((TextView) parent.getChildAt(0)).setTextColor(getResources().getColor(R.color.black));
.
如果我评论上面的行,因为我保存状态旋转屏幕前,当我旋转屏幕,我的数据恢复,所有的作品如预期的除了的微调是对因此光的颜色是很差可见。
If I comment the above line, since i'm saving the state before rotating the screen, after I rotate the screen, my data is restored and all works as expected EXCEPT the spinner that is on light color thus being poorly visible.
我知道我可以创建自己的微调
布局和解决这个问题,但我想知道我怎么能解决这个问题。
I understand that I can create my own spinner
layout and solve this matter but I would like to know how can I solve this.
推荐答案
屏幕旋转后,你的微调
查看未装孩子的意见,但(你可以通过调用验证它 parent.getChildCount()
),因此你的 parent.getChildAt(0)
返回null,从而导致 NPE
。
After screen rotation, your Spinner
view has no children views attached yet (you can verify it by calling parent.getChildCount()
), thus your parent.getChildAt(0)
returns null, resulting in NPE
.
活动创建后,机器人通过调用显示其含量 onMeasure()
然后按 onLayout()
每个视图在布局层次结构。
After activity creation, Android displays its content by calling onMeasure()
followed by onLayout()
for each view in the layout hierarchy.
微调
将其子视图创建,其中填充适配器的数据和通话过程中附着 onLayout()
,你可以<一href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/1.5_r4/android/widget/Spinner.java#138">see这里。
Spinner
will have its children views created, populated with data from adapter, and attached during call to onLayout()
, as you can see here.
所以,通常你的微调,你将有序列: onMeasure
- > onLayout
- > onItemSelected
既然 onLayout
在 onItemSelected
被称为 - 在最初的活动启动一切工作正常,你
So, normally for your Spinner you will have sequence : onMeasure
-> onLayout
-> onItemSelected
and since onLayout
is called before onItemSelected
- everything works fine for you during initial activity startup.
现在,让我们看看会发生什么,当你旋转屏幕:的
在活动中销毁了 onSavedInstanceState
被称为宣扬调用微调
的 onSavedInstanceState
,将保存当前选择的位置。
Before Activity is destroyed its onSavedInstanceState
gets called which propagates the call to Spinner
's onSavedInstanceState
that will save current selected position.
旋转之后,你的活动是重新创建,然后它的 onRestoreInstanceState
之称。
After rotation, your activity is re-created and then its onRestoreInstanceState
is called.
在活动# onRestoreInstanceState
被称为最终会调用到微调的<一个href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/1.5_r4/android/widget/AbsSpinner.java#439">onRestoreInstanceState,它具有以下code:
when Activity#onRestoreInstanceState
is called it will eventually call to Spinner's onRestoreInstanceState, which has the following code :
SavedState ss = (SavedState) state;
//...some code
if (ss.selectedId >= 0) {
mDataChanged = true;
//...some more code
}
正如你所看到的,它总是会设置mDataChanged标志,如果微调的previous状态已保存<一个href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/1.5_r4/android/widget/AbsSpinner.java#426">onSavedInstanceState.
然后,<一个href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/1.5_r4/android/widget/AbsSpinner.java#170">onMeasure()被调用,它有下面这段code:
Then, onMeasure() is called, which has the following piece of code :
if (mDataChanged) {
handleDataChanged();
}
的<一个实施href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/1.5_r4/android/widget/AdapterView.java#AdapterView.handleDataChanged%28%29">handleDataChanged()最终将调用<一href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/1.5_r4/android/widget/AdapterView.java#AdapterView.fireOnSelected%28%29">fireOnSelected(),引发微调的 onItemSelected
。
Implementation of handleDataChanged() will eventually call fireOnSelected(), triggering Spinner's onItemSelected
.
因此 onItemSelected
在 onMeasure
被调用,在 onLayout
。照片
而如上所述,微调
面前没有孩子的 onLayout
之称。
Thus onItemSelected
gets called during onMeasure
, before onLayout
.
And as explained above, Spinner
has no children before its onLayout
is called.
希望现在的问题是显而易见的。
Hope the problem is clear now.
要确认该行为,解决NPE,你可以简单地提供空的实施 onSavedInstanceState
/ onRestoreInstanceState
在你的活动(无需调用超实现):
To confirm that behaviour and resolve NPE you could simply provide empty implementation for onSavedInstanceState
/onRestoreInstanceState
in your activity (without call to super implementation) :
@Override
protected void onSaveInstanceState(Bundle outState) { /* do nothing */ }
这将prevent设置 mDataChanged
和 onMeasure
将不会触发 fireOnSelected
。
This would prevent setting mDataChanged
and onMeasure
will not trigger fireOnSelected
.
不调用活动超。
覆盖时实施 onSavedInstanceState
/ onRestoreInstanceState
是绝对不推荐,因为你至少不能自动保存您的内部视图的状态(包括您的微调)。
我鼓励你只能做到这一点,以验证上述的行为解释,并看到 NPE
走了。
Not calling Activity super.
implementation when overriding onSavedInstanceState
/onRestoreInstanceState
is definitely not recommended, as a minimum you will not be able to automatically save states of your internal views (including your spinner).
I encourage you to only do that to verify the behavior explained above and to see that NPE
is gone.
在preferable解决方案是定义的TextView
与所需的颜色为你飞旋项目的的.xml布局,并用它来构建 ArrayAdapter
的微调。
The preferable solution is to define TextView
with desired color for you spinner item in a .xml layout and use it for constructing ArrayAdapter
for the spinner.
这篇关于找不到微调旋转屏幕后,的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!