Android Java更改ListView以选择多行(用于删除)而没有单独的类 [英] Android Java change ListView to select multiple lines (for deleting) without a separate class

查看:43
本文介绍了Android Java更改ListView以选择多行(用于删除)而没有单独的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我搜索过高和低,我开始认为这是不可能的,但是我有一个自定义的ListView,它以夸张的布局放置在弹出窗口中.这些线是使用适配器从布局文件制成的.列表中的每个项目都是可单击的,并将用户带到不同的列表.我还希望这样做,以便当我长按一个项目时,它选择该项目,然后允许我选择多行,然后有一个单独的按钮来删除它们.需要明确的是,我不需要每行都有一个复选框(没有空间).只是要突出显示的行.我被选择该项目"卡住了.部分,更不用说选择多条线"了.我将把代码截断为相关部分.注意:masterRecord是ListView的名称.

  private void fillList(){int numRows = mainDB.numRowsMaster();如果(numRows == 0){Toast.makeText(getApplicationContext(),没什么可加载!",Toast.LENGTH_SHORT).show();返回;}cursor = mainDB.getAllRowsMaster();startManagingCursor(cursor);String [] fromFieldNames = new String [] {DBAdapter.KEY_MASNAMECOL,DBAdapter.KEY_MASLASTDATECOL,DBAdapter.KEY_MASTOTALTIMEASCLOCKCOL};int [] toViewIds = new int [] {R.id.rowName,R.id.rowLastDate,R.id.rowTotalTime};SimpleCursorAdapter cursorAdapter =新的SimpleCursorAdapter(this,R.layout.master_list_row,cursor,fromFieldNames,toViewIds);masterRecord.setAdapter(cursorAdapter);masterRecord.setLongClickable(true);} 

  private void listItemClick(){masterRecord.setOnItemClickListener((parent,viewClicked,position,idInDB)-> {//这里的代码束使下一个listview弹出并创建一个游标适配器.这一切都很好.});masterRecord.setOnItemLongClickListener((parent, view, position, idInDB) -> {Toast.makeText(getApplicationContext(),这工作正常吗?",Toast.LENGTH_SHORT).show();masterRecord.setClickable(false);//即使正在运行,这也没有什么不同.//masterRecord中的项目仍可单击.我不担心ATM的其他问题.masterRecord.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);masterRecord.setMultiChoiceModeListener(new ListView.MultiChoiceModeListener(){@Overridepublic void onItemCheckedStateChanged(ActionMode mode,int position,long id,boolean checked){Toast.makeText(getApplicationContext(),"Here4",Toast.LENGTH_SHORT).show();}@Overridepublic boolean onCreateActionMode(ActionMode模式,菜单菜单){Toast.makeText(getApplicationContext(),"Here1",Toast.LENGTH_SHORT).show();返回false;}@Overridepublic boolean onPrepareActionMode(ActionMode模式,菜单菜单){Toast.makeText(getApplicationContext(),"Here3",Toast.LENGTH_SHORT).show();返回false;}@Overridepublic boolean onActionItemClicked(ActionMode mode,MenuItem item){Toast.makeText(getApplicationContext(),"Here2",Toast.LENGTH_SHORT).show();返回false;}@Overridepublic void onDestroyActionMode(ActionMode mode){Toast.makeText(getApplicationContext(),"Here5",Toast.LENGTH_SHORT).show();}});返回true;});} 

这些吐司只是为了让我可以在屏幕上看到正在运行的内容.这有效吗?"是我长按时显示的唯一内容.什么都没被选择,如果我一直按住不放,它只会继续做同样的事情.如果再短按,则只会执行普通的短按操作.

我找到了Checkable小部件并兴奋不已,但似乎也无法使它工作.我所见过的教程和其他信息为ListView提供了一个单独的类,但这似乎有点过头了.那真的是唯一的方法吗?如果我错过任何相关代码,请告诉我,我将进行编辑以包括在内.谢谢.

解决方案

我在另一篇文章(类似)中找到了答案,所以我将在这里发表我的所作所为,并链接到他们的答案./p>

按照以下答案进行设置: https://stackoverflow.com/a/25169360/5374362 这包括使可绘制对象在行布局上使用.请记住,您可以将可绘制背景应用于行布局的任何部分(包括整个布局).选中该选项后,它将更改您应用的任何内容.

所有这些都假设您已经设置了带有适配器的ListView.

注意:masterRecord是我的ListView的名称.

这是我的项目长按监听器:

  masterRecord.setOnItemLongClickListener((父,视图,位置,idInDB)-> {//在第一次长按时,它将选择模式设置为多个.masterRecord.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);//selections是一个整数ArrayList.第一个条目只是设置长按的内容//选中,然后将位置添加到数组中.//我正在回收布局(而不是堆砌),所以这也设置了一个已经//现有按钮可以执行某项操作.如果(selections.size()== 0){masterRecord.setItemChecked(position,true);selections.add(position);switchLists.setText(清除选择");switchLists.setOnClickListener(clearSelection);}//如果某人长时间点击了另一个项目(如果尚未选择),//将被选中.否则它将被取消选择.//这也会显示在常规项目点击监听器中.别的如果(!selections.contains(position)){masterRecord.setItemChecked(position,true);selections.add(position);} else if(selections.contains(position)){masterRecord.setItemChecked(position,false);selections.remove(Integer.valueOf(position));//如果手动取消选择所有内容,则下一个if会将所有内容恢复为正常如果(selections.size()== 0){switchLists.setText(按日期查看");switchLists.setOnClickListener(showDateList);masterRecord.setChoiceMode(ListView.CHOICE_MODE_NONE);}}返回true;}); 

接下来是常规的onItemClick()

  masterRecord.setOnItemClickListener((AdapterView<?>父级,查看viewClicked,int位置,长idInDB)-> {//这基本上与长单击侦听器中的代码相同.如果(selections.size()> 0){如果(!selections.contains(position)){masterRecord.setItemChecked(position,true);selections.add(position);} else if(selections.contains(position)){masterRecord.setItemChecked(position,false);selections.remove(Integer.valueOf(position));如果(selections.size()== 0){switchLists.setText(按日期查看");switchLists.setOnClickListener(showDateList);masterRecord.setChoiceMode(ListView.CHOICE_MODE_NONE);}}//return在此处用于停止其他onItemClick的运行,因为它应该//仅当我不尝试多选时才运行.返回;} 

奖金-清除选择按钮:

  View.OnClickListener clearSelection = v->{//一个循环,该循环将遍历选择ArrayList并取消选中所有项目//在列表视图中,然后将其从ArrayList中删除.for(int i = selections.size()-1; i> = 0; i--){masterRecord.setItemChecked(selections.get(i),false);selections.remove(i);}//然后它只是将所有内容都设置回原始状态.switchLists.setText(按日期查看");switchLists.setOnClickListener(showDateList);}; 

I've searched high and low and I'm beginning to think this isn't possible, but I have a custom ListView which is in an inflated layout and put onto a popup window. The lines are made from a layout file using an adapter. Each item of the list is clickable and takes the user to a different list. I want to also make it so that when I long click an item, it selects that item and then allows me to select multiple lines, and then I have a separate button to delete them. To be clear, I don't want a checkbox on each line (there's no room). Just the lines to get highlighted. I'm stuck at the "selects that item" part, let alone the "select multiple lines". I'm going to truncate my code to the relevant parts. Note: masterRecord is the name of the ListView.

private void fillList() {

        int numRows = mainDB.numRowsMaster();

        if (numRows == 0) {
            Toast.makeText(getApplicationContext(), "Nothing to load!", Toast.LENGTH_SHORT).show();
            return;
        }

        cursor = mainDB.getAllRowsMaster();

        startManagingCursor(cursor);

        String[] fromFieldNames = new String[]{DBAdapter.KEY_MASNAMECOL, DBAdapter.KEY_MASLASTDATECOL, DBAdapter.KEY_MASTOTALTIMEASCLOCKCOL};
        int[] toViewIds = new int[]{R.id.rowName, R.id.rowLastDate, R.id.rowTotalTime};

        SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(this, R.layout.master_list_row, cursor, fromFieldNames, toViewIds);

        masterRecord.setAdapter(cursorAdapter);
        masterRecord.setLongClickable(true);

    }

private void listItemClick() {
        masterRecord.setOnItemClickListener((parent, viewClicked, position, idInDB) -> {

//Bunch of code here to make the next listview popup and make a cursor adapter. This all works fine.

        });

        masterRecord.setOnItemLongClickListener((parent, view, position, idInDB) -> {

            Toast.makeText(getApplicationContext(), "Is this working?", Toast.LENGTH_SHORT).show();

            masterRecord.setClickable(false); //This doesn't make a difference even though it's running.
//The items in masterRecord are still clickable. Separate issue that I'm not worried about ATM.
            masterRecord.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
            masterRecord.setMultiChoiceModeListener(new ListView.MultiChoiceModeListener() {
                @Override
                public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
                    Toast.makeText(getApplicationContext(), "Here4", Toast.LENGTH_SHORT).show();
                }

                @Override
                public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                    Toast.makeText(getApplicationContext(), "Here1", Toast.LENGTH_SHORT).show();
                    return false;
                }

                @Override
                public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                    Toast.makeText(getApplicationContext(), "Here3", Toast.LENGTH_SHORT).show();
                    return false;
                }

                @Override
                public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                    Toast.makeText(getApplicationContext(), "Here2", Toast.LENGTH_SHORT).show();
                    return false;
                }

                @Override
                public void onDestroyActionMode(ActionMode mode) {
                    Toast.makeText(getApplicationContext(), "Here5", Toast.LENGTH_SHORT).show();
                }
            });

            return true;
        });
    }

The toasts are just so I can see what's running or not on screen. "Is this working?" is the only thing that shows up when I long press. Nothing gets selected, and if I keep long pressing, it just keeps doing the same thing. If I then short press, it just does the normal short press stuff.

I found the Checkable widget and got all excited, but can't seem to make that work either. The tutorials and other information I've seen have a separate class for the ListView, but that seems like overkill. Is that really the only way to do this? If I missed any relevant code, let me know and I'll edit to include. Thank you.

解决方案

I found the answer in another post (kind of), so I'm going to post what I did here, and link to their answer as well.

Follow this answer for the setup: https://stackoverflow.com/a/25169360/5374362 That includes making a drawable to use on the row layout. Bear in mind that you can apply the drawable background to any part of your row layout (including the whole layout). It will change whatever you apply it to when it's checked.

All of this assumes you already have a ListView set up with an adapter.

Note: masterRecord is the name of my ListView.

Here is my item long click listener:

masterRecord.setOnItemLongClickListener((parent, view, position, idInDB) -> {

//On first long click, it sets the choice mode to multiple.
            masterRecord.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

//selections is an Integer ArrayList. First entry just sets whatever was long clicked to 
//checked, and adds the position into the array.
//I'm recycling layouts (rather than making a bunch), so this also sets an already 
//existing button to do something.
            if (selections.size() == 0) {
                masterRecord.setItemChecked(position, true);
                selections.add(position);
                switchLists.setText("clear selection");
                switchLists.setOnClickListener(clearSelection);
            } 
//In the event someone long clicks on another item, if it's not already selected, it 
//will get selected. Otherwise it will get unselected.
//This also shows up in the regular item click listener.
            else
            if (!selections.contains(position)) {
                masterRecord.setItemChecked(position, true);
                selections.add(position);
            } else if (selections.contains(position)) {
                masterRecord.setItemChecked(position, false);
                selections.remove(Integer.valueOf(position));
//The next if will set everything back to normal if everything is manually deselected
                if (selections.size() == 0) {
                    switchLists.setText("View by date");
                    switchLists.setOnClickListener(showDateList);
                    masterRecord.setChoiceMode(ListView.CHOICE_MODE_NONE);
                }
            }
            return true;
        });

Next is the regular onItemClick()

masterRecord.setOnItemClickListener((AdapterView<?> parent, View viewClicked, int position, long idInDB) -> {

//This is basically the same code as in the long click listener.
            if (selections.size() > 0) {

                if (!selections.contains(position)) {
                    masterRecord.setItemChecked(position, true);
                    selections.add(position);
                } else if (selections.contains(position)) {
                    masterRecord.setItemChecked(position, false);
                    selections.remove(Integer.valueOf(position));
                    if (selections.size() == 0) {
                        switchLists.setText("View by date");
                        switchLists.setOnClickListener(showDateList);
                        masterRecord.setChoiceMode(ListView.CHOICE_MODE_NONE);
                    }
                }
//return is used here to stop the rest of the onItemClick from running, since it should
//only run when I'm not trying to multi-select.
                return;
            }

BONUS - Clear Selection Button:

View.OnClickListener clearSelection = v -> {
//A loop which will run through the selections ArrayList and uncheck all the items
//in the listview, and remove them from the ArrayList.
        for (int i = selections.size()-1; i >= 0; i--) {
            masterRecord.setItemChecked(selections.get(i), false);
            selections.remove(i);
        }
//Then it just sets everything back to original.
        switchLists.setText("View by date");
        switchLists.setOnClickListener(showDateList);
    };

这篇关于Android Java更改ListView以选择多行(用于删除)而没有单独的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