美文网首页自定义控件
笔记:Android二级联动---RecyclerView实现

笔记:Android二级联动---RecyclerView实现

作者: RoJacKing | 来源:发表于2017-12-11 11:13 被阅读1220次

    做笔记免得以后有重写一边或者忘了,仅供自己学习(只实现功能,无动画实现,左边没做可见处理,有空再做吧):
    1、左右两个RecyclerView,
    2、左边RecyclerView点击某个item同时item改变背景颜色,右边RecyclerView置顶相对应的item
    3、右边RecyclerView滑动,左边RecyclerView相对应的item被选中并且改变颜色


    image.png

    1、MainActivity.java中使用

    package com.myapplication;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.view.View;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
    
        private isScroll=false;
        private RecyclerView rv_left_classify;
        private RecyclerView rv_right_classify;
        private List<String> dataList;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            rv_left_classify= (RecyclerView) findViewById(R.id.rv_left_classify);//左边recyclerview
            rv_right_classify= (RecyclerView) findViewById(R.id.rv_right_classify);//右边recyclerview
            initViewAndData();
        }
    
        public void initViewAndData() {
    
            dataList=new ArrayList<>();
            for (int i=0;i<20;i++){
                dataList.add("数据第"+i+"条");
            }
    
            //右边recyclerview
            //这个是自定义后的LayoutManager
            final RecyclerView.LayoutManager layoutManagerRight=new AdvertiseLinearLayoutManager(this, LinearLayoutManager.VERTICAL,false);
            rv_right_classify.setLayoutManager(layoutManagerRight);
            ClassifyRVRightAdapter classifyAdapterRight=new ClassifyRVRightAdapter(this,dataList);
            rv_right_classify.setAdapter(classifyAdapterRight);
    
            //左边recyclerview
            RecyclerView.LayoutManager layoutManager=new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
            rv_left_classify.setLayoutManager(layoutManager);
            final ClassifyRVLeftAdapter classifyRVAdapterLeft=new ClassifyRVLeftAdapter(this,dataList);
            rv_left_classify.setAdapter(classifyRVAdapterLeft);
    
            //右边recyclerview
            //右边recyclerview在滚动的时候监听第一个可见或者最后可见的item,这里是利用LayoutManager才可以监听到的
            rv_right_classify.setOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
                    //判断是当前layoutManager是否为LinearLayoutManager
                    // 只有LinearLayoutManager才有查找第一个和最后一个可见view位置的方法
                    int lastItemPosition = 0;//最后可见 右边
                    int firstItemPosition;//第一次可见 右边
                    if (layoutManager instanceof LinearLayoutManager) {
                        LinearLayoutManager linearManager = (LinearLayoutManager) layoutManager;
                        //获取最后一个可见view的位置    这两个随便选一个
                        lastItemPosition = linearManager.findLastVisibleItemPosition();
                        //获取第一个可见view的位置
                        firstItemPosition = linearManager.findFirstVisibleItemPosition();
                      
                       Log.e("可见item的位置--->>","最后一个可见=="+lastItemPosition+ "第一个可见==" + firstItemPosition);
                    }
                    //设置左边的RecyclerView的被点击
                    classifyRVAdapterLeft.setSelectedPosition(lastItemPosition);
                    //刷新左边的RecyclerView,否则选中无效(亲自踩坑)
                    classifyRVAdapterLeft.notifyDataSetChanged();
                }
             }
    
                @Override
                public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                    super.onScrollStateChanged(recyclerView, newState);
                    //如果是手动滑动右边RecyclerView,则isScroll为true,要刷新左边的RecyclerView,否则为false,不刷新
                    //这里说明一下,newState的三种情况
                  //RecyclerView停止滚动public static final int SCROLL_STATE_IDLE = 0;//RecyclerView正在被外部拖拽,一般为用户正在用手指滚动public static final int SCROLL_STATE_DRAGGING = 1;//自动滚动开始public static final int SCROLL_STATE_SETTLING = 2;
                    if (newState==RecyclerView.SCROLL_STATE_DRAGGING){
                        isScroll=true;
                    }else {
                        isScroll=false;
                    }
            });
    
            //左边recyclerview
            //点击左边的RecyclerView的某个item,右边RecyclerView相对应指定item
            classifyRVAdapterLeft.setOnItemClickListener(new ClassifyRVLeftAdapter.OnItemClickListener() {
                @Override
                public void onItemClick(View view, int position) {
                    //右边RecyclerView相对应置顶
                    rv_right_classify.smoothScrollToPosition(position);
                    //左边的RecyclerView被选中时改变背景颜色
                    classifyRVAdapterLeft.setSelectedPosition(position);
                    //刷新左边被选中的item,否则背景颜色不改变无效(亲自踩坑)
                    classifyRVAdapterLeft.notifyDataSetChanged();
                }
            });
        }
    }
    

    2、自定义LinearLayoutManager--------->>AdvertiseLinearLayoutManager.java

    当左边RecyclerView的某个item被选中,右边RecyclerView要置顶相对应的item,但是RecyclerView的本身的rv_right_classify.smoothScrollToPosition(position);的方法无法满足。所以我自定义了LinearSmoothScroller 与LinearLayoutManager(具体为啥就不深究了,只是做个笔记方便自己以后用到)

    package com.myapplication;
    
    import android.content.Context;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.util.AttributeSet;
    
    /**
     * Created by lenovo on 2017/12/8.
     */
    
      public class AdvertiseLinearLayoutManager extends LinearLayoutManager {
    
        public AdvertiseLinearLayoutManager(Context context) {
            super(context);
        }
        public AdvertiseLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
            super(context, orientation, reverseLayout);
        }
    
        public AdvertiseLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
        }
    
        @Override
        public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
            AdvertiseLinearSmoothScroller linearSmoothScroller =
                    new AdvertiseLinearSmoothScroller(recyclerView.getContext());
            linearSmoothScroller.setTargetPosition(position);
            startSmoothScroll(linearSmoothScroller);
        }
    }
    

    3、自定义LinearSmoothScroller

    package com.myapplication;
    
    import android.content.Context;
    import android.support.v7.widget.LinearSmoothScroller;
    import android.util.DisplayMetrics;
    
    /**
     * Created by lenovo on 2017/12/8.
     */
    
    class AdvertiseLinearSmoothScroller extends LinearSmoothScroller {
    
        public AdvertiseLinearSmoothScroller(Context context) {
            super(context);
        }
    
        /**
         *
         * @param viewStart RecyclerView的top位置
         * @param viewEnd RecyclerView的Bottom位置
         * @param boxStart item的top位置
         * @param boxEnd  item的bottom位置
         * @param snapPreference 滑动方向的识别
         * @return
         */
        @Override
        public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
            return boxStart-viewStart;//返回的就是我们item置顶需要的偏移量
        }
    
        /**
         * 此方法返回滚动每1px需要的时间,可以用来控制滚动速度
         * 即如果返回2ms,则每滚动1000px,需要2秒钟
         * @param displayMetrics
         * @return
         */
        @Override
        protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
            return super.calculateSpeedPerPixel(displayMetrics);
        }
    }
    
    

    4、左边RecyclerView的Adapter------>>>>ClassifyRVLeftAdapter.java

    package com.myapplication;
    
    import android.content.Context;
    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.TextView;
    
    import java.util.List;
    
    /**
     * Created by lenovo on 2017/12/8.
     */
    
    public class ClassifyRVLeftAdapter extends     RecyclerView.Adapter<ClassifyRVLeftAdapter.MyViewHolder>  implements View.OnClickListener {
    
        private List<String> mDatas;
        private Context mContext;
        private LayoutInflater inflater;
    
        private int selectedPosition = 0;
    
        private OnItemClickListener mOnItemClickListener = null;
        private View viewClassify;
    
        //define interface
        public static interface OnItemClickListener {
            void onItemClick(View view, int position);
        }
    
    
        public ClassifyRVLeftAdapter(Context context, List<String> datas){
            this. mContext=context;
            this. mDatas=datas;
            inflater= LayoutInflater. from(mContext);
        }
    
        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view  = inflater.inflate(R.layout.item_classify_rv_adapter,parent, false);
            MyViewHolder holder= new MyViewHolder(view);
            view.setOnClickListener(this);
            return holder;
        }
    
        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {
            holder.tv.setText( mDatas.get(position));
            //选中和没选中时,设置不同的颜色
            if (position == selectedPosition) {
                holder.tv.setBackgroundColor(Color.GRAY);
            } else {
                holder.tv.setBackgroundColor(Color.WHITE);
            }
            holder.itemView.setTag(position);
        }
    
    
        @Override
        public int getItemCount() {
            return mDatas.size();
        }
    
        @Override
        public void onClick(View view) {
            if (mOnItemClickListener != null) {
                //注意这里使用getTag方法获取position
                mOnItemClickListener.onItemClick(view,(int)view.getTag());
            }
        }
    
        public void setOnItemClickListener(OnItemClickListener listener) {
            this.mOnItemClickListener = listener;
        }
    
        public void setSelectedPosition(int selectedPosition) {
            this.selectedPosition = selectedPosition;
        }
    
        public int getSelectedPosition() {
            return selectedPosition;
        }
    
    
        class MyViewHolder extends RecyclerView.ViewHolder
        {
    
            TextView tv;
    
            public MyViewHolder(View view)
            {
                super(view);
                tv = (TextView) view.findViewById(R.id.classsify_tv);
            }
        }
    
    }
    

    4.1、左边RecyclerView的item布局 item_classify_rv_adapter.xml

    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/classsify_tv"
        android:gravity="center"
        android:paddingTop="5dp"
        android:paddingBottom="5dp"
        android:layout_width="120dp"
        android:layout_height="wrap_content">
    </TextView>
    

    5、右边RecyclerView的adapter------->>>>>>ClassifyRVRightAdapter.java

    package com.myapplication;
    
    import android.content.Context;
    import android.support.v7.widget.RecyclerView;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.AdapterView;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    import com.bumptech.glide.Glide;
    
    import java.util.List;
    
    
    /**
     * Created by lenovo on 2017/12/8.
     */
    
    public class ClassifyRVRightAdapter extends RecyclerView.Adapter<ClassifyRVRightAdapter.MyViewHolder>{
    
        private List<String> mDatas;
        private Context mContext;
        private LayoutInflater inflater;
    
        public ClassifyRVRightAdapter(MainActivity context, List<String> datas) {
            this.mContext = context;
            this.mDatas = datas;
            inflater = LayoutInflater.from(mContext);
        }
    
        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = inflater.inflate(R.layout.item_classify_right, parent, false);
            MyViewHolder holder = new MyViewHolder(view);
            return holder;
        }
    
        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {
            holder.txt_two_tit.setText(mDatas.get(position));
    
        }
    
    
        @Override
        public int getItemCount() {
            return mDatas.size();
        }
    
        class MyViewHolder extends RecyclerView.ViewHolder {
    
            TextView txt_two_tit;
            MyGridView my_gridview;
    
            public MyViewHolder(View view) {
                super(view);
                txt_two_tit = (TextView) view.findViewById(R.id.txt_two_tit);//标题
                my_gridview = (MyGridView) view.findViewById(R.id.my_gridview);
                my_gridview.setAdapter(new GridViewAdapter());
                my_gridview.setNumColumns(2);
                my_gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                        Log.e("aaaa","被点击");
                    }
                });
            }
        }
        class GridViewAdapter extends android.widget.BaseAdapter {
    
    
            @Override
            public int getCount() {
                return mDatas.size();
            }
    
            @Override
            public Object getItem(int position) {
                return position;
            }
    
            @Override
            public long getItemId(int position) {
                return position;
            }
    
            @Override
            public View getView(int position, View view, ViewGroup viewGroup) {
                ViewHolder mHolder;
                if (view == null) {
                    mHolder = new ViewHolder();
                    view = LayoutInflater.from(viewGroup.getContext())
                            .inflate(R.layout.item_hot_sale, viewGroup, false);
                    mHolder.image_commodity = (ImageView) view.findViewById(R.id.image_commodity);
                    mHolder.txt_name = (TextView) view.findViewById(R.id.txt_name);
                    view.setTag(mHolder);
                } else {
                    mHolder = (ViewHolder) view.getTag();
                }
                if (mDatas != null) {
                    Glide.with(mContext).load(R.mipmap.ic_launcher).into(mHolder.image_commodity);
                    mHolder.txt_name.setText(mDatas.get(position));
                }
                return view;
            }
    
            private class ViewHolder {
                private ImageView image_commodity;
                private TextView txt_name;
            }
        }
    }
    

    5.1、右边adapter的item布局 item_classify_right.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="vertical">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#10000000"
            android:gravity="center"
            android:orientation="horizontal">
    
            <TextView
                android:layout_width="40dp"
                android:layout_height="1dp"
                android:layout_gravity="center_vertical"
                android:background="@color/colorAccent" />
    
            <TextView
                android:id="@+id/txt_two_tit"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="12dp"
                android:text="222222" />
    
            <TextView
                android:layout_width="40dp"
                android:layout_height="1dp"
                android:layout_gravity="center_vertical"
                android:background="@color/colorAccent" />
        </LinearLayout>
    
        <com.myapplication.MyGridView
            android:id="@+id/my_gridview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </LinearLayout>
    

    5.2、右边RecyclerView中的自定义GridView--->>>MyGridView.java

    package com.myapplication;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.widget.GridView;
    
    /**
     * Created by Administrator on 2017/2/13 0013.
     */
    
    public class MyGridView extends GridView {
    
        public MyGridView(Context context) {
            super(context);
        }
    
        public MyGridView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public MyGridView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                    MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, expandSpec);
        }
    }
    

    5.3、右边RecyclerView中的MyGridView的item布局 item_hot_sale.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/item_hot_sale"
        android:orientation="vertical">
    
              <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:paddingBottom="10dp"
                android:paddingTop="10dp"
                android:orientation="vertical" >
    
            <ImageView
                android:id="@+id/image_commodity"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:src="@mipmap/ic_launcher"
                android:scaleType="fitXY"
                />
    
            <TextView
                android:id="@+id/txt_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="女装"
                android:layout_marginTop="3dp"
                android:layout_gravity="center_horizontal"
                android:textColor="@android:color/black" />
            </LinearLayout>
    </LinearLayout>
    

    加强版:右边悬浮+decoration修饰分割线

    效果还是挺流畅的,只是gif有点卡,凑合着看吧


    联动.gif

    仅供学习之用

    相关文章

      网友评论

        本文标题:笔记:Android二级联动---RecyclerView实现

        本文链接:https://www.haomeiwen.com/subject/viqiixtx.html