Android 开发之 RecyclerView 拖拽 + 固定首个

来源:互联网 发布:网络小说吧 编辑:程序博客网 时间:2024/05/18 00:49

仿腾讯视频中全部频道界面,首个精选长按不能拖动,其余的可以拖动。

效果图

这里写图片描述

1、添加依赖

dependencies {    compile 'com.android.support:recyclerview-v7:25.2.0'}

2、布局

activity_grid_view.xml

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.gyq.recyclerviewtest.GridViewActivity">    <android.support.v7.widget.RecyclerView        android:id="@+id/recycler_grid"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:clipChildren="false"        android:clipToPadding="false"/></FrameLayout>

item_grid_view.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:background="@android:color/white"    android:padding="10dp"    android:orientation="vertical">    <ImageView        android:id="@+id/img_item"        android:layout_width="match_parent"        android:layout_height="40dp"        app:srcCompat="@drawable/ic_fruit_icons_01"/>    <TextView        android:id="@+id/tv_item"        android:layout_marginTop="10dp"        style="@style/TextAppearance.AppCompat.Button"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:gravity="center"        android:text="item"/></LinearLayout>

3、逻辑代码

1,GridViewActivity.java

package com.gyq.recyclerviewtest;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.GridLayoutManager;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.helper.ItemTouchHelper;import android.view.MenuItem;import android.widget.Toast;import com.gyq.recyclerviewtest.adapter.RecyAdapter;import com.gyq.recyclerviewtest.bean.DataManager;import com.gyq.recyclerviewtest.recyevent.OnRecyclerItemClickListener;import com.gyq.recyclerviewtest.recyevent.RecyItemTouchHelperCallback;import com.gyq.recyclerviewtest.recymbelish.DividerGridItemDecoration;import java.util.ArrayList;import java.util.List;public class GridViewActivity extends AppCompatActivity {    RecyclerView mRecyclerView;    List<String> mStringList;    RecyAdapter mRecyAdapter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_grid_view);        getSupportActionBar().setDisplayHomeAsUpEnabled(true);        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_grid);        initRecy();    }    private void initRecy() {        if (mStringList == null) {            mStringList = new ArrayList<>();        }        mStringList.addAll(DataManager.getData(9));        mRecyAdapter = new RecyAdapter(R.layout.item_grid_view, mStringList, true);        mRecyclerView.setLayoutManager(new GridLayoutManager(this, 4));        mRecyclerView.addItemDecoration(new DividerGridItemDecoration(this));        mRecyclerView.setHasFixedSize(true);        RecyItemTouchHelperCallback itemTouchHelperCallback = new RecyItemTouchHelperCallback(mRecyAdapter, false, true);        final ItemTouchHelper itemTouchHelper = new ItemTouchHelper(itemTouchHelperCallback);        itemTouchHelper.attachToRecyclerView(mRecyclerView);        mRecyclerView.addOnItemTouchListener(new OnRecyclerItemClickListener(mRecyclerView) {            @Override            public void onItemClick(RecyclerView.ViewHolder viewHolder) {                RecyAdapter.ViewHolder viewHolder1 = (RecyAdapter.ViewHolder) viewHolder;                String tvString = viewHolder1.mTextView.getText().toString();                Toast.makeText(GridViewActivity.this, "点击了..." + tvString, Toast.LENGTH_SHORT).show();            }            @Override            public void onLongClick(RecyclerView.ViewHolder viewHolder) {                Toast.makeText(GridViewActivity.this, "" + "长按拖动...", Toast.LENGTH_SHORT).show();                if (viewHolder.getLayoutPosition() != 0) {                    itemTouchHelper.startDrag(viewHolder);                }            }        });        mRecyclerView.setAdapter(mRecyAdapter);    }}

适配器

package com.gyq.recyclerviewtest.adapter;import android.graphics.Color;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;import com.gyq.recyclerviewtest.R;import java.util.Arrays;import java.util.List;/** * Created by gyq on 2017/9/8 09:59 */public class RecyAdapter extends RecyclerView.Adapter<RecyAdapter.ViewHolder> {    private int item_layout;    private List<String> mDataList;    private List<Integer> mInts;    private boolean isFirstSpecial;    public RecyAdapter(int item_layout, List<String> dataList) {        this.item_layout = item_layout;        mDataList = dataList;        mInts = Arrays.asList(R.drawable.dsj, R.drawable.dy,                R.drawable.yy, R.drawable.wzry,                R.drawable.nnhk, R.drawable.zy,                R.drawable.ty, R.drawable.se, R.drawable.dm);    }    public RecyAdapter(int item_layout, List<String> dataList, boolean isFirstSpecial) {        this(item_layout, dataList);        this.isFirstSpecial = isFirstSpecial;    }    @Override    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View view = LayoutInflater.from(parent.getContext()).inflate(item_layout, parent, false);        return new ViewHolder(view);    }    @Override    public void onBindViewHolder(ViewHolder holder, int position) {        String string = mDataList.get(position);        if (isFirstSpecial && position == 0) {            holder.itemView.setBackgroundColor(Color.LTGRAY);            holder.mTextView.setText("精选");            holder.mImageView.setImageResource(R.drawable.jx);        } else {            holder.itemView.setBackgroundColor(Color.WHITE);            holder.mTextView.setText(string);            holder.mImageView.setImageResource(mInts.get(position % mInts.size()));        }    }    @Override    public int getItemCount() {        return mDataList == null ? 0 : mDataList.size();    }    public List<String> getDataList() {        return mDataList;    }    public class ViewHolder extends RecyclerView.ViewHolder {        public TextView mTextView;        ImageView mImageView;        ViewHolder(View itemView) {            super(itemView);            mTextView = (TextView) itemView.findViewById(R.id.tv_item);            mImageView = (ImageView) itemView.findViewById(R.id.img_item);        }    }}

