Google 相册风格的RecyclerView多选效果: drag-select-recyclerview

简介:
Google 相册风格的RecyclerView多选效果,手指滑动所到之处都被选中。不过与谷歌相册的差距是一次只能选择一屏的item。

Gradle依赖 

 build.gradle 文件: 

repositories {
    // ...
    maven { url "https://jitpack.io" }
}
 
dependencies {
    // ...
    compile('com.afollestad:drag-select-recyclerview:0.1.0@aar') {
        transitive = true
    }
}

介绍 

本库主要的两个类是DragSelectRecyclerView和DragSelectRecyclerViewAdapter。两个一起工作为你提供需要的功能。 

DragSelectRecyclerView 

DragSelectRecyclerView取代你通常在布局中使用的RecyclerView。它拦截触摸事件判断选择模式是否处于激活状态,然后自动向你的adapter报告。 

<com.afollestad.dragselectrecyclerview.DragSelectRecyclerView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical" />

设置基本上和普通RecyclerView一样。你必须为他设置一个LayoutManager与RecyclerView.Adapter: 

DragSelectRecyclerView list = (DragSelectRecyclerView) findViewById(R.id.list);
list.setLayoutManager(new GridLayoutManager(this, 3));
list.setAdapter(adapter);

这里最主要的区别就是 setAdapter()里面放入的东西,它不能是普通的RecyclerView.Adapter,必须是DragSelectRecyclerViewAdapter的子类。下面将会讨论。 

DragSelectRecyclerViewAdapter 

DragSelectRecyclerViewAdapter是一个DragSelectRecyclerView可以与之交互的RecyclerView.Adapter 的子类。它跟踪被选中的索引-让你可以改变它们,清除它们,监听它们的变化以及检查某个索引是否被选中。 

最基本的adapter实现如下: 

public class MainAdapter extends DragSelectRecyclerViewAdapter<MainAdapter.MainViewHolder>
        implements View.OnClickListener, View.OnLongClickListener {
 
    // Receives View.OnClickListener set in onBindViewHolder(), tag contains index
    @Override
    public void onClick(View v) {
        if (v.getTag() != null) {
            int index = (int) v.getTag();
            // Forwards to the adapter's constructor callback
            if (mCallback != null) mCallback.onClick(index);
        }
    }
 
    // Receives View.OnLongClickListener set in onBindViewHolder(), tag contains index
    @Override
    public boolean onLongClick(View v) {
        if (v.getTag() != null) {
            int index = (int) v.getTag();
            // Forwards to the adapter's constructor callback
            if (mCallback != null) mCallback.onLongClick(index);
            return true;
        }
        return false;
    }
 
    public interface ClickListener {
        void onClick(int index);
 
        void onLongClick(int index);
    }
 
    private final ClickListener mCallback;
 
 
    // Constructor takes click listener callback
    protected MainAdapter(ClickListener callback) {
        super();
        mCallback = callback;
    }
 
    @Override
    public MainViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.griditem_main, parent, false);
        return new MainViewHolder(v);
    }
 
    @Override
    public void onBindViewHolder(MainViewHolder holder, int position) {
        // Sets position + 1 to a label view
        holder.label.setText(String.format("%d", position + 1));
 
        if (isIndexSelected(position)) {
            // Item is selected, change it somehow 
        } else {
            // Item is not selected, reset it to a non-selected state
        }
 
        // Tag is used to retrieve index from the click/long-click listeners
        holder.itemView.setTag(position);
        holder.itemView.setOnClickListener(this);
        holder.itemView.setOnLongClickListener(this);
    }
 
    @Override
    public int getItemCount() {
        return 60;
    }
 
    public class MainViewHolder extends RecyclerView.ViewHolder {
 
        public final TextView label;
 
        public MainViewHolder(View itemView) {
            super(itemView);
            this.label = (TextView) itemView.findViewById(R.id.label);
        }
    }
}


You choose what to do when an item is selected (in onBindViewHolder). isIndexSelected(int)returns true or false. The click listener implementation used here will aid in the next section. 

你自己选择在一个item被选择(在onBindViewHolder中)的时候做什么。 


用户激活 

除非你告诉library,否则它不会启用选择模式。用户要能够自己激活它,上面adapter中click listener的实现可以帮助你做到这点。 

