在Android中带有复选框的列表视图中选择项目

3
我已经创建了一个带有复选框和搜索功能的列表视图。搜索功能正常,复选框也正常显示。现在我想要的是,在单击按钮时获取所有已选列表项的名称。我还想知道如何在项目名称下面显示另一个文本视图,例如价格。
主布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <!-- Editext for Search -->

    <EditText
        android:id="@+id/inputSearch"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="Search products.."
        android:inputType="textVisiblePassword" />

    <ListView
        android:id="@+id/mainListView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >
    </ListView>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="5dp"
        android:onClick="showResult"
        android:text="Show Result" >
    </Button>

</LinearLayout>

simplerow.xml文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">

  <TextView android:id="@+id/rowTextView" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:textStyle="bold"
    android:textSize="16sp" >
  </TextView>

  <CheckBox android:id="@+id/CheckBox01" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:padding="10dp"
    android:layout_alignParentRight="true" android:layout_marginRight="6sp"
    android:focusable="false">
  </CheckBox>

</RelativeLayout>
活动(Activity):
public class MultiSelectList extends Activity {

     // Search EditText
       EditText inputSearch;

    private ListView mainListView;
    private mItems[] itemss;
    private ArrayAdapter<mItems> listAdapter;
    ArrayList<String> checked = new ArrayList<String>();

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Find the ListView resource.
        mainListView = (ListView) findViewById(R.id.mainListView);
        inputSearch = (EditText) findViewById(R.id.inputSearch);

        // When item is tapped, toggle checked properties of CheckBox and
        // Planet.
        mainListView
                .setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View item,
                            int position, long id) {
                        mItems planet = listAdapter.getItem(position);
                        planet.toggleChecked();
                        SelectViewHolder viewHolder = (SelectViewHolder) item
                                .getTag();
                        viewHolder.getCheckBox().setChecked(planet.isChecked());

                    }
                });

        // Create and populate planets.
        itemss = (mItems[]) getLastNonConfigurationInstance();

        ArrayList<mItems> planetList = new ArrayList<mItems>();

        planetList.add(new mItems("DJ- Android"));
        planetList.add(new mItems("Android"));
        planetList.add(new mItems("iPhone"));
        planetList.add(new mItems("BlackBerry"));
        planetList.add(new mItems("Java"));
        planetList.add(new mItems("PHP"));
        planetList.add(new mItems(".Net"));
        planetList.add(new mItems("Jhoomla"));

        // Set our custom array adapter as the ListView's adapter.
        listAdapter = new SelectArralAdapter(this, planetList);
        mainListView.setAdapter(listAdapter);

         /**
            * Enabling Search Filter
            * */
           inputSearch.addTextChangedListener(new TextWatcher() {

               @Override
               public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
                   // When user changed the Text
                   MultiSelectList.this.listAdapter.getFilter().filter(cs);   
               }

               @Override
               public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
                       int arg3) {
                   // TODO Auto-generated method stub

               }

               @Override
               public void afterTextChanged(Editable arg0) {
                   // TODO Auto-generated method stub                          
               }
           });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // TODO Auto-generated method stub
        menu.add(0, 1, Menu.NONE, "Products");
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // TODO Auto-generated method stub
        switch (item.getItemId()) {
        case 1:

            for (int i = 0; i < checked.size(); i++) {
                Log.d("pos : ", "" + checked.get(i));
            }
            break;
        }
        return super.onOptionsItemSelected(item);
    }

    /** Holds planet data. */
    private static class mItems {
        private String name = "";
        private boolean checked = false;

        public mItems() {
        }

        public mItems(String name) {
            this.name = name;
        }

        public mItems(String name, boolean checked) {
            this.name = name;
            this.checked = checked;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public boolean isChecked() {
            return checked;
        }

        public void setChecked(boolean checked) {
            this.checked = checked;
        }

        public String toString() {
            return name;
        }

        public void toggleChecked() {
            checked = !checked;
        }
    }

    /** Holds child views for one row. */
    private static class SelectViewHolder {
        private CheckBox checkBox;
        private TextView textView;

        public SelectViewHolder() {
        }

        public SelectViewHolder(TextView textView, CheckBox checkBox) {
            this.checkBox = checkBox;
            this.textView = textView;
        }

        public CheckBox getCheckBox() {
            return checkBox;
        }

        public void setCheckBox(CheckBox checkBox) {
            this.checkBox = checkBox;
        }

        public TextView getTextView() {
            return textView;
        }

        public void setTextView(TextView textView) {
            this.textView = textView;
        }
    }

    /** Custom adapter for displaying an array of Planet objects. */
    private static class SelectArralAdapter extends ArrayAdapter<mItems> {
        private LayoutInflater inflater;

        public SelectArralAdapter(Context context, List<mItems> planetList) {
            super(context, R.layout.simplerow, R.id.rowTextView, planetList);
            // Cache the LayoutInflate to avoid asking for a new one each time.
            inflater = LayoutInflater.from(context);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // Planet to display
            mItems planet = (mItems) this.getItem(position);

            // The child views in each row.
            CheckBox checkBox;
            TextView textView;

            // Create a new row view
            if (convertView == null) {
                convertView = inflater.inflate(R.layout.simplerow, null);

                // Find the child views.
                textView = (TextView) convertView
                        .findViewById(R.id.rowTextView);
                checkBox = (CheckBox) convertView.findViewById(R.id.CheckBox01);
                // Optimization: Tag the row with it's child views, so we don't
                // have to
                // call findViewById() later when we reuse the row.
                convertView.setTag(new SelectViewHolder(textView, checkBox));
                // If CheckBox is toggled, update the planet it is tagged with.
                checkBox.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View v) {
                        CheckBox cb = (CheckBox) v;
                        mItems planet = (mItems) cb.getTag();
                        planet.setChecked(cb.isChecked());
                    }
                });
            }
            // Reuse existing row view
            else {
                // Because we use a ViewHolder, we avoid having to call
                // findViewById().
                SelectViewHolder viewHolder = (SelectViewHolder) convertView
                        .getTag();
                checkBox = viewHolder.getCheckBox();
                textView = viewHolder.getTextView();
            }

            // Tag the CheckBox with the Planet it is displaying, so that we can
            // access the planet in onClick() when the CheckBox is toggled.
            checkBox.setTag(planet);
            // Display planet data
            checkBox.setChecked(planet.isChecked());
            textView.setText(planet.getName());
            return convertView;
        }
    }

    public Object onRetainNonConfigurationInstance() {
        return itemss;
    }




}