recyclerView 的分割线

package com.gyq.recyclerviewtest.recymbelish;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Rect;import android.graphics.drawable.ColorDrawable;import android.graphics.drawable.Drawable;import android.support.v7.widget.GridLayoutManager;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.StaggeredGridLayoutManager;import android.view.View;/** * Created by gyq on 2017/9/8 10:03 */public class DividerGridItemDecoration extends RecyclerView.ItemDecoration {    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};    private Drawable mDivider;    private int lineWidth = 1;    public DividerGridItemDecoration(Context context) {        final TypedArray a = context.obtainStyledAttributes(ATTRS);        mDivider = a.getDrawable(0);        a.recycle();    }    public DividerGridItemDecoration(int color) {        mDivider = new ColorDrawable(color);    }    public DividerGridItemDecoration() {        this(Color.parseColor("#cccccc"));    }    @Override    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {        drawHorizontal(c, parent);        drawVertical(c, parent);    }    private int getSpanCount(RecyclerView parent) {        // 列数        int spanCount = -1;        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager instanceof GridLayoutManager) {            spanCount = ((GridLayoutManager) layoutManager).getSpanCount();        } else if (layoutManager instanceof StaggeredGridLayoutManager) {            spanCount = ((StaggeredGridLayoutManager) layoutManager)                    .getSpanCount();        }        return spanCount;    }    public void drawHorizontal(Canvas c, RecyclerView parent) {        int childCount = parent.getChildCount();        for (int i = 0; i < childCount; i++) {            final View child = parent.getChildAt(i);            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child                    .getLayoutParams();            final int left = child.getLeft() - params.leftMargin;            final int right = child.getRight() + params.rightMargin                    + lineWidth;            final int top = child.getBottom() + params.bottomMargin;            final int bottom = top + lineWidth;            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    public void drawVertical(Canvas c, RecyclerView parent) {        final int childCount = parent.getChildCount();        for (int i = 0; i < childCount; i++) {            final View child = parent.getChildAt(i);            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();            final int top = child.getTop() - params.topMargin;            final int bottom = child.getBottom() + params.bottomMargin;            final int left = child.getRight() + params.rightMargin;            final int right = left + lineWidth;            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    private boolean isLastColum(RecyclerView parent, int pos, int spanCount, int childCount) {        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager instanceof GridLayoutManager) {            if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边            {                return true;            }        } else if (layoutManager instanceof StaggeredGridLayoutManager) {            int orientation = ((StaggeredGridLayoutManager) layoutManager)                    .getOrientation();            if (orientation == StaggeredGridLayoutManager.VERTICAL) {                if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边                {                    return true;                }            } else {                childCount = childCount - childCount % spanCount;                if (pos >= childCount)// 如果是最后一列,则不需要绘制右边                    return true;            }        }        return false;    }    private boolean isLastRaw(RecyclerView parent, int pos, int spanCount, int childCount) {        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager instanceof GridLayoutManager) {            childCount = childCount - childCount % spanCount;            if (pos >= childCount)// 如果是最后一行,则不需要绘制底部                return true;        } else if (layoutManager instanceof StaggeredGridLayoutManager) {            int orientation = ((StaggeredGridLayoutManager) layoutManager)                    .getOrientation();            // StaggeredGridLayoutManager 且纵向滚动            if (orientation == StaggeredGridLayoutManager.VERTICAL) {                childCount = childCount - childCount % spanCount;                // 如果是最后一行,则不需要绘制底部                if (pos >= childCount)                    return true;            } else            // StaggeredGridLayoutManager 且横向滚动            {                // 如果是最后一行,则不需要绘制底部                if ((pos + 1) % spanCount == 0) {                    return true;                }            }        }        return false;    }    @Override    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {        boolean b = state.willRunPredictiveAnimations();        int itemPosition = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition();        int spanCount = getSpanCount(parent);        int childCount = parent.getAdapter().getItemCount();//        if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,则不需要绘制底部//        {//            outRect.set(0, 0, lineWidth, 0);//        }//        else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,则不需要绘制右边//        {////            if (b){////                outRect.set(0, 0, lineWidth, lineWidth);////            }else {//                outRect.set(0, 0, 0, lineWidth);////            }//        }//        else {        outRect.set(0, 0, lineWidth, lineWidth);//        }    }}

点击事件
OnRecyclerItemClickListener.java

package com.gyq.recyclerviewtest.recyevent;import android.support.v4.view.GestureDetectorCompat;import android.support.v7.widget.RecyclerView;import android.view.GestureDetector;import android.view.MotionEvent;import android.view.View;/** * Created by gyq on 2017/9/8 10:08 */public abstract class OnRecyclerItemClickListener implements RecyclerView.OnItemTouchListener{    private GestureDetectorCompat mGestureDetectorCompat;    private RecyclerView mRecyclerView;    public OnRecyclerItemClickListener(RecyclerView recyclerView) {        mRecyclerView = recyclerView;        mGestureDetectorCompat = new GestureDetectorCompat(mRecyclerView.getContext(),                new ItemTouchHelperGestureListener());    }    @Override    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {        mGestureDetectorCompat.onTouchEvent(e);        return false;    }    @Override    public void onTouchEvent(RecyclerView rv, MotionEvent e) {        mGestureDetectorCompat.onTouchEvent(e);    }    @Override    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {    }    public abstract void onItemClick(RecyclerView.ViewHolder viewHolder);    public abstract void onLongClick(RecyclerView.ViewHolder viewHolder);    private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener{        @Override        public boolean onSingleTapUp(MotionEvent e) {            View childViewUnder = mRecyclerView.findChildViewUnder(e.getX(), e.getY());            if (childViewUnder != null) {                RecyclerView.ViewHolder childViewHolder = mRecyclerView.getChildViewHolder(childViewUnder);                onItemClick(childViewHolder);            }            return true;        }        @Override        public void onLongPress(MotionEvent e) {            View childViewUnder = mRecyclerView.findChildViewUnder(e.getX(), e.getY());            if (childViewUnder != null) {                RecyclerView.ViewHolder childViewHolder = mRecyclerView.getChildViewHolder(childViewUnder);                onLongClick(childViewHolder);            }        }    }}

RecyItemTouchHelperCallback.java

package com.gyq.recyclerviewtest.recyevent;import android.graphics.Color;import android.support.v7.widget.GridLayoutManager;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.helper.ItemTouchHelper;import com.gyq.recyclerviewtest.adapter.RecyAdapter;import java.util.Collections;/** * Created by gyq on 2017/9/8 10:08 */public class RecyItemTouchHelperCallback extends ItemTouchHelper.Callback {    RecyclerView.Adapter mAdapter;    boolean isSwipeEnable;    boolean isFirstDragUnable;    public RecyItemTouchHelperCallback(RecyclerView.Adapter adapter) {        mAdapter = adapter;        isSwipeEnable = true;        isFirstDragUnable = false;    }    public RecyItemTouchHelperCallback(RecyclerView.Adapter adapter, boolean isSwipeEnable, boolean isFirstDragUnable) {        mAdapter = adapter;        this.isSwipeEnable = isSwipeEnable;        this.isFirstDragUnable = isFirstDragUnable;    }    @Override    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {        if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {            int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN |                    ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;            int swipeFlags = 0;            return makeMovementFlags(dragFlags, swipeFlags);        } else {            int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;            int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;            return makeMovementFlags(dragFlags, swipeFlags);        }    }    @Override    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {        int fromPosition = viewHolder.getAdapterPosition();        int toPosition = target.getAdapterPosition();        if (isFirstDragUnable && toPosition == 0) {            return false;        }        if (fromPosition < toPosition) {            for (int i = fromPosition; i < toPosition; i++) {                Collections.swap(((RecyAdapter) mAdapter).getDataList(), i, i + 1);            }        } else {            for (int i = fromPosition; i > toPosition; i--) {                Collections.swap(((RecyAdapter) mAdapter).getDataList(), i, i - 1);            }        }        mAdapter.notifyItemMoved(fromPosition, toPosition);        return true;    }    @Override    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {        int adapterPosition = viewHolder.getAdapterPosition();        mAdapter.notifyItemRemoved(adapterPosition);        ((RecyAdapter) mAdapter).getDataList().remove(adapterPosition);    }    @Override    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {        if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {            viewHolder.itemView.setBackgroundColor(Color.LTGRAY);        }        super.onSelectedChanged(viewHolder, actionState);    }    @Override    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {        super.clearView(recyclerView, viewHolder);        viewHolder.itemView.setBackgroundColor(Color.WHITE);    }    @Override    public boolean isLongPressDragEnabled() {        return !isFirstDragUnable;    }    @Override    public boolean isItemViewSwipeEnabled() {        return isSwipeEnable;    }}

数据
DataManager.java

package com.gyq.recyclerviewtest.bean;import java.util.ArrayList;import java.util.Arrays;import java.util.List;/** * Created by gyq on 2017/9/8 10:02 */public class DataManager {    private static List<String> sStringList = Arrays.asList("电视剧", "电影", "音乐", "王者荣耀",            "那年花开", "综艺", "体育", "少儿", "动漫");    public static final List<String> getData(int number) {        List<String> stringList = new ArrayList<>();        for (int i = 0; i < number; i++) {            stringList.add(sStringList.get(i % sStringList.size()));        }        return stringList;    }}

OK,结束啦!

原创粉丝点击