长按时检查适配器中的列表视图项

时间:2018-02-07 12:46:12

标签: java android listview android-adapter

对于使用我的适配器设置的笔记应用程序,我有一个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;
                }
            });
        }

2 个答案:

答案 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());
        }
    });