public class MainActivity extends AppCompatActivity implements
        MainAdapter.ClickListener, DragSelectRecyclerViewAdapter.SelectionListener {
 
    private DragSelectRecyclerView mList;
    private MainAdapter mAdapter;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        // Setup adapter and callbacks
        mAdapter = new MainAdapter(this);
        // Listen for selection changes to update indicators
        mAdapter.setSelectionListener(this);
        // Restore selected indices after Activity recreation
        mAdapter.restoreInstanceState(savedInstanceState);
 
        // Setup the RecyclerView
        mList = (DragSelectRecyclerView) findViewById(R.id.list);
        mList.setLayoutManager(new GridLayoutManager(this, getResources().getInteger(R.integer.grid_width)));
        mList.setAdapter(mAdapter);
    }
 
    @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
        // Save selected indices to be restored after recreation
        mAdapter.saveInstanceState(outState);
    }
 
    @Override
    public void onClick(int index) {
        // Single click will select or deselect an item
        mAdapter.toggleSelected(index);
    }
 
    @Override
    public void onLongClick(int index) {
        // Long click initializes drag selection, and selects the initial item
        mList.setDragSelectActive(true, index);
    }
 
    @Override
    public void onDragSelectionChanged(int count) {
        // TODO Selection was changed, updating an indicator, e.g. a Toolbar or contextual action bar
    }
}

DragSelectRecyclerViewAdapter包含了许多可以帮助你的方法! 

// Clears all selected indices
adapter.clearSelected();
 
// Sets an index as selected (true) or unselected (false);
adapter.setSelected(index, true);
 
// If an index is selected, unselect it. Otherwise select it. Returns new selection state.
boolean selectedNow = adapter.toggleSelected(index);
 
// Gets the number of selected indices
int count = adapter.getSelectedCount();
 
// Gets all selected indices
Integer[] selectedItems = adapter.getSelectedIndices();
 
// Checks if an index is selected, useful in adapter subclass
boolean selected = adapter.isIndexSelected(index);
 
// Sets a listener that's notified of selection changes, used in the section above
adapter.setSelectionListener(listener);
 
// Used in section above, saves selected indices to Bundle
adapter.saveInstanceState(outState);
 
// Used in section above, restores selected indices from Bundle
adapter.restoreInstanceState(inState);


项目主页:http://www.open-open.com/lib/view/home/1446619651232


相关文章
|
Web App开发 JavaScript iOS开发
仿Google+相册的动画
在使用Google+的时候,查看某一相册,会经常看到,如下图所示的动画效果。 鼠标移入、移出时均有动画效果,咋一看估计是使用了css3的transform属性来实现动画效果的。 在网上搜索“Google+ 相册 效果”的时候发现有人使用CSS3做了这样的效果,不过使用调试工具查看节点元素的时候,我觉得它是使用JS在进行的控制。
674 0
|
3月前
|
数据可视化 定位技术 Sentinel
如何用Google Earth Engine快速、大量下载遥感影像数据?
【2月更文挑战第9天】本文介绍在谷歌地球引擎(Google Earth Engine,GEE)中,批量下载指定时间范围、空间范围的遥感影像数据(包括Landsat、Sentinel等)的方法~
633 0
如何用Google Earth Engine快速、大量下载遥感影像数据?
|
3月前
|
编解码 人工智能 算法
Google Earth Engine——促进森林温室气体报告的全球时间序列数据集
Google Earth Engine——促进森林温室气体报告的全球时间序列数据集
31 0
|
3月前
|
编解码 人工智能 数据库
Google Earth Engine(GEE)——全球道路盘查项目全球道路数据库
Google Earth Engine(GEE)——全球道路盘查项目全球道路数据库
48 0
|
3月前
|
编解码
Open Google Earth Engine(OEEL)——matrixUnit(...)中产生常量影像
Open Google Earth Engine(OEEL)——matrixUnit(...)中产生常量影像
23 0
|
3月前
Google Earth Engine(GEE)——导出指定区域的河流和流域范围
Google Earth Engine(GEE)——导出指定区域的河流和流域范围
51 0
|
3月前
|
传感器 编解码 数据处理
Open Google Earth Engine(OEEL)——哨兵1号数据的黑边去除功能附链接和代码
Open Google Earth Engine(OEEL)——哨兵1号数据的黑边去除功能附链接和代码
25 0
|
3月前
Google Earth Engine(GEE)——当加载图表的时候出现错误No features contain non-null values of “system:time_start“.
Google Earth Engine(GEE)——当加载图表的时候出现错误No features contain non-null values of “system:time_start“.
45 0