对于使用我的适配器设置的笔记应用程序,我有一个listview
。列表视图组件由一些textviews
和一个复选框组成,当长按listview
项时,该复选框会弹出删除图标。
当删除图标变为可见时,我会自动从适配器看到checkboxes
,以便用户可以选择要删除的项目。
问题是我想要在长时间点击时自动检查单个列表项。我该怎么做?我的逻辑不起作用。
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>
适配器
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;
}
});
}
答案 0 :(得分:1)
这里的问题是您只从一个持有者设置了 checkBox 的可见性。你的逻辑是正确的,但你还没有改变visibility
checkBoxes
的所有holders
。您必须为持有者创建一个arrayList并使用null项初始化它们。
private ArrayList<View> collectionOfViews = new ArrayList<>();
for (int i = 0; i < objects.size(); i++) {
collectionOfViews.add(null);
}
这是来自适配器的getView()
。另外,要从所有框中存储checkStatus
,请在checkStatus
对象中添加元素Note
。
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();
}
});
}
checkBox的可见性由 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();
}
阅读this文章,这可能会对您有所帮助。我从这里得到了将视图存储在数组中的想法。
我希望这会有所帮助。
答案 1 :(得分:0)
尝试以下代码:
适配器:
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
// }
}
活动:
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());
}
});