Android:检查多项ListView

4
我正在尝试在ListView中实现多项选择。该列表使用CursorAdapter进行管理。我遵循了http://developer.android.com/guide/topics/ui/menus.html#CAB上的教程。然而,当我运行应用程序时,只有一项被选中(高亮显示)。您能指出我做错了什么吗? MainActivity.java
public class MainActivity extends ActionBarActivity {
DbHelper db;
ListView myList;
ActionMode mActionMode;
int checkedCount;
private static final String[] GENRES = new String[] {
        "Action", "Adventure", "Animation", "Children", "Comedy", "Documentary", "Drama",
        "Foreign", "History", "Independent", "Romance", "Sci-Fi", "Television", "Thriller"
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    db = new DbHelper(this);
    myList = (ListView) findViewById(R.id.newList);
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_activated_1, GENRES);
    myList.setAdapter(adapter);

    loadData();

    myList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
    myList.setItemsCanFocus(false);
    myList.setOnLongClickListener(new View.OnLongClickListener() {
        // Called when the user long-clicks on someView
        public boolean onLongClick(View view) {
            if (mActionMode != null) {

                return false;

            }

            // Start the CAB using the ActionMode.Callback defined above
        //    mActionMode = getActivity().startActionMode(mActionMode.Callback);

            view.setSelected(true);
            view.setBackgroundColor(25);
            return true;
        }
    });
    myList.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {

        @Override
        public void onItemCheckedStateChanged(ActionMode mode, int position,
                                              long id, boolean checked) {
            // Here you can do something when items are selected/de-selected,
            // such as update the title in the CAB
         //   Log.v(ListView.getCheckedItemPositions());
            if(checked)
            {
                checkedCount++;
            }
            else checkedCount--;
            mode.setTitle(checkedCount+" selected");
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            // Respond to clicks on the actions in the CAB
            switch (item.getItemId()) {
                case R.id.menu_delete:
                    //   deleteSelectedItems();
                    mode.finish(); // Action picked, so close the CAB
                    return true;
                default:
                    return false;
            }
        }

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            // Inflate the menu for the CAB
            menu.clear();
            checkedCount=0;
            MenuInflater inflater = mode.getMenuInflater();
            inflater.inflate(R.menu.context_main, menu);
            return true;
        }


        public void onDestroyActionMode(ActionMode mode) {
            // Here you can make any necessary updates to the activity when
            // the CAB is removed. By default, selected items are deselected/unchecked.
        }


        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            // Here you can perform updates to the CAB due to
            // an invalidate() request
            return false;
        }
    });
}

public void onResume()
{
    super.onResume();
    loadData();
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    menu.clear();
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
public void loadData()
{
    Cursor cursor = null;
    try {
        cursor = db.fetchData();
    }
    catch(NullPointerException e)
    {
        e.printStackTrace();
    }
    ListAdapter myAdapter = new SimpleCursorAdapter(this, R.layout.tasks,
            cursor,
            new String[]{db._ID, db.COLUMN_1, db.COLUMN_2},
            new int[]{R.id.idnum, R.id.c1, R.id.c2}, 0);
    myList.setAdapter(myAdapter);


}
public void addNew(View v)
{
    Intent intent = new Intent(this,AddActivity.class);
    startActivity(intent);

}
}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

<TextView android:text="@string/welcome"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:textSize="20sp"
    android:id="@+id/topic"
/>
<ListView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/newList"
    android:layout_below="@+id/topic"
    android:layout_above="@+id/MainButtons"
    android:choiceMode="multipleChoice"
    android:listSelector="@color/background_material_dark"

    ></ListView>
<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:id="@+id/MainButtons"
>
<Button
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:text="@string/add"
    android:id="@+id/addButton"
    android:onClick="addNew"
/>
<Button
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:text="@string/edit"
    android:id="@+id/editButton"
/>
<Button
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:text="@string/del"
    android:id="@+id/deleteButton"
/>
</LinearLayout>

</RelativeLayout>

tasks.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/idnum"
    android:paddingRight="20dp"

    />
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/c1"
    android:layout_toRightOf="@+id/idnum"
    android:paddingRight="20dp"
   />
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/c2"
    android:layout_toRightOf="@+id/c1"
    />
</RelativeLayout>

menu_main.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
<item android:id="@+id/action_settings" android:title="@string/action_settings"
    android:orderInCategory="100" app:showAsAction="always"
   />

</menu>

如果需要更多细节,请在评论中提出。

