切换方向后复选框全部显示相同的文本
编辑:查看已接受的答案。教训:有时视图会自动保存和恢复其状态。这发生在 onCreate 之后。这可能会导致您在 onCreate 中所做的事情被覆盖。如果您没有唯一的 ID,则可以使用相同的保存状态覆盖某种类型的所有视图(在我的例子中是文本框)。(ps:感谢大家的帮助!)
所以,我有一个简单的方法线性布局,我想添加一些带有图像复选框的视图。一切正常,直到我切换 Android 手机的方向。当我这样做时,它会返回到 onCreate,但这次复选框都以相同的文本结束。奇怪的是,图像看起来很好。
我的问题是:为什么要这样做?我怎样才能让它每次都像第一次一样?
如果这没有意义,这里有一个例子:(编辑:事实证明它总是显示最后一个元素的文本)
我首先看到的
[] a *a's image*
[] b *b's image*
[] c *c's image*
[] d *d's image*
然后,旋转我的手机后,它重新绘制
[] d *a's image*
[] d *b's image*
[] d *c's image*
[] d *d's image*
我的原始代码非常复杂,但我构建了以下内容这说明了问题所在。
Main.java:AnswerView.java
public class Main extends Activity {
ArrayList<AnswerView> answers = new ArrayList<AnswerView>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView title = (TextView)findViewById(R.id.questionText);
title.setText("This is a test");
HashMap<String, Drawable> answerInfo = new HashMap<String, Drawable>();
Resources res = getResources();
answerInfo.put("a", res.getDrawable(R.drawable.flower_orange));
answerInfo.put("b", res.getDrawable(R.drawable.flower_white));
answerInfo.put("c", res.getDrawable(R.drawable.leaf));
answerInfo.put("d", res.getDrawable(R.drawable.flower_yellow));
setBoxes(answerInfo);
}
private void setBoxes(HashMap<String, Drawable> answerInfo) {
LinearLayout answerList = (LinearLayout)findViewById(R.id.answerlist);
AnswerView cb = null;
//Remove all existing answer views
answerList.removeAllViews();
answers.clear();
//For each possible answer create a answer views
for (String s : answerInfo.keySet()) {
cb = new AnswerView(this, s, answerInfo.get(s));
answers.add(cb);
String text = cb.getText();
answerList.addView(cb);
}
}
}
image_checkbox.xml
public class AnswerView extends RelativeLayout {
private CheckBox m_checkbox;
private ImageView m_image;
//private Context m_context;
public AnswerView(Context context, String answer, Drawable d) {
super(context);
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.image_checkbox, this, true);
m_checkbox = (CheckBox) view.findViewById(R.id.image_checkbox_cb);
m_image = (ImageView) view.findViewById(R.id.image_checkbox_img);
//m_context = context;
m_checkbox.setText(answer);
m_image.setImageDrawable(d);
m_image.setVisibility(VISIBLE);
}
public void setChecked(boolean checked) {
m_checkbox.setChecked(checked);
}
public boolean isChecked() {
return m_checkbox.isChecked();
}
public String getText() {
return m_checkbox.getText().toString();
}
}
Main.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dip">
<TextView android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/questionText"
android:textSize="18sp"/>
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/answerlist"/>
<LinearLayout android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<Button
android:layout_width="200dip"
android:layout_height="wrap_content"
android:text="Enter"
android:id="@+id/buttonAnswerEnter"/>
/>
</LinearLayout>
</LinearLayout>
</ScrollView>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/image_checkbox_cb"></CheckBox>
<ImageView
android:id="@+id/image_checkbox_img"
android:layout_width="100dip"
android:layout_height="100dip"
android:visibility="gone"></ImageView>
</LinearLayout>
Edit: See the accepted answer. Lesson: Sometimes views will save and restore their state automatically. This happens AFTER onCreate. This can cause the overwriting of stuff you did in onCreate. If you don't have unique ids, all views of a certain kind (in my case textboxes) can be overwritten with the same saved state. (ps: thanks for your help everyone!)
So, I have a simple linear layout and I want to add some views that have checkboxes with images. Everything works fine until I switch the orientation of my android phone. When I do it goes back through the onCreate but this time the checkboxes all end up with the same text. Weirdly, the images appear fine.
My question is: why is it doing this and how can I make it appear like the first time everytime?
In case that makes no sense here's an example: (Edit: It turns out it always shows the last element's text)
What I see at first
[] a *a's image*
[] b *b's image*
[] c *c's image*
[] d *d's image*
Then, after rotating my phone, it redraws
[] d *a's image*
[] d *b's image*
[] d *c's image*
[] d *d's image*
My original code is pretty complex, but i constructed the following that demonstrates the problem.
Main.java:
public class Main extends Activity {
ArrayList<AnswerView> answers = new ArrayList<AnswerView>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView title = (TextView)findViewById(R.id.questionText);
title.setText("This is a test");
HashMap<String, Drawable> answerInfo = new HashMap<String, Drawable>();
Resources res = getResources();
answerInfo.put("a", res.getDrawable(R.drawable.flower_orange));
answerInfo.put("b", res.getDrawable(R.drawable.flower_white));
answerInfo.put("c", res.getDrawable(R.drawable.leaf));
answerInfo.put("d", res.getDrawable(R.drawable.flower_yellow));
setBoxes(answerInfo);
}
private void setBoxes(HashMap<String, Drawable> answerInfo) {
LinearLayout answerList = (LinearLayout)findViewById(R.id.answerlist);
AnswerView cb = null;
//Remove all existing answer views
answerList.removeAllViews();
answers.clear();
//For each possible answer create a answer views
for (String s : answerInfo.keySet()) {
cb = new AnswerView(this, s, answerInfo.get(s));
answers.add(cb);
String text = cb.getText();
answerList.addView(cb);
}
}
}
AnswerView.java
public class AnswerView extends RelativeLayout {
private CheckBox m_checkbox;
private ImageView m_image;
//private Context m_context;
public AnswerView(Context context, String answer, Drawable d) {
super(context);
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.image_checkbox, this, true);
m_checkbox = (CheckBox) view.findViewById(R.id.image_checkbox_cb);
m_image = (ImageView) view.findViewById(R.id.image_checkbox_img);
//m_context = context;
m_checkbox.setText(answer);
m_image.setImageDrawable(d);
m_image.setVisibility(VISIBLE);
}
public void setChecked(boolean checked) {
m_checkbox.setChecked(checked);
}
public boolean isChecked() {
return m_checkbox.isChecked();
}
public String getText() {
return m_checkbox.getText().toString();
}
}
Main.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dip">
<TextView android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/questionText"
android:textSize="18sp"/>
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/answerlist"/>
<LinearLayout android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<Button
android:layout_width="200dip"
android:layout_height="wrap_content"
android:text="Enter"
android:id="@+id/buttonAnswerEnter"/>
/>
</LinearLayout>
</LinearLayout>
</ScrollView>
image_checkbox.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/image_checkbox_cb"></CheckBox>
<ImageView
android:id="@+id/image_checkbox_img"
android:layout_width="100dip"
android:layout_height="100dip"
android:visibility="gone"></ImageView>
</LinearLayout>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为每个 AnswerView 设置唯一 ID 是否可以解决您的问题?您可以按如下方式实现:
Does setting a unique ID for each AnswerView solve your issue? You could achieve that as follows:
实现。
在您的自定义布局 AnswerView 中
Implement
in your custom layout AnswerView.
尽我所能,我无法找出为什么会发生这种情况的原因(我很乐意为任何能够解释它的人投票),但这里有一个解决方案。由于某些原因,Android 不满意您将 XML 膨胀布局调整得如此接近其在
setContentView()
中的实际膨胀。解决方案是在onPostCreate()
或onResume()
中执行布局过程的动态部分,具体取决于您的 Activity 需求。如果您负担得起,我会推荐
onResume()
,因为通常不建议重写onPostCreate()
...但是onResume()
可能会经常被调用,并且可能会弄乱您的布局。以下是修改为使用onPostCreate()
的示例。我注意到的另外两件事可能不会影响您,但我想我会提到:
HashMap.keySet()
是一个糟糕的选择。此方法在不同的实现中以不同的顺序返回这些值。如果您需要顺序始终相同,我会推荐LinkedHashMap
或List
。希望有帮助!请随意忽略任何无用的内容:)
Try as I might, I'm unable to come up with reasoning for why this is occurring (and I would happily upvote anyone who can explain it), but here is a solution. For some reason, Android isn't happy with you adjusting the XML inflated layout so close to its actual inflation in
setContentView()
. The solution is to do the dynamic portion of the layout process either inonPostCreate()
oronResume()
, depending on your Activity needs.I would recommend
onResume()
if you can afford it, sinceonPostCreate()
is not typically suggested for override...howeveronResume()
may be called to often and may mess up your layout. Here is your example modified to useonPostCreate()
instead.Two other things I noticed which may not affect you, but I figured I'd mention:
HashMap.keySet()
is a bad choice. This method returns these values in different orders on different implementations. I would recommend aLinkedHashMap
or aList
if you need the order to always be the same.Hope that Helps! Feel free to ignore anything that wasn't useful :)