Android 如何突出显示或选中选定的列表项

Android 如何突出显示或选中选定的列表项,android,listview,gridview,contextual-action-bar,multichoiceitems,Android,Listview,Gridview,Contextual Action Bar,Multichoiceitems,我应该如何实现Java或XML代码,以便在Android中以多选模式突出显示(或显示复选框)列表行或网格项,以便与上下文操作栏一起使用 我已经实现了上下文操作栏和ListView/GridView,我可以选择它们并在所选项目上运行函数,但除了长时间单击列表行/项目时短暂高亮显示列表行/项目外,没有任何视觉反馈,当列表行/项目被释放时,这些信息会消失 我的第一个想法是在适配器中设置行/项的背景色,但我似乎无法让它工作。我还尝试了这个问题的公认答案所建议的解决方案:但它对我的ListView和Gri

我应该如何实现Java或XML代码,以便在Android中以多选模式突出显示(或显示复选框)列表行或网格项,以便与上下文操作栏一起使用

我已经实现了上下文操作栏和ListView/GridView,我可以选择它们并在所选项目上运行函数,但除了长时间单击列表行/项目时短暂高亮显示列表行/项目外,没有任何视觉反馈,当列表行/项目被释放时,这些信息会消失

我的第一个想法是在适配器中设置行/项的背景色,但我似乎无法让它工作。我还尝试了这个问题的公认答案所建议的解决方案:但它对我的ListView和GridView的行为没有任何影响


我最感兴趣的是,根据材料设计指南和/或最常用的方法,了解进行此操作的标准方法。提前感谢您提供的任何建议或解决方案

编辑

我尝试了Redman的答案(事实上与之类似,因为我使用的是情境动作模式和多选听众),但没有得到任何结果。以下是我在listener中所做的:

public void onItemCheckedStateChanged(ActionMode actionMode, int i, long id, boolean checked) {
            if (checked) {
                selectedItems.add(listAdapter.getItem(i));
                ((CheckBox) listAdapter.getView(i,null,listView).findViewById(R.id.listCheckBox)).setChecked(true);
            }
            else {
                selectedItems.remove(listAdapter.getItem(i));
                ((CheckBox) listAdapter.getView(i,null,listView).findViewById(R.id.listCheckBox)).setChecked(false);
            }
        }

它运行时没有错误,但对复选框没有任何作用,因此我不确定问题出在哪里。非常感谢您的帮助。

您可以通过以下方式在listview中使用multiselection显示复选框

在列表子xml中添加复选框,并在xml中将其设置为clickable false

 android:clickable="false"
对于您的列表,请保存此列表

 ArrayList<Integer> listPositionsSaveArray= new ArrayList<Integer>(); 

  listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                    CheckBox presentCheckBox=(CheckBox)view.findViewById(R.id.checkbox__list);

                    if(presentCheckBox.isChecked()){
                          presentCheckBox.setChecked(false);
                          listPositionsSaveArray.removeAll(Arrays.asList(position+1));
                    }
                    else{
                    presentCheckBox.setChecked(true);
                    listPositionsSaveArray.add(position+1);
                    }


            }
        });
ArrayList listPositionsSaveArray=new ArrayList();
setOnItemClickListener(新的AdapterView.OnItemClickListener(){
@凌驾
public void onItemClick(AdapterView父对象、视图、整型位置、长id){
CheckBox presentCheckBox=(CheckBox)view.findViewById(R.id.CheckBox\u列表);
if(presentCheckBox.isChecked()){
presentCheckBox.setChecked(false);
listPositionsSaveArray.removeAll(Arrays.asList(位置+1));
}
否则{
presentCheckBox.setChecked(true);
listPositionsSaveArray.add(位置+1);
}
}
});

列表视图的所有选定位置现在都将位于
listpositionsavearray
。在布局文件中,在
列表视图中使用以下属性:

android:choiceMode="singleChoice"
android:listSelector="#666666"
如果要以编程方式执行,请尝试以下操作:

listView.setSelector(Drawable selector)

listView.setSelector(int resourceId)

listview.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
如果需要多选,请使用
AbsListView.CHOICE\u MODE\u multiple

“我最感兴趣的是了解根据材料设计指南进行此操作的标准方法和/或最常用的方法。”

我不确定我的答案是材料设计还是普通,但我已经在谷歌“照片”应用程序中完成了基于处理选择的GridView。我已经测试过它,知道它将包括一个突出显示的边框和一个“复选框”

**免责声明**

我曾考虑过使用选择器,但如果视图滚动,似乎会出现问题(请参阅)。此外,我还使用了一个自定义复选框(实际上只是两个不同的绘图项),部分原因是。而且,这个答案基本上就是在纵向模式下处理手机。需要添加更多以处理不同的配置(屏幕大小、方向等)