编辑:我看了重复的问题。但是,大部分答案建议使用ArrayAdapter,而我的列表项是使用SQLite进行管理的,并且每个项由3个单独的项目组成(no,text1,text2)。我如何在这里使用ArrayAdapter?另外,一个得到高票数的答案建议使用CheckedTextView。那么我应该为列表项的所有3个部分都使用CheckedTextView吗?


当你点击下一个项目时会发生什么?会选择新的一个吗?还是什么也不会发生? - skywall
@skywall:没有选择新的,只有我先点击的那个保持选中状态,直到我再次点击它。 - Ayushi Jha
使用 myList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); 替换 myList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);。Modal 是为了 ContexualActionBar 菜单而设计的,也就是说当你长按一个项目时,它会显示一个菜单列表。对于普通的列表视图,请不要使用 modal。 - Vishnu Prabhu
@VishnuPrabhu:我也试过了,现在甚至没有一个项目被选中。 - Ayushi Jha
请添加以下代码:listView.setItemsCanFocus(false); 和 listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); - Vishnu Prabhu
显示剩余12条评论
2个回答

1
我最终通过使用一个“选择器”解决了这个问题。这是“selector.xml”文件:
<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:state_checked="true"
    android:drawable="@color/link_text_material_dark"

    />
<item android:state_active="true"
android:drawable="@color/primary_dark_material_dark"
/>
<item android:state_selected="true"
    android:drawable="@color/highlighted_text_material_dark"
    />

<item android:state_activated="true" android:drawable="@android:color/white" />

</selector> 

最重要的一个是state_activated项。它用于突出显示所有选定的项目。
此外,为了使用此选择器,请将以下行添加到tasks.xml或您定义每个行(项目)的任何位置:
android:background="@drawable/selector"

0

我已经修改了你的代码,做了一些小改动。如果你仍然有问题,请按照SDK示例文件夹中的示例进行操作,该文件夹位于以下位置。

sdks\samples\android-14\ApiDemos\src\com\example\android\apis\view\List16.java

        public class MainActivity extends ActionBarActivity {

            private static final String[] GENRES = new String[] {
                    "Action", "Adventure", "Animation", "Children", "Comedy", "Documentary", "Drama",![enter image description here][2]
                    "Foreign", "History", "Independent", "Romance", "Sci-Fi", "Television", "Thriller"
            };


            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                ListView myList = (ListView) findViewById(R.id.newList);

    /**
     * the use of CHOICE_MODE_MULTIPLE_MODAL, a.k.a. selection mode on ListView
     * couple with the new simple_list_item_activated_1 which uses a highlighted    border for selected
     * items.
     */
                ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                        android.R.layout.simple_list_item_activated_1, GENRES);
                myList.setAdapter(adapter);
                myList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
                myList.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {

                    @Override
                    public void onItemCheckedStateChanged(ActionMode mode, int position,
                            long id, boolean checked) {
                        // Here you can do something when items are selected/de-selected,
                        // such as update the title in the CAB
                    }

                    @Override
                    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                        // Respond to clicks on the actions in the CAB
                        switch (item.getItemId()) {
                            case R.id.action_settings:
                                //   deleteSelectedItems();
                                mode.finish(); // Action picked, so close the CAB
                                return true;
                            default:
                                return false;
                        }
                    }

                    @Override
                    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                        // Inflate the menu for the CAB
                        MenuInflater inflater = mode.getMenuInflater();
                        inflater.inflate(R.menu.menu_main, menu);
                        return true;
                    }


                    public void onDestroyActionMode(ActionMode mode) {
                        // Here you can make any necessary updates to the activity when
                        // the CAB is removed. By default, selected items are deselected/unchecked.
                    }


                    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                        // Here you can perform updates to the CAB due to
                        // an invalidate() request
                        return false;
                    }
                });

            }
        }

![enter image description here][1]


menu_main.xml

    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
        <item android:id="@+id/action_settings" android:title="@string/action_settings"
            android:orderInCategory="100" app:showAsAction="always" android:icon="@drawable/ic_launcher" />
    </menu>


activity_main.xml is same as your layout.

enter image description here


mActionMode 是什么? - Ayushi Jha
它显示无法解析符号getActivity()和mActionModeCallback。 - Ayushi Jha
您已经两次实现了多选监听器,一次是作为匿名类,另一次是由活动本身实现。请检查以上内容。 - Vishnu Prabhu
我理解了你提到的第二点关于多选监听器的实现,但是当另一个项目被点击时仍然没有任何反应。 - Ayushi Jha
好的,我可以选择项目,但如何将它们标记出来? - Ayushi Jha
显示剩余9条评论

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