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

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


笔记:Android二级联动---RecyclerView实现_第1张图片
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 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  implements View.OnClickListener {

    private List 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 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




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{

    private List mDatas;
    private Context mContext;
    private LayoutInflater inflater;

    public ClassifyRVRightAdapter(MainActivity context, List 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




    

        

        

        
    

    

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




          

        

        
        

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

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


联动.gif

仅供学习之用

你可能感兴趣的:(笔记:Android二级联动---RecyclerView实现)