如何在recyclerview中执行多选?

时间:2016-07-29 03:37:32

标签: android android-recyclerview personalization

我正在创建一个具有个性化功能的应用,用户可以根据该应用选择他的偏好并显示数据。在点击项目时应该选择它(突出显示项目边框)并重新点击它应该是未选中的,还应该在recyclerview中进行多项选择。这是我的应用程序个性化屏幕的屏幕截图

enter image description here

4 个答案:

答案 0 :(得分:4)

添加到sonnv1368的答案:

试试这个:

在模型类对象中创建一个布尔值,以跟踪imageview的选择:例如boolean isSelected;

int maxIndex = gridPane.getChildren().stream().mapToInt(n -> {
    Integer row = GridPane.getRowIndex(n);
    Integer rowSpan = GridPane.getRowSpan(n);

    // default values are 0 / 1 respecively
    return (row == null ? 0 : row) + (rowSpan == null ? 0 : rowSpan - 1);
}).max().orElse(-1);

// add nodes after last row
gridPane.addRow(maxIndex+1, node1, node2, ...);

答案 1 :(得分:3)

使用此选项在recyclerview中选择多行,并使用actionmode删除。

SelectableAdapter.class

public abstract class SelectableAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
@SuppressWarnings("unused")
private static final String TAG = SelectableAdapter.class.getSimpleName();

private SparseBooleanArray selectedItems;

public SelectableAdapter() {
    selectedItems = new SparseBooleanArray();
}

/**
 * Indicates if the item at position position is selected
 * @param position Position of the item to check
 * @return true if the item is selected, false otherwise
 */
public boolean isSelected(int position) {
    return getSelectedItems().contains(position);
}

/**
 * Toggle the selection status of the item at a given position
 * @param position Position of the item to toggle the selection status for
 */
public void toggleSelection(int position) {
    if (selectedItems.get(position, false)) {
        selectedItems.delete(position);
    } else {
        selectedItems.put(position, true);
    }
    notifyItemChanged(position);
}

/**
 * Clear the selection status for all items
 */
public void clearSelection() {
    List<Integer> selection = getSelectedItems();
    selectedItems.clear();
    for (Integer i : selection) {
        notifyItemChanged(i);
    }
}

/**
 * Count the selected items
 * @return Selected items count
 */
public int getSelectedItemCount() {
    return selectedItems.size();
}

/**
 * Indicates the list of selected items
 * @return List of selected items ids
 */
public List<Integer> getSelectedItems() {
    List<Integer> items = new ArrayList<>(selectedItems.size());
    for (int i = 0; i < selectedItems.size(); ++i) {
        items.add(selectedItems.keyAt(i));
    }
    return items;
}
}

Item.class

public class Item {

private String title;

public Item(String title){
    this.title=title;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}
}

Adapter.class

public class Adapter extends SelectableAdapter<Adapter.ViewHolder> {
@SuppressWarnings("unused")
private static final String TAG = Adapter.class.getSimpleName();
private static final int ITEM_COUNT = 50;
private List<Item> items;

private ViewHolder.ClickListener clickListener;

public Adapter(ViewHolder.ClickListener clickListener) {
    super();

    this.clickListener = clickListener;

    items = new ArrayList<>();
    for (int i = 0; i < ITEM_COUNT; ++i) {
        items.add(new Item("Item " + i));
    }
}

public void removeItem(int position) {
    items.remove(position);
    notifyItemRemoved(position);
}

public void removeItems(List<Integer> positions) {
    // Reverse-sort the list
    Collections.sort(positions, new Comparator<Integer>() {
        @Override
        public int compare(Integer lhs, Integer rhs) {
            return rhs - lhs;
        }
    });

    // Split the list in ranges
    while (!positions.isEmpty()) {
        if (positions.size() == 1) {
            removeItem(positions.get(0));
            positions.remove(0);
        } else {
            int count = 1;
            while (positions.size() > count && positions.get(count).equals(positions.get(count - 1) - 1)) {
                ++count;
            }

            if (count == 1) {
                removeItem(positions.get(0));
            } else {
                removeRange(positions.get(count - 1), count);
            }

            for (int i = 0; i < count; ++i) {
                positions.remove(0);
            }
        }
    }
}

private void removeRange(int positionStart, int itemCount) {
    for (int i = 0; i < itemCount; ++i) {
        items.remove(positionStart);
    }
    notifyItemRangeRemoved(positionStart, itemCount);
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_card, parent, false);
    return new ViewHolder(v, clickListener);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    final Item item = items.get(position);

    holder.title.setText(item.getTitle());

