Check a list view item from adapter when long clicked

倖福魔咒の 提交于 2019-12-11 07:35:11

问题


I have a listview for a note application set with my adapter. The list view component consists of some textviewsand a checkbox which pops up delete icon when a listviewitem is long clicked. Am automatically making the checkboxes visible from the adapter when the delete icon becomes visible so that the user could select the items he wants to delete.

The problem is i want a single list item to be automatically checked when long clicked. How do i go about this? My logic does not work.

listcomponent.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_marginTop="6dp"
    android:layout_marginLeft="6dp"
    android:layout_marginRight="6dp"
    android:background="#F5F5F5"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <View
        android:id="@+id/verticallineview"
        android:layout_width="4dp"
        android:layout_height="match_parent"
        android:background="@color/toast_color"
        />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:weightSum="1"
        android:orientation="horizontal">
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">
        <TextView
            android:id="@+id/list_note_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=""
            android:padding="1dp"
            android:textStyle="bold"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textColor="@color/light_black" />

        <TextView
            android:id="@+id/list_note_date"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="1dp"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textColor="@color/colorPrimary"
            android:text=""
            />

        <TextView
            android:id="@+id/list_note_content_preview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="1dp"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:text=""
            android:textColor="@color/light_black"
            />
    </LinearLayout>
        <CheckBox
            android:id="@+id/checkbox"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0.2"
            android:layout_marginEnd="5dp"
            android:theme="@style/checkBoxStyle"
            android:visibility="gone"
            android:gravity="center"
            android:layout_gravity="center"
            android:layout_marginRight="5dp" />
    </LinearLayout>
</LinearLayout>

Adapter

   class NoteListAdapter extends ArrayAdapter<Note>{
private List<Note> objects;
private List<Note> originalList = new ArrayList<>();
boolean isLongPressed;
//    boolean isChecked;
boolean[] isChecked;
private boolean isItemsChecked;

NoteListAdapter(Context context, int resource, List<Note> objects) {
    super(context, resource, objects);
    this.objects = objects;
    this.originalList.addAll(objects);
    isLongPressed = false;
//        isChecked = false;
    isChecked = new boolean[objects.size()];
    for(int i=0; i<isChecked.length; i++) isChecked[i] = false;
}

@Override
public int getCount() {
    return objects.size();
}

@Nullable
@Override
public Note getItem(int position) {
    return objects.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_component, parent, false);
    }

    Note note = getItem(position);
    if (note != null) {
        TextView title = convertView.findViewById(R.id.list_note_title);
        TextView content = convertView.findViewById(R.id.list_note_content_preview);
        TextView date = convertView.findViewById(R.id.list_note_date);
        // setting checkbox logic on the adapter
        CheckBox checkBox = convertView.findViewById(R.id.checkbox);
// now i wanna toggle checked items from a checkbox on my header
  if (isItemsChecked) {
                checkBox.setChecked(true);
            } else {
                checkBox.setChecked(false);
            }
        if (isLongPressed) {
            checkBox.setVisibility(View.VISIBLE);
        } else {
            checkBox.setVisibility(View.GONE);
        }
        // also handle checks for all list view items
        checkBox.setChecked(isChecked[position]);
        checkBox.setTag(position);
        checkBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                CheckBox cb = (CheckBox) v;
                int checkedPosition = (int)cb.getTag();
                isChecked[checkedPosition] = cb.isChecked();
                notifyDataSetChanged();
            }
        });
    }
    return convertView;
}

void showCheckbox(int clickedPosition) {
    isLongPressed = true;
    for(int i=0; i<isChecked.length; i++) isChecked[i] = false;
    isChecked[clickedPosition] = true;
    notifyDataSetChanged();  // Required for update
}

void removeCheckbox() {
    isLongPressed = false;
    notifyDataSetChanged();  // Required for update
}

 void Check() {
      isItemsChecked = true;
        notifyDataSetChanged();  // Required for update
    }
    void Uncheck() {
        isItemsChecked = false;
        notifyDataSetChanged();  // Required for update
    }

NoteActivity.java

  private void listViewLongClick() {
            mListNotes.setLongClickable(true);
            mListNotes.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
    // universal button controls all checked items
                 Checkbox  universalCheckBox = findViewById(R.id.check_all);
                universalCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked){
    na.Check();
} else {
    na.Uncheck();
}
                    }
                });
                    mDeleteButton = findViewById(R.id.delete_icon);
                   na.showCheckbox();
                    deleteButtonIn();
                    return true;
                }
            });
        }

回答1:


Try the code below:

Adapter:

