【问题标题】:Android: Check multiple items ListViewAndroid:检查多个项目ListView
【发布时间】:2015-04-25 22:00:48
【问题描述】:

我正在尝试在 ListView 中实现多个项目选择。该列表使用 CursoAdapter 进行管理。我正在关注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 吗?

【问题讨论】:

  • @Lamorak:点击你提供的链接给了我一堆新错误。 :( 请同时查看已编辑的问题。
  • 点击下一项时会发生什么?新的被选中了吗?什么都没发生?
  • @skywall: 没有新的没有被选中,只有我第一次点击的那个一直被选中,直到我再次点击它。
  • @Lamorak:我也试过list Adapter方法,logcat给了我NullPointerException

标签: android listview listadapter listitem


【解决方案1】:

我终于通过使用selector 解决了这个问题。这是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"

【讨论】:

    【解决方案2】:

    我已经修改了你的代码,添加了一些小改动。如果您仍然有问题,请按照您的 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.
    

    【讨论】:

    • 什么是mActionMode
    • 为分配给 ListView 的新 AbsListView.MultiChoiceModeListener() 创建一个引用对象。 mActionMode 只不过是 ActionMode.Callback 类的对象。 MultiChoiceModeListener() 扩展了 ActionMode.CallBack。设置对象参考您的 MultiChoiceModeListnener。 OnLongPress 调用该对象的 startActionMode(multichoiceListnener object)
    • 显示无法解析符号 getActivity() 和 mActionModeCallback
    • 您已经实现了两次多选监听器,一次是作为匿名类,另一次是通过活动本身实现的。请检查以上内容。
    • 我得到了你关于两次实现多选监听器的第二点,但是,单击另一个项目时仍然没有任何反应。
    猜你喜欢
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-18
    • 1970-01-01
    相关资源
    最近更新 更多