【问题标题】:CheckBoxes in ListView disappear when the screen rotatesListView 中的复选框在屏幕旋转时消失
【发布时间】:2012-04-26 16:14:29
【问题描述】:

我的应用程序首先所做的是通过设置其可见性View.Gone来加载ListView,其项目具有不可见CheckBoxes。当用户点击菜单按钮时,它将打开和关闭CheckBox 可见性和其他一些布局。下面是代码,我去掉了一些不必要的部分:

private void editmodeSwitch(boolean flag){
    // get topbar, bottombar, and bottombar2
    LinearLayout topbar = (LinearLayout) findViewById(R.id.task_topbar_linearLayout);
    LinearLayout bottombar = (LinearLayout) findViewById(R.id.task_bottombar1_linearlayout);
    LinearLayout bottombar2 = (LinearLayout) findViewById(R.id.task_bottombar2_linearlayout);

    if(flag){
        isEditmodeOn = true;            

        // make topbar and bottombar2 visilble, but bottombar gone
        topbar.setVisibility(View.VISIBLE);
        bottombar.setVisibility(View.GONE);
        bottombar2.setVisibility(View.VISIBLE);

        // make checkboxes visible in listview visible as well
        for(int i=0; i<listView.getChildCount(); i++){
            LinearLayout ll = (LinearLayout) listView.getChildAt(i);
            CheckBox cb = (CheckBox) ll.findViewById(R.id.task_row_checkBox1);
            cb.setVisibility(View.VISIBLE);
        }
    }
    else{
        isEditmodeOn = false;

        topbar.setVisibility(View.GONE);
        bottombar.setVisibility(View.VISIBLE);
        bottombar2.setVisibility(View.GONE);

        // set each checkbox false and its visibility gone
        for(int i=0; i<listView.getChildCount(); i++){
            LinearLayout ll = (LinearLayout) listView.getChildAt(i);
            CheckBox cb = (CheckBox) ll.findViewById(R.id.task_row_checkBox1);
            cb.setVisibility(View.GONE);
            cb.setChecked(false);
        }
    }
}