我应该做些什么才能得到想要的结果呢?


你可以在 setOnItemClickListener 中将点击的项目存储到 ArrayList 中或者其他容器中,然后在按钮被点击时,你就会得到准备好的列表。 - Shashank Kadne
@kittu88为什么不检查已发布的链接是否有可用的代码? - Raghunandan
@Raghunandan,我填充ListView并实现搜索功能的方式与给定链接中不同。他们以不同的方式填充列表,但没有搜索功能。 - kittu88
@kittu88,将搜索功能保持不变的情况下提取已选项目的逻辑实现起来有多难?你已经有了搜索功能,也有了获取已选项目的示例。将它们整合起来即可。 - Raghunandan
@Raghunandan 他们提取列表项的方式不同,实际上他们使用的ArrayList也不同,我的ArrayList用于搜索功能。如果您能够仔细阅读这两个代码,您就会明白! - kittu88
显示剩余4条评论
2个回答

1
你应该在自定义适配器中保留复选框的状态,使用一些ArrayList或SparseArray。然后,当你想要获取所有选中项的名称时,只需遍历数组并读取已选参数为true的名称。当然,在复选框状态改变时,列表应该被更新。
这是唯一正确的解决方案,因为屏幕上只有少数ListView项目是可见的,所以试图即时读取它们的属性是不可靠的 - 任何时刻项目可能被回收,因此无法访问。

代码建议请! - kittu88
这里有一个包含复选框的ListView自定义适配器的示例。 - Malachiasz

1
现在我想要的是,当单击按钮时,我想获取所有已选列表项的名称。 为什么不遍历itemss数组并获取其checked字段为true的项目? 我还想知道如何显示另一个文本视图,比如项目名称下面的价格。 更新您的simplerow.xml(添加价格TextView),还有您的SelectViewHolder和SelectArralAdapter。 我猜这些不应该很难编码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接