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.baiduhome.net/lib/view/home/1446619651232

     本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
     轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
     本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!