它工作正常,但问题是当屏幕旋转时应用程序不工作(改变屏幕方向)。一切正常,因为它显示了一些布局,但只有CheckBoxes in list items. Below is the code inonCreate()`:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.task_layout);

    initialize();
    loadDB();
    updateListAdapter(list_title, list_date);

    // in case of screen rotation
    if(savedInstanceState != null){
        isEditmodeOn = savedInstanceState.getBoolean(EDITMODE_CHECK);
        isItemChecked = savedInstanceState.getBoolean(ITEM_CHECK);

        if(isEditmodeOn){
            if(!isItemChecked){
                Log.i(tag, "item NOT checked");
                editmodeSwitch(true);
            } else{
                //this is something different so please don't mind
                deditmodeSwitch(savedInstanceState.getBooleanArray(LIST_CB_CHECK));
            }
        }
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    // save values for rotation
    outState.putBoolean(EDITMODE_CHECK, isEditmodeOn);
    outState.putBoolean(ITEM_CHECK, isItemChecked);
    outState.putBooleanArray(LIST_CB_CHECK, list_cb_check);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    Log.i(tag, "you're in onRestoreInstanceState()");

    // in case of screen rotation
    if(savedInstanceState != null){
        isEditmodeOn = savedInstanceState.getBoolean(EDITMODE_CHECK);
        isItemChecked = savedInstanceState.getBoolean(ITEM_CHECK);

        if(isEditmodeOn){
            if(!isItemChecked){
                Log.i(tag, "item NOT checked");
                editmodeSwitch(true);
            } else{
                // this is for something else so please ignore this part
                editmodeSwitch(savedInstanceState.getBooleanArray(LIST_CB_CHECK));
            }
        }
    }

我猜是 ListView 正在最后加载。因此,即使onCreate() 中的代码使CheckBoxes 可见,CheckBoxes 将再次变为不可见,因为它在 xml 中的初始化将这样做。但是,我被困在这里,需要您的建议来解决这个问题。谁能帮帮我?

以防万一,下面是getview的布局xml文件的复选框代码。

<CheckBox android:id="@+id/task_row_checkBox1" android:gravity="right" 
    android:layout_width="wrap_content" android:layout_height="wrap_content" 
    android:visibility="gone"
    />

【问题讨论】:

  • 在检索之前,您没有在 onSaveInstanceState 中保存复选框状态。所以首先通过覆盖 onSaveInstanceState 在 onSaveInstanceState 中保存状态
  • 对不起伊姆兰。我将在一分钟内将我的代码放入 onSaveInstanceState() 中。谢谢你的建议!

标签: android android-listview rotation checkbox


【解决方案1】:

覆盖 onSaveInstanceState 以保存屏幕旋转的值,覆盖 onRestoreInstanceState 为:

protected void onCreate(Bundle savedInstanceState) {

    if(null != savedInstanceState)
            {
                Boolean IntTest = savedInstanceState.getBoolean("ITEM_CHECK");
                Boolean StrTest = savedInstanceState.getBoolean("ITEM_CHECK");
                Log.e(TAG, "onCreate get the   savedInstanceState+IntTest="+IntTest+"+StrTest="+StrTest);        
            }
}
        @Override
        public void onSaveInstanceState(Bundle savedInstanceState) {
            // Save away the CheckBoxes states, so we still have it if the activity
            // needs to be killed while paused.

          savedInstanceState.putBoolean(EDITMODE_CHECK, 0);
          savedInstanceState.putBoolean(ITEM_CHECK, 0);
          super.onSaveInstanceState(savedInstanceState);
          Log.e(TAG, "onSaveInstanceState");
        } 
        @Override
        public void onRestoreInstanceState(Bundle savedInstanceState) {
          super.onRestoreInstanceState(savedInstanceState);
          Boolean IntTest = savedInstanceState.getBoolean(EDITMODE_CHECK);
          Boolean StrTest = savedInstanceState.getBoolean(ITEM_CHECK);
          Log.e(TAG, "onRestoreInstanceState+IntTest="+IntTest+"+StrTest="+StrTest);
        }

【讨论】:

  • 感谢您的想法 Imran。但是,它并没有解决我的问题。经过一些测试,似乎在onSaveInstanceState和onRestoreInstanceState之后仍然在最后加载复选框可见性不可见的getview的布局xml文件。因此,我猜他们重置了我的复选框 View.Gone。我知道你已经给了我一个好主意,但如果可能的话,我可以再请你帮忙吗?
  • 我猜 onRestoreInstanceSate() 或 onCreate() 的捆绑参数实际上工作正常,但我认为唯一的问题是 getview 的布局 xml 文件似乎在最后加载。由于此布局文件将复选框 View.Gone 设置为初始化,这就是为什么所有其他功能都有效但只有复选框可见性,因为它将被布局文件重置。因此,我想我需要在加载 getview 后调用我的代码,但我被困在这里(或者我的想法可能是错误的)你对这个 Imran 有什么想法吗?提前感谢您的快速回复!
  • 向我们展示您的 onRestoreInstanceState 和 onSaveInstanceState 代码,然后我们可以从那里开始。
  • 对不起,我忘了上传它们。我现在才这样做。谢谢 Gophermofur!
  • 感谢您对 Gophermofur 的持续帮助!我放了 super.onSaveInstanceState(outState) 但不幸的是复选框仍然隐藏。我也阅读了您的修改后的答案,但是,很难找到在哪里设置代码以设置复选框可见,因为似乎复选框的布局 xml 仍在稍后加载(或者我的想法可能是错误的)。现在,我开始认为在 getview 中修改它们可能会更好。你觉得这样好吗?
【解决方案2】:

与覆盖 onCreate 的方式类似,您可以覆盖 onConfigurationChanged(...),您可以将其设置为在屏幕改变方向时运行。

为了在屏幕旋转时触发 OnConfigurationChanged(...),您需要编辑清单并将该关系/规则放入其中。

这很容易做到,但需要一些解释,之前在这个问题中已经回答过: Activity restart on rotation Android

编辑:这是关于如何处理配置更改的开发指南 http://developer.android.com/guide/topics/resources/runtime-changes.html

编辑#2:首先,让我建议使用 Imran 的解决方案。它更好地遵循开发者指南,最终结果将是相同的。

现在,关于 onConfigurationChanged 解决方案。

看看你在用你的 onCreate 做什么:

1) 设置视图。 (此时复选框已隐藏。对吗?)

2) 调用您的数据库并确定您是否应该显示复选框(编辑模式)

3) 使所有复选框可见。

现在,onConfigurationChanged 还调用 setContentView,此时您的所有复选框都将再次隐藏。所以你需要重复使你的复选框可见的过程(上面的#3)。您可能不需要重复第 2 步,因为应该保留该值,但我不确定您的应用程序的逻辑是如何工作的,因此您可能需要重新执行第 2 步.

这有意义吗?

【讨论】:

  • 为什么要覆盖这个问题所需的 OnConfigurationChanged?
  • 感谢您的想法和良好的链接 Gophermofur。我可以学习新技术。并使用了 onConfiguraionChanged() 方法,但它仍然没有使复选框可见(其他布局工作正常)。经过一些测试,我认为 getview 的布局 xml,其中有复选框 View.Gone 作为初始化,最后仍在加载。因此,这就是为什么复选框变得不可见的原因,因为 xml 文件具有复选框 View.Gone 并在 onConfigurationChanged() 和 onRestoreInstanceState() 使它们可见之后重置复选框不可见。我知道你已经帮了我很多,但是,我可以请求你更多的帮助吗?
  • 这里解释太长了,请看我修改后的答案。
【解决方案3】:

根据我的经验,getview 似乎在最后被触发,这就是为什么 'onRestoreInstanceState()' 和 'onConfigurationChanged()' 无法成功,因为 getview 将重置我的复选框在布局 xml 文件中初始化时不可见。

因此,我能找到的唯一解决方案是我必须在 getview 中控制它们以获得答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-14
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-15
    • 1970-01-01
    • 2012-04-03
    相关资源
    最近更新 更多