1

我有一个应用程序,它使用复合视图在片段中显示多个相似类型的视图。这些复合视图的一个自定义部分是为每个复合视图中的 CheckBox 设置的文本。片段的生命周期第一次显示视图的内容一切都很好(每个复选框都具有片段的 xml 中使用属性指定的正确文本),但是在每个后​​续视图(在方向更改或通过选项卡导航之后)所有 CheckBox 文本设置为相同的值(最后一个复合视图的复选框文本值)。

我的复合视图的 xml 布局信息。 复合视图.xml:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">  
  <CheckBox
    android:id="@+id/myCheckBox" 
    style="@style/CheckBoxLeftAligned" 
    android:checked="false"
  />
  ...
</merge>

我的属性文件允许为每个复合视图的复选框设置特定文本。 属性.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="ZZZ">
    <attr name="name"   format="string" />              
  </declare-styleable>
</resources>

我的片段布局,其中包含我的四个复合视图。 片段布局.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:ctd="http://schemas.android.com/apk/res/com.xxx.yyy"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical">
  <RelativeLayout 
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.xxx.yyy.ui.zzz
      android:id="@+id/aaa"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      ctd:name="@string/aaa"
    />
    <com.xxx.yyy.ui.zzz
      android:id="@+id/bbb"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      ctd:name="@string/bbb"
    />
    <com.xxx.yyy.ui.zzz
      android:id="@+id/ccc"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      ctd:name="@string/ccc"
    />
    <com.xxx.yyy.ui.zzz
      android:id="@+id/ddd"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      ctd:name="@string/ddd"
    />
  </RelativeLayout>
</ScrollView>

我的复合视图的 java 实现。 zzz.java

package com.xxx.yyy.ui;

... 

public class zzz extends RelativeLayout {

  private static final String TAG = zzz.class.getSimpleName();

  private final Context mContext;

  private CheckBox mLabelCheckBox;


  public zzz(Context context, AttributeSet attrs) {
    super(context, attrs);

    mContext = context;

    initializeLayoutBasics(context);
    processAttributeInformation(context, attrs);


  }

  private void initializeLayoutBasics(Context context) {
    final LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    inflater.inflate(R.layout.composite_view, this);    
  }

  private void processAttributeInformation(Context context, AttributeSet attr) {
    mLabelCheckBox = (CheckBox) findViewById(R.id.myCheckBox);

    final TypedArray a = context.obtainStyledAttributes(attr, R.styleable.ZZZ);
    String text = a.getString(R.styleable.ZZZ_name);
    mLabelCheckBox.setText(text);
    Log.d(TAG, "CheckBox=" + mLabelCheckBox.toString() + ", Title= " + payName);            

    a.recycle();
  }

  ...
}

目录日志输出

03-10 08:20:31.151: D/MyFragment(400): MyFragment.onAttach
03-10 08:20:31.151: D/MyFragment(400): MyFragment.onCreate
03-10 08:20:31.151: D/MyFragment(400): MyFragment.onCreateView
03-10 08:20:31.200: D/zzz(400): CheckBox=android.widget.CheckBox@40a78e00, Title= MSP
03-10 08:20:31.220: D/zzz(400): CheckBox=android.widget.CheckBox@40a9da58, Title= ISP
03-10 08:20:31.239: D/zzz(400): CheckBox=android.widget.CheckBox@40aa1248, Title= ASP
03-10 08:20:31.250: D/zzz(400): CheckBox=android.widget.CheckBox@40aa4a88, Title= Board Certified Pay
03-10 08:20:31.260: D/zzz(400): CheckBox=android.widget.CheckBox@40aa8310, Title= HPO Board Cert Pay
03-10 08:20:31.270: D/MyFragment(400): MyFragment.onStart
03-10 08:20:31.270: D/MyFragment(400): MyFragment.onResume
03-10 08:20:32.410: D/App(400): onTabUnselected detaching fragment MyFragment
03-10 08:20:32.426: D/App(400): onTabSelected adding fragment OtherFragment
03-10 08:20:32.440: D/MyFragment(400): MyFragment.onPause
03-10 08:20:32.450: D/TotalPayFragment(400): OtherFragment.onCreateView
03-10 08:20:32.519: D/TotalPayFragment(400): OtherFragment.onStart
03-10 08:20:33.120: D/App(400): onTabUnselected detaching fragment OtherFragment
03-10 08:20:33.120: D/App(400): onTabSelected attaching fragment MyFragment
03-10 08:20:33.170: D/MyFragment(400): MyFragment.onCreateView
03-10 08:20:33.190: D/SimplePay(400): CheckBox=android.widget.CheckBox@40acb618, Title= MSP
03-10 08:20:33.201: D/SimplePay(400): CheckBox=android.widget.CheckBox@40ace530, Title= ISP
03-10 08:20:33.210: D/SimplePay(400): CheckBox=android.widget.CheckBox@40ad1c20, Title= ASP
03-10 08:20:33.230: D/SimplePay(400): CheckBox=android.widget.CheckBox@40ad5310, Title= Board Certified Pay
03-10 08:20:33.280: D/SimplePay(400): CheckBox=android.widget.CheckBox@40ad8ad8, Title= HPO Board Cert Pay
03-10 08:20:33.290: D/MyFragment(400): MyFragment.onStart
03-10 08:20:33.290: D/MyFragment(400): MyFragment.onResume

因此,即使是我的 catlog 输出也显示我的每个复选框都被设置为我在片段的 xlm 中使用属性设置的特定文本。但是在我的片段第二次通过 onCreateView 之后,所有 CheckBox 文本值都设置为“HPO Board Cert Pay”。此输出使用 Honeycomb 仿真器。

在复合视图中设置 TextBoxes 中的文本时,我使用了相同的模式,所以我打赌这与复选框有关。

有什么想法吗?

4

2 回答 2

0

虽然我无法回答为什么 Android 会像我所说的那样表现,但以下是我的解决方法:

我通过在我的 onResume 中创建和调用以下函数并将 forceUpdateOfCheckBoxText 方法添加到我的复合 UI 来解决这个问题。

  //Used to force checkboxes to be updated
  private void forceUpdateOfCheckboxesInCompositeViews(ViewGroup parent) {    
    for(int i = 0; i < parent.getChildCount(); i++) {
          View child = parent.getChildAt(i);            

          if(child instanceof ViewGroup) {
            Class<?> c = child.getClass();
            if (c == SimplePay.class) {
              ((SimplePay) child).forceUpdateOfCheckBoxText();
            } 
            else {
                forceUpdateOfCheckboxesInCompositeViews((ViewGroup)child);
            }
          }               
      }
  }

从我的角度来看,这不是最理想的,但它确实有效。

于 2014-01-14T01:40:00.780 回答
0

默认情况下,Android 会恢复ViewActivity 中所有对象的状态。要正确执行此操作,每个视图都需要一个唯一 ID(请参阅重新创建 Activity)。

您的视图的嵌套结构导致有四个具有 ID 的视图aaa,其他视图也是如此。这会导致视图的状态被错误地恢复。

一种解决方法是覆盖onSaveInstanceState()并清除outState捆绑包。这将阻止 Android 保存视图的状态。缺点是你要自己负责维护状态;否则会丢失,比如用户EditText在旋转屏幕后会丢失文本。

于 2013-12-11T19:44:26.990 回答