class NoteListAdapter extends ArrayAdapter<Note>{
private List<Note> objects;
private List<Note> originalList = new ArrayList<>();
boolean isLongPressed;
//    boolean isChecked;
boolean[] isChecked;

NoteListAdapter(Context context, int resource, List<Note> objects) {
    super(context, resource, objects);
    this.objects = objects;
    this.originalList.addAll(objects);
    isLongPressed = false;
//        isChecked = false;
    isChecked = new boolean[objects.size()];
    for(int i=0; i<isChecked.length; i++) isChecked[i] = false;
}

@Override
public int getCount() {
    return objects.size();
}

@Nullable
@Override
public Note getItem(int position) {
    return objects.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_component, parent, false);
    }

    Note note = getItem(position);
    if (note != null) {
        TextView title = convertView.findViewById(R.id.list_note_title);
        TextView content = convertView.findViewById(R.id.list_note_content_preview);
        TextView date = convertView.findViewById(R.id.list_note_date);
        // setting checkbox logic on the adapter
        CheckBox checkBox = convertView.findViewById(R.id.checkbox);
        // now i wanna toggle checked items from a checkbox on my header
 //  if (isItemsChecked) {
 //           checkBox.setChecked(true);
 //       } else {
 //           checkBox.setChecked(false);
 //       }
        if (isLongPressed) {
            checkBox.setVisibility(View.VISIBLE);
        } else {
            checkBox.setVisibility(View.GONE);
        }
        // also handle checks for all list view items
        checkBox.setChecked(isChecked[position]);
        checkBox.setTag(position);
        checkBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                CheckBox cb = (CheckBox) v;
                int checkedPosition = (int)cb.getTag();
                isChecked[checkedPosition] = cb.isChecked();
                notifyDataSetChanged();
            }
        });
    }
    return convertView;
}

void showCheckbox(int clickedPosition) {
    isLongPressed = true;
    for(int i=0; i<isChecked.length; i++) isChecked[i] = false;
    isChecked[clickedPosition] = true;
    notifyDataSetChanged();  // Required for update
}

void removeCheckbox() {
    isLongPressed = false;
    notifyDataSetChanged();  // Required for update
}

void checkboxAllChange(boolean state) {
    isLongPressed = true;
    for(int i=0; i<isChecked.length; i++) isChecked[i] = state;
    notifyDataSetChanged();  // Required for update
}

//    void Check() {
//        isChecked = true;
//        notifyDataSetChanged();  // Required for update
//    }
//    void Uncheck() {
//        isChecked = false;
//        notifyDataSetChanged();  // Required for update
//    }

}

In Activity:

    mListNotes.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
            deleteButtonIn();
            na.showCheckBox(position);
            return true;
        }
    });
    Checkbox  universalCheckBox = findViewById(R.id.check_all);
    universalCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            na.checkboxAllChange(buttonView.isChecked());
        }
    });



回答2:


The problem here is you have set the visibility of the checkBox from only one holder. Your logic is right but you haven't changed the visibility of checkBoxes from all the holders. You have to create a arrayList for holders and initialize them with null items.

private ArrayList<View> collectionOfViews = new ArrayList<>();
for (int i = 0; i < objects.size(); i++) {
   collectionOfViews.add(null);
}

This is my getView() from the adapter. Also to store checkStatus from all the boxes add a element checkStatus in your Note object.

if (note != null) {
        final TextView textView = convertView.findViewById(R.id.textView);
        final CheckBox checkBox = convertView.findViewById(R.id.checkBox);              
        checkBox.setChecked(note.getCheckStatus());
        textView.setText(note.getTextView());
        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (checkBox.getVisibility() != View.GONE) {
                    note.changeCheckStatus();
                    checkBox.setChecked(note.getCheckStatus());
                }
            }
        });
        checkBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                note.changeCheckStatus();
                checkBox.setChecked(note.getCheckStatus());
            }
        });
        //setting holder in your array
        collectionOfViews.set(position, convertView);
        convertView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                note.changeCheckStatus();
                checkBox.setChecked(note.getCheckStatus());
                return true;
            }
        });
        checkBoxStatus();
        checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                checkBoxStatus();
            }
        });
}

The visibility of the checkBox is handled from checkBoxStatus()

void checkBoxStatus(){
    int count = 0;
    for (Note noteCheck : mData) {
        if (!noteCheck.getCheckStatus()) {
            count++;
        }
    }
    if (count == mData.size()) {
        for (View view : collectionOfViews) {
            if (view != null) {
                CheckBox checkBoxInside = view.findViewById(R.id.checkBox);
                checkBoxInside.setVisibility(View.GONE);
            }
        }
    }else{
        for (View view : collectionOfViews) {
            if (view != null) {
                CheckBox checkBoxInside = view.findViewById(R.id.checkBox);
                checkBoxInside.setVisibility(View.VISIBLE);
            }
        }
    }
    notifyDataSetChanged();
}

Read this article this may help you. I got this idea of storing views in array from here.

I hope this helps.



来源:https://stackoverflow.com/questions/48664207/check-a-list-view-item-from-adapter-when-long-clicked

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!