以编程方式添加的复选框不保存状态

时间:2014-12-09 15:25:08

标签: android checkbox

在我的代码中,我在linearlayout中有几个视图。视图以编程方式添加

mUserProfile = mNavigationCallback.getUserProfile();
    List<Contact> contacts = mUserProfile.getContacts();
    for (Contact c : contacts) {
        View view = View.inflate(getActivity(), R.layout.item_contact, null);
        TextView tv = (TextView) view.findViewById(R.id.tvPhone);
        tv.setText(c.getValue());
        CheckBox cb = (CheckBox) view.findViewById(R.id.cbContactChecked);
        cb.setId(generateViewId());
        if (c.getType().equals("email")) {
            llEmailContacts.addView(view);
        }
        if (c.getType().equals("phone")) {
            llPhoneContacts.addView(view);
        }
    }

每个视图都包含带Textview和Checkbox的线性布局。 但是当屏幕旋转时,复选框不会保存自己的状态,是什么问题以及如何修复它?

UPD:我不能使用onSaveInstanceState,因为这个片段使用setRetainInstance(true)

3 个答案:

答案 0 :(得分:0)

当您旋转屏幕时,您的活动会被破坏并再次恢复。将重新创建所有成员变量,并重新绘制所有视图。您可以向清单添加一些标记,但是您应该考虑在方法onSaveInstancestate()

中保存状态

在您的示例中,Contact可以有一个变量isSelected,它会在复选框选择中更改

mUserProfile = mNavigationCallback.getUserProfile();
    List<Contact> contacts = mUserProfile.getContacts();
    for (Contact c : contacts) {
        View view = View.inflate(getActivity(), R.layout.item_contact, null);
        TextView tv = (TextView) view.findViewById(R.id.tvPhone);
        tv.setText(c.getValue());
        CheckBox cb = (CheckBox) view.findViewById(R.id.cbContactChecked);
        cb.setChecked(c.isSelected)
        cb.setId(generateViewId());
        if (c.getType().equals("email")) {
            llEmailContacts.addView(view);
        }
        if (c.getType().equals("phone")) {
            llPhoneContacts.addView(view);
        }
    }

然后您覆盖保存所有联系人的onSaveInstanceState

public void onSaveInstanceState(Bundla outState) {
//Save your userprofile somehow, for example by serializing it using json
//and add to bundle
}

然后在onCreate()

public void onCreate(Bundle state) {
//Get your userProfile from state. If it is null, there was no state saved then get it like you //already do = mUserProfile = mNavigationCallback.getUserProfile();
List<Contact> contacts = mUserProfile.getContacts();
for (Contact c : contacts) {
            View view = View.inflate(getActivity(), R.layout.item_contact, null);
            TextView tv = (TextView) view.findViewById(R.id.tvPhone);
            tv.setText(c.getValue());
            CheckBox cb = (CheckBox) view.findViewById(R.id.cbContactChecked);
            cb.setChecked(c.isSelected)
            cb.setId(generateViewId());
            if (c.getType().equals("email")) {
                llEmailContacts.addView(view);
            }
            if (c.getType().equals("phone")) {
                llPhoneContacts.addView(view);
            }
        }
}

答案 1 :(得分:0)

  

Id使用View类

中的generateViewId()方法生成

在设置小部件的初始时间可能没问题。对于第二次及以后的时间,如果您希望内置的已保存实例状态逻辑能够正常工作,则需要使用与之前使用的相同的ID

答案 2 :(得分:0)

通过保存生成的ID并重新使用它来修复:

 mUserProfile = mNavigationCallback.getUserProfile();
    List<Contact> contacts = mUserProfile.getContacts();
    for (Contact c : contacts) {
        View view = View.inflate(getActivity(), R.layout.item_contact, null);
        TextView tv = (TextView) view.findViewById(R.id.tvPhone);
        tv.setText(c.getValue());
        CheckBox cb = (CheckBox) view.findViewById(R.id.cbContactChecked);
        if (c.getViewId() == 0) {
            c.setViewId(generateViewId());
        }
        cb.setId(c.getViewId());

        cb.setTag(c);
        Timber.d("setting CB: " + "ID :" + cb.getId() + " tag " + cb.getTag());

        cb.setOnCheckedChangeListener(mOnCheckedChangeListener);
        if (c.getType().equals("email")) {
            llEmailContacts.addView(view);
        }
        if (c.getType().equals("phone")) {
            llPhoneContacts.addView(view);
        }
    }