筆記:Android二級聯(lián)動---RecyclerView實現(xiàn)

做筆記免得以后有重寫一邊或者忘了,僅供自己學(xué)習(xí)(只實現(xiàn)功能,無動畫實現(xiàn),左邊沒做可見處理,有空再做吧):
1、左右兩個RecyclerView,
2、左邊RecyclerView點擊某個item同時item改變背景顏色,右邊RecyclerView置頂相對應(yīng)的item
3、右邊RecyclerView滑動,左邊RecyclerView相對應(yīng)的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("數(shù)據(jù)第"+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在滾動的時候監(jiān)聽第一個可見或者最后可見的item,這里是利用LayoutManager才可以監(jiān)聽到的
        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();
                //判斷是當(dāng)前l(fā)ayoutManager是否為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);
                }
                //設(shè)置左邊的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停止?jié)L動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相對應(yīng)指定item
        classifyRVAdapterLeft.setOnItemClickListener(new ClassifyRVLeftAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                //右邊RecyclerView相對應(yīng)置頂
                rv_right_classify.smoothScrollToPosition(position);
                //左邊的RecyclerView被選中時改變背景顏色
                classifyRVAdapterLeft.setSelectedPosition(position);
                //刷新左邊被選中的item,否則背景顏色不改變無效(親自踩坑)
                classifyRVAdapterLeft.notifyDataSetChanged();
            }
        });
    }
}

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

當(dāng)左邊RecyclerView的某個item被選中,右邊RecyclerView要置頂相對應(yīng)的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));
        //選中和沒選中時,設(shè)置不同的顏色
        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);//標(biāo)題
            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有點卡,湊合著看吧


聯(lián)動.gif

僅供學(xué)習(xí)之用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,063評論 25 709
  • afinalAfinal是一個android的ioc,orm框架 https://github.com/yangf...
    passiontim閱讀 15,877評論 2 45
  • 第一次上沙盤課的時候,老師帶我們進入一個意象畫面,要求每一個人用兩個字的詞語來描述自己沉入無意識狀態(tài)中的感受。閉著...
    青禾青禾閱讀 170評論 0 1
  • ???寫在前面的話 本文作者是2017屆的翻碩考生,也是向博主咨詢的同學(xué)之一。雖然沒有進入一志愿復(fù)試,但憑著自己出...
    尚理滬江翻譯閱讀 8,578評論 4 19
  • 王紹宇--韓國首爾 最大的收獲,大概是認(rèn)識到,為了中餐和火鍋,這輩子是絕對不能移民的。 能夠申請到韓國的項目,應(yīng)該...
    7751f01a0fcb閱讀 311評論 0 0

友情鏈接更多精彩內(nèi)容