找不到微调旋转屏幕后, [英] Can't find spinner after rotating the screen

查看:131
本文介绍了找不到微调旋转屏幕后,的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用片段来获得与两个片段布局所以我的课扩展片段

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