【问题标题】:ListActivity with a complex row item: how to access row views?具有复杂行项的 ListActivity:如何访问行视图?
【发布时间】:2013-11-22 11:41:39
【问题描述】:

我很确定这是可能的,但奇怪的是找不到方法。 所以,我有一个ListActivity。我希望这是它的行元素:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <CheckBox
        android:id="@+id/checkbox"
        style="@style/CheckBox" />

    <TextView
        android:id="@+id/text"
        style="@style/Label"
        android:layout_width="fill_parent"
        android:layout_height="50sp"
        android:gravity="center_vertical" />

</LinearLayout>

我已经可以使用这个布局了,我知道在创建ArrayAdapter时如何指定TextView的id。布局很好,我可以勾选复选框。

问题是,我不明白如何访问这些复选框。我需要一个膨胀的行布局来调用findViewById,但它是异步膨胀的,而不是在我将项目添加到适配器时立即膨胀。如何做到这一点?

【问题讨论】:

  • 这和TestView一样。。有什么问题。解释
  • 你想用它们做什么?
  • @PankajKumar:不一样。我愿意:ArrayAdapter&lt;String&gt; list = new ArrayAdapter&lt;String&gt;(this, R.layout.row, R.id.text, items); 它会自行填充TextViews。我不必手动操作。 CheckBoxes我需要访问自己,目前还不清楚如何。
  • @Geralt:添加新列表行时,我需要获取对其CheckBox 的引用(可能是异步的,我不在乎)。例如,如果我可以获取行视图,我会调用 findViewById(R.id.checkbox) 并完成。
  • @PankajKumar All 加深了你想用复选框做的事情。我现在有一些方法,但似乎效率不高。如果你能告诉我你想要实现什么,也许很快就会有答案。

标签: android android-ui


【解决方案1】:

选中 CheckBox 时,我需要取消选中所有其他复选框并 存储选中的索引

这是我现在想到的解决方案。我现在不知道您的实现(适配器的实现、数据源等),因此您可能需要进行一些修改。所以现在我的解决方案:

您需要 onCheckedChangedListener 并放入您的 ListAdapter 类:

public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
   // do your stuff
}

现在我不知道您的实际情况,但很可能您有一些要传递给 Adapter 的对象集合,并且您在返回行视图的 getView() 方法中使用它。

正是在这里,我建议修改您的对象(表示适配器中每一行的项目)并添加属性:

private boolean isChecked;

这将“代表”您的 CheckBox

现在每个 CheckBox 都将被隐式取消选中(没关系,因为布尔值被隐式分配为 false)。

现在直接进入Adapter类。在您的班级中,正是在您的 getView() 中,您需要执行以下操作:

public View getView(final int position, View convertView, ViewGroup parent) {
   RowHolder holder = null; // RowHolder that holds widgets for each row
   LayoutInflater inflater = LayoutInflater.from(context); // for inflate rows

   // logic for inflating rows, pretty simply
   if (convertView == null) {
      // inflate row
      convertView = inflater.inflate(<yourLayout>, null, false);
      holder = new RowHolder(convertView);
      convertView.setTag(holder);
   }
   else {
      // recycle row
      holder = (RowHolder) convertView.getTag();
   }

   // inicialising row values
   final Item i = collection.get(position); // item from collection

   /** here will be work with CheckBoxes **/

   // here you will set position as CheckBox's tag
   holder.getCheckBox().setTag(position);

   // set CheckBox checked or not due to item in collection
   holder.getCheckBox().setChecked(item.isChecked());

   // and assign listener to CheckBox
   holder.getCheckBox().setOnCheckedChangeListener(this);
}

这是非常重要的逻辑。在这里,您将 CheckBox 在 Adapter 中的位置保存到 CheckBox 本身中。现在 CheckBox 知道“位于哪里”

然后你的听众会做出以下动作:

public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
   // buttonView is CheckBox you changed state so we know which CheckBox it is
   int position = (Integer) buttonView.getTag();

   // if CheckBox is checked
   if (isChecked) {

      // iterate collection and assign all items except selected into false
      for (int i = 0; i < collection.size(); i++) {
         if (i != position) {
            collection.get(i).setChecked(false);
         }
      }

      // now call notifyDataSetChanged() that will call getView() method again
      // and it will update your List
      notifyDataSetChanged();
   }  
}

这里听者会耍花招。还有一些关于

希望它能帮助你实现目标。

【讨论】:

  • 实际上,直到现在我什至没有自定义适配器 :)
  • @VioletGiraffe 自定义适配器是一种非常有效的方式,可以更好地控制您的适配器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-09
相关资源
最近更新 更多