    // Highlight the item if it's selected
    holder.selectedOverlay.setVisibility(isSelected(position) ? View.VISIBLE : View.INVISIBLE);
}

@Override
public int getItemCount() {
    return items.size();
}


public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
        View.OnLongClickListener {
    @SuppressWarnings("unused")
    private static final String TAG = ViewHolder.class.getSimpleName();

    TextView title;
    TextView subtitle;
    View selectedOverlay;

    private ClickListener listener;

    public ViewHolder(View itemView, ClickListener listener) {
        super(itemView);

        title = (TextView) itemView.findViewById(R.id.textView);
        selectedOverlay = (View)itemView.findViewById(R.id.selectedOverlay);

        this.listener = listener;

        itemView.setOnClickListener(this);
        itemView.setOnLongClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (listener != null) {
            listener.onItemClicked(getLayoutPosition());
        }
    }

    @Override
    public boolean onLongClick(View v) {
        if (listener != null) {
            return listener.onItemLongClicked(getLayoutPosition());
        }

        return false;
    }

    public interface ClickListener {
         void onItemClicked(int position);
         boolean onItemLongClicked(int position);
    }
}

}

MainActivity.class

public class MainActivity extends AppCompatActivity implements Adapter.ViewHolder.ClickListener {

@SuppressWarnings("unused")
private static final String TAG = MainActivity.class.getSimpleName();

private Adapter adapter;
private ActionModeCallback actionModeCallback = new ActionModeCallback();
private ActionMode actionMode;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    adapter = new Adapter(this);

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    recyclerView.setAdapter(adapter);
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.setLayoutManager(new GridLayoutManager(this,3));
}

@Override
public void onItemClicked(int position) {
    if (actionMode != null) {
        toggleSelection(position);
    } else {
        //adapter.removeItem(position);
    }
}

@Override
public boolean onItemLongClicked(int position) {
    if (actionMode == null) {
        actionMode = startSupportActionMode(actionModeCallback);
    }

    toggleSelection(position);

    return true;
}

/**
 * Toggle the selection state of an item.
 *
 * If the item was the last one in the selection and is unselected, the selection is stopped.
 * Note that the selection must already be started (actionMode must not be null).
 *
 * @param position Position of the item to toggle the selection state
 */
private void toggleSelection(int position) {
    adapter.toggleSelection(position);
    int count = adapter.getSelectedItemCount();

    if (count == 0) {
        actionMode.finish();
    } else {
        actionMode.setTitle(String.valueOf(count));
        actionMode.invalidate();
    }
}

private class ActionModeCallback implements ActionMode.Callback {
    @SuppressWarnings("unused")
    private final String TAG = ActionModeCallback.class.getSimpleName();

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        mode.getMenuInflater().inflate (R.menu.toolbar_menu, menu);
        return true;
    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false;
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_delete:
                adapter.removeItems(adapter.getSelectedItems());
                mode.finish();
                return true;

            default:
                return false;
        }
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        adapter.clearSelection();
        actionMode = null;
    }
}
}

item_card.xml

<?xml version="1.0" encoding="utf-8"?>

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:foreground="?android:attr/selectableItemBackground"
app:cardUseCompatPadding="true">

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:id="@+id/textView"
    android:padding="7dp"
    android:text="sample"/>

 </LinearLayout>

 <View
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:visibility="invisible"
    android:id="@+id/selectedOverlay"
    android:background="@color/transparent"/>

 </android.support.v7.widget.CardView>

答案 2 :(得分:2)

  • 使用与isSelected (boolean)合作的Object上的字段recyclerview
  • Adapter课程中,使用onBindViewHolder方法:将setOnClickListener用于显示头像的ImageView。当用户点击时,更改对象的isSelected并设置imageView的背景isSelected true false

答案 3 :(得分:0)

这与您要查找的内容有点相似,尝试使用DragSelectRecyclerView它会对您有用,并且对于边框突出显示创建一个选择器。

<div class="container">
  <div class="row visit-redeem text-center">
    <h5>Visit Site To Redeem</h5>
  </div>
  <div class="row">
  <div class="col-xs-6 survey-extra">
    <h5>FROM OUR SPONSORS</h5>
    <span class="money-extra">$0.00</span>
  </div>

  <div class="col-xs-6 survey-extra">
    <h5>FREEBIES</h5>
    <span class="money-extra">$0.00</span>
  </div>
</div>
</div>

你也可以这样使用

http://www.grokkingandroid.com/statelistdrawables-for-recyclerview-selection/

http://bignerdranch.github.io/recyclerview-multiselect/