这里有很多,但就像我说的,我已经测试过了。整个项目已发布到

1、在MainActivity onCreate()中

这里是GridItem类的核心,省略了getter和setter

public class GridItem {

    private BitmapDrawable bitmap = null;
    private boolean isSelected = false;

    public GridItem(BitmapDrawable bitmap) {
        this.bitmap = bitmap;
    }
}
Java就是这样。现在来看一些xml

grid_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/colorAccent"
    >
    <FrameLayout
        android:layout_width="140dp"
        android:layout_height="140dp"
        android:id="@+id/image_frame"
        >
        <!-- view for the main image -->
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:scaleType="center"
            android:background="@android:color/white"
            android:id="@+id/image_view"
            />
    </FrameLayout>

    <!-- view for the 'checkbox' in upper left corner -->
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="2dp"
        android:src="@drawable/custom_check_box_unselected"
        android:id="@+id/custom_check_box"
        />
</RelativeLayout>

这将放在content\u main.xml或activity\u main.xml中,等等

<GridView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:numColumns="2"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="20dp"
    android:stretchMode="columnWidth"
    android:gravity="center"
    android:id="@+id/grid_view"
    >
</GridView>

现在为您的可绘制文件夹创建2个文件

自定义\u复选框\u unselected.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="20dp"
    android:width="20dp"

    android:viewportWidth="400"
    android:viewportHeight="400">

    <!-- the outside box -->
    <!-- top line & top left corner -->
    <path android:pathData="M 340 30 H 62 c -20 0 -35 15 -35 35 "
        android:strokeColor="#000000" android:strokeWidth="20" />

    <!-- left line & bottom left corner -->
    <path android:pathData="M 27 64 v271 c0 20 15 35 35 35 "
        android:strokeColor="#000000" android:strokeWidth="20" />

    <!-- bottom line & bottom right corner -->
    <path android:pathData="M 60 370 h275 c20 0 35 -15 35 -35"
        android:strokeColor="#000000" android:strokeWidth="20" />

    <!-- right line & top right corner -->
    <path android:pathData="M 370 336 v -271 c0 -20 -15 -35 -35  -35"
        android:strokeColor="#000000" android:strokeWidth="20" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="20dp"
    android:width="20dp"

    android:viewportWidth="400"
    android:viewportHeight="400">

    <!-- the outside box -->
    <path android:pathData="M 340 30 H 62 c -20 0 -35 15 -35 35
            v271 c0 20 15 35 35 35
            h275 c20 0 35 -15 35 -35
            v -271 c0 -20 -15 -35 -35  -35 "
        android:fillColor="#FDD835"  android:strokeColor="#000000" android:strokeWidth="20" />

    <!-- the check mark -->
    <path android:pathData="M 140 320 l -100 -100 25 -30
            l 75 75 l 190 -190
            l 25 30 l -190 190"
        android:fillColor="#000000"  android:strokeColor="#000000" android:strokeWidth="2" />
</vector>

自定义\u复选框\u selected.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="20dp"
    android:width="20dp"

    android:viewportWidth="400"
    android:viewportHeight="400">

    <!-- the outside box -->
    <!-- top line & top left corner -->
    <path android:pathData="M 340 30 H 62 c -20 0 -35 15 -35 35 "
        android:strokeColor="#000000" android:strokeWidth="20" />

    <!-- left line & bottom left corner -->
    <path android:pathData="M 27 64 v271 c0 20 15 35 35 35 "
        android:strokeColor="#000000" android:strokeWidth="20" />

    <!-- bottom line & bottom right corner -->
    <path android:pathData="M 60 370 h275 c20 0 35 -15 35 -35"
        android:strokeColor="#000000" android:strokeWidth="20" />

    <!-- right line & top right corner -->
    <path android:pathData="M 370 336 v -271 c0 -20 -15 -35 -35  -35"
        android:strokeColor="#000000" android:strokeWidth="20" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="20dp"
    android:width="20dp"

    android:viewportWidth="400"
    android:viewportHeight="400">

    <!-- the outside box -->
    <path android:pathData="M 340 30 H 62 c -20 0 -35 15 -35 35
            v271 c0 20 15 35 35 35
            h275 c20 0 35 -15 35 -35
            v -271 c0 -20 -15 -35 -35  -35 "
        android:fillColor="#FDD835"  android:strokeColor="#000000" android:strokeWidth="20" />

    <!-- the check mark -->
    <path android:pathData="M 140 320 l -100 -100 25 -30
            l 75 75 l 190 -190
            l 25 30 l -190 190"
        android:fillColor="#000000"  android:strokeColor="#000000" android:strokeWidth="2" />
</vector>

根据我的理解,当用户选中该复选框时,您希望更改listview行的颜色

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

        for (int j = 0; j < adapterView.getChildCount(); j++)
            adapterView.getChildAt(j).setBackgroundColor(Color.TRANSPARENT);

        // change the background color of the selected element
        view.setBackgroundColor(Color.LTGRAY);
});
listView.setOnItemClickListener(新的AdapterView.OnItemClickListener(){
@凌驾
公共无效onItemClick(AdapterView AdapterView、View视图、int i、long l){
对于(int j=0;j

您可以使用您的逻辑根据您的要求实现此颜色更改,您需要多种选择型号、适配器。因此,您必须创建customlistview。我在下面给出了一个示例。您只需替换MarkAttention_细节(TextView)若要选中复选框,若“P”设置复选框,则选中“else”。若您在这方面遇到任何问题,请告诉我

Adaper类-->

模型应该是这样-->

活动应该是这样-->

公共课堂出勤\u页面扩展AppCompative活动{
列表视图列表视图;
注意力模型;
AttendanceAdapter AttendanceAdapter;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u atendance\u页面);
listView=(listView)findViewById(R.id.attendancepage\u列表\u视图);
attendanceAdapter=新的attendanceAdapter(getApplicationContext(),R.layout.attendance\u列表);
setAdapter(attendanceAdapter);

for(int i=1;ilistview有一个属性app:selector。请尝试使用它,为此,您必须在可绘图文件夹中创建一个xml文件,其中包含选定的true或默认为false属性,您可以在其中分配colors@Mohammad你能给我们提供预期的屏幕截图和当前的工作屏幕吗
public class AttendanceAdapter extends ArrayAdapter {

    List list = new ArrayList();

    static class DataHolder {
        TextView rollNo_detail,studentName_detail,markAttendance_detail;
    }

    public AttendanceAdapter(Context context, int resource) {
        super(context, resource);
    }
    @Override
    public void add(Object object) {
        super.add(object);
        list.add(object);
    }
    @Override
    public int getCount() {
        return this.list.size();
    }

    @Override
    public Object getItem(int position) {
        return this.list.get(position);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row;
        row = convertView;
        final DataHolder dataHolder;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.attendance_list, parent, false);
            dataHolder = new DataHolder();

            dataHolder.rollNo_detail=(TextView)row.findViewById(R.id.student_rollno);
            dataHolder.studentName_detail=(TextView)row.findViewById(R.id.student_name);
            dataHolder.markAttendance_detail=(TextView)row.findViewById(R.id.mark_attendance);
            dataHolder.markAttendance_detail.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    AttendanceModel model=(AttendanceModel) dataHolder.markAttendance_detail.getTag();
                    String att=model.getAttendance().toString();
                    if (model.isSelected()==false){
                        model.setSelected(true);
                        dataHolder.markAttendance_detail.setText("P");
                    }else if (model.isSelected()==true){
                        model.setSelected(false);
                        dataHolder.markAttendance_detail.setText("A");
                    }
                }

            });
            row.setTag(dataHolder);
            dataHolder.markAttendance_detail.setTag(list.get(position));

        }
        else {
            dataHolder = (DataHolder) row.getTag();
            ((DataHolder) row.getTag()).markAttendance_detail.setTag(list.get(position));

        }
        AttendanceModel model = (AttendanceModel) this.getItem(position);

        dataHolder.rollNo_detail.setText(model.getRoll_no());
        dataHolder.studentName_detail.setText(model.getStudent_name());
        if (model.isSelected()==true){
           dataHolder.markAttendance_detail.setText("P");
       }else if (model.isSelected()==false){
            dataHolder.markAttendance_detail.setText("A");
        }
        return row;
    }
public class AttendanceModel {
    private String roll_no;
    private String student_name;
    private String attendance;
    private boolean selected;
    public AttendanceModel(String roll_no,String student_name,String attendance){
        this.roll_no=roll_no;
        this.selected=true;
        this.student_name=student_name;
        this.attendance=attendance;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    public String getRoll_no() {
        return roll_no;
    }

    public void setRoll_no(String roll_no) {
        this.roll_no = roll_no;
    }

    public String getStudent_name() {
        return student_name;
    }

    public void setStudent_name(String student_name) {
        this.student_name = student_name;
    }

    public String getAttendance() {
        return attendance;
    }

    public void setAttendance(String attendance) {
        this.attendance = attendance;
    }
}
public class Attendance_Page extends AppCompatActivity {
    ListView listView;
   AttendanceModel model;
    AttendanceAdapter attendanceAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_atendance_page);
        listView= (ListView) findViewById(R.id.attendancepage_list_view);
    attendanceAdapter=new AttendanceAdapter(getApplicationContext(),R.layout.attendance_list);
       listView.setAdapter(attendanceAdapter);
        for (int i=1;i<=10;i++){
            model=new AttendanceModel("1","Aryan","P");
            attendanceAdapter.add(model);
        }
    }
}