切换方向后,复选框都显示相同的文本

时间:2011-05-15 06:14:08

标签: android android-linearlayout

编辑:查看已接受的答案。课程:有时视图会自动保存和恢复其状态。这发生在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:

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>

3 个答案:

答案 0 :(得分:0)

实施

onSaveInstanceState ()
onRestoreInstanceState ()
自定义布局中的

AnswerView。

答案 1 :(得分:0)

为每个AnswerView设置唯一ID是否可以解决您的问题?您可以按如下方式实现:

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
    // BEGIN modified code
    int counter = 0;
    // END modified code
    for (String s : answerInfo.keySet()) {
        cb = new AnswerView(this, s, answerInfo.get(s));
        // BEGIN modified code
        cb.setId(counter);
        counter++;
        // END modified code
        answers.add(cb);
        String text = cb.getText();
        answerList.addView(cb);
    }
}

答案 2 :(得分:0)

尽可能地尝试,我无法想出为什么会发生这种情况的原因(我很乐意向任何可以解释它的人投票),但这是一个解决方案。出于某种原因,Android不满意您调整XML膨胀布局,使其接近setContentView()中的实际通货膨胀率。解决方案是在onPostCreate()onResume()中执行布局过程的动态部分,具体取决于您的活动需求。

如果你能负担得起,我会推荐onResume(),因为onPostCreate()通常不建议覆盖...但是onResume()可能经常被调用,可能会弄乱你的布局。以下是您修改后使用onPostCreate()代替的示例。

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");
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);

        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);
        }
    }
}

我注意到的其他两件事可能不会影响你,但我想我会提到:

  1. 如果您希望您的商品始终以相同的顺序返回,则HashMap.keySet()是不错的选择。此方法在不同的实现上以不同的顺序返回这些值。如果您需要订单始终相同,我建议您使用LinkedHashMapList
  2. 至少在这个例子中,在再次设置它们之前清除你的集合是没有意义的......因为只有在重建Activity时才会这样做。然而,在更大的实施中,这可能有更大的目的。
  3. 希望有帮助!随意忽略任何无用的东西:)