左右联动(一行两条数据)

效果图:

1、引入依赖

2、左侧类型适配器

3、左侧类型布局文件

4、右侧内容适配器

5、右侧内容布局文件

6、MainActivity代码

7、MainActivity布局文件

8、dimens.xml尺寸文件

9、left_item_check_bg.xml左侧选中的背景文件

10、item_right_title.xml分组标题文件

11、ScrollBean实体类

12、在AndroidManifest.xml中加入权限

引入依赖:

 先在build.gradle(Project)中加入

allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://jitpack.io" }
    }
}

 然后在build.gradle(Module)中加入(加入后记得点击右上角的同步(Sync Now))

implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.47'
implementation 'com.github.bumptech.glide:glide:4.9.0'
implementation 'com.google.android.material:material:1.0.0'

 

左侧类型适配器(LeftAdapter):

package com.example.recycleview2.adapter;

import android.graphics.Color;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.example.recycleview2.R;

import java.util.ArrayList;
import java.util.List;

public class LeftAdapter extends BaseQuickAdapter {
    private List tvList = new ArrayList<>();

    public LeftAdapter(int layoutResId, @Nullable List data){
        super(layoutResId,data);
    }

    @Override
    protected void convert(@NonNull BaseViewHolder helper, String item) {
        helper.setText(R.id.left_text,item).addOnClickListener(R.id.item);
        tvList.add((TextView)helper.getView(R.id.left_text)); //将左侧item中的TextView添加到集合中
        //设置进入页面之后,左边列表的初始状态
        if(tvList != null && getData() != null && tvList.size() == getData().size()){
            selectItemt(0);
        }
        helper.getView(R.id.item).setSelected(true);
    }

    public void selectItemt(int i){
        for (int j = 0; j < getData().size(); j++) {
            if( i == j){
//                tvList.get(j).setBackgroundColor(Color.parseColor("#008577")); //选中的背景
                tvList.get(j).setBackgroundResource(R.drawable.left_item_check_bg);
                tvList.get(j).setTextColor(ContextCompat.getColor(mContext,R.color.white));
            }else{
                tvList.get(j).setBackgroundColor(0xffffffff); //未选中的背景
                tvList.get(j).setTextColor(ContextCompat.getColor(mContext,R.color.gray));
            }
        }
    }
}

 

左侧类型布局文件(item_left.xml):



    

 

右侧内容适配器(RightAdapter):

package com.example.recycleview2.adapter;

import android.media.Image;
import android.widget.ImageView;

import androidx.annotation.Nullable;

import com.bumptech.glide.Glide;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseSectionQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.example.recycleview2.R;
import com.example.recycleview2.entity.ScrollBean;

import java.util.List;

public class RightAdapter extends BaseSectionQuickAdapter {
    public RightAdapter(int layoutResId, int sectionHeadResId, List data){
        super(layoutResId,sectionHeadResId,data);
    }

    @Override
    protected void convertHead(BaseViewHolder helper,ScrollBean item){
        helper.setText(R.id.right_title,item.header);
    }

    @Override
    protected void convert(@Nullable BaseViewHolder helper,ScrollBean item){
        ScrollBean.ScrollItemBean itemBean = item.t;
        helper.setText(R.id.main_name,itemBean.getName());
        helper.setText(R.id.main_price,itemBean.getPrice());
        Glide.with(mContext).load(itemBean.getImg()).into((ImageView)helper.getView(R.id.main_image));
    }
}

 

右侧内容布局文件(item_right.xml):




    

        

        

            

            

            

        
    


 

MainActivity代码:

package com.example.recycleview2;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.content.Context;
import android.graphics.Rect;
import android.icu.util.LocaleData;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.example.recycleview2.adapter.LeftAdapter;
import com.example.recycleview2.adapter.RightAdapter;
import com.example.recycleview2.entity.ScrollBean;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private RecyclerView recyclerLeft,recyclerRight;
    private TextView tvRightTitle; //右侧item标题
    private List leftList; //左侧文本数据
    private List rightList; //右侧数据
    private LeftAdapter leftAdapter; //左侧适配器
    private RightAdapter rightAdapter; //右侧适配器

    //右侧标题在数据中所对应的数据集合
    private List integerList = new ArrayList<>();
    private Context mContext;

    private int titleHeight; //标题的高度
    private int first = 0; //右侧第一个item数据
    private GridLayoutManager gridLayoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();

    }

    private void initView(){
        mContext = this;
        recyclerLeft = findViewById(R.id.rec_left);
        recyclerRight = findViewById(R.id.rec_right);
        tvRightTitle = findViewById(R.id.right_title);
        getLeftData(); //获取左侧数据
        getRightData(); //获取右侧数据
        initRightLayout();
        initLeftLayout();
    }

    private void getLeftData(){
        leftList = new ArrayList<>();
        leftList.add("星期一");
        leftList.add("星期二");
        leftList.add("星期三");
        leftList.add("星期四");
        leftList.add("星期五");
        leftList.add("星期六");
        leftList.add("星期日");
    }

    private void getRightData(){
        String imgUrl = "http://imgm.gmw.cn/attachement/jpg/site215/20190902/3742794414253686953.jpg";
        rightList = new ArrayList<>();
        for (int i = 0; i < leftList.size(); i++) {
            rightList.add(new ScrollBean(true,leftList.get(i))); //第一组数据
            for (int j = 0; j < 6; j++) {
                rightList.add(new ScrollBean((new ScrollBean.ScrollItemBean("数据" + j,String.valueOf(i*j),imgUrl,leftList.get(i)))));
            }
        }

        for (int i = 0; i < rightList.size(); i++) {
            if(rightList.get(i).isHeader){
                integerList.add(i); //将header添加到集合
            }
        }
    }

    //右侧数据布局
    private void initRightLayout(){
        gridLayoutManager = new GridLayoutManager(mContext,2);
        if(rightAdapter == null){
            rightAdapter = new RightAdapter(R.layout.item_right,R.layout.item_right_title,null);
            recyclerRight.setLayoutManager(gridLayoutManager);
            recyclerRight.addItemDecoration(new RecyclerView.ItemDecoration() {
                @Override
                public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
                    super.getItemOffsets(outRect, view, parent, state);
                    outRect.set(dpToPx(mContext, getDimens(mContext, R.dimen.dp3)),0
                            , dpToPx(mContext, getDimens(mContext, R.dimen.dp3))
                            , dpToPx(mContext, getDimens(mContext, R.dimen.dp3)));
                }
            });
            recyclerRight.setAdapter(rightAdapter);
        }else{
            rightAdapter.notifyDataSetChanged();
        }
        rightAdapter.setNewData(rightList);
        //设置右侧初始化标题
        if(rightList.get(first).isHeader){
            tvRightTitle.setText(rightList.get(first).header);
        }
        //滑动监听
        recyclerRight.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                titleHeight = tvRightTitle.getHeight(); //获取右侧标题的高度
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if(rightList.get(first).isHeader){
                    View view = gridLayoutManager.findViewByPosition(first); //获取item的View
                    if(view != null){
                        //item顶部和父容器顶部距离大于等于标题的高度,则设置偏移量
                        if(view.getTop() >= titleHeight){
                            tvRightTitle.setY(view.getTop() - titleHeight);
                        }else{
                            tvRightTitle.setY(0); //不设置
                        }
                    }
                }
                /*
                每次滑动之后,右侧列表中可见的第一个item的position肯定会改变,
                并且右侧列表中可见的第一个item的position变换了之后,
                才有可能改变右侧title的值,
                所以这个方法内的逻辑在右侧可见的第一个item的position改变之后一定会执行
                */
                int firstPosition = gridLayoutManager.findFirstVisibleItemPosition();
                if(first != firstPosition && firstPosition >= 0){
                    first = firstPosition; //给first赋值
                    tvRightTitle.setY(0); //不设置y轴的偏移量
                    //右侧第一个item是否是header,是则设置相应的值
                    if(rightList.get(first).isHeader){
                        tvRightTitle.setText(rightList.get(first).header);
                    }else{
                        tvRightTitle.setText(rightList.get(first).t.getType());
                    }
                }
                //遍历左边列表,列表对应的内容等于右边的title,则设置左侧对应item高亮
                for (int i = 0; i < leftList.size(); i++) {
                    if(leftList.get(i).equals(tvRightTitle.getText().toString())){
                        leftAdapter.selectItemt(i);
                    }
                }
                /*
                如果右边最后一个完全显示的item的position,
                等于bean中最后一条数据的position(也就是右侧列表拉到底了),
                则设置左侧列表最后一条item高亮
                */
                if(gridLayoutManager.findLastCompletelyVisibleItemPosition() == rightList.size() - 1){
                    leftAdapter.selectItemt(leftList.size() - 1);
                }
            }
        });
    }

    //左侧数据布局
    private void initLeftLayout(){
        if(leftAdapter == null){
            leftAdapter = new LeftAdapter(R.layout.item_left,null);
            recyclerLeft.setLayoutManager(new LinearLayoutManager(mContext,RecyclerView.VERTICAL,false));
            recyclerLeft.addItemDecoration(new DividerItemDecoration(mContext,DividerItemDecoration.VERTICAL));
            recyclerLeft.setAdapter(leftAdapter);
        }else{
            leftAdapter.notifyDataSetChanged();
        }
        leftAdapter.setNewData(leftList);
        leftAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
            @Override
            public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
                switch (view.getId()){
                    case R.id.item:
                        leftAdapter.selectItemt(position);
                        gridLayoutManager.scrollToPositionWithOffset(integerList.get(position),0);
                        break;
                        default:break;
                }
            }
        });
    }

    private float getDimens(Context context,int id){
        DisplayMetrics dm = context.getResources().getDisplayMetrics();
        float px = context.getResources().getDimension(id);
        return px / dm.density;
    }

    private int dpToPx(Context context,float dp){
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        return (int) ((dp * displayMetrics.density) + 0.5f);
    }
}

 

MainActivity布局文件:




    

    

    

        

        
    

 

dimens.xml尺寸文件(此文件放在values文件夹中):



    8sp
    9sp
    10sp
    11sp
    12sp
    13sp
    14sp
    15sp
    16sp
    17sp
    18sp
    19sp
    20sp
    21sp
    22sp
    23sp
    24sp
    25sp
    26sp
    27sp
    28sp
    29sp
    30sp

    1dp
    2dp
    3dp
    4dp
    5dp
    6dp
    7dp
    8dp
    9dp
    10dp
    11dp
    12dp
    13dp
    14dp
    15dp
    16dp
    17dp
    18dp
    19dp
    20dp
    21dp
    22dp
    23dp
    24dp
    25dp
    26dp
    27dp
    28dp
    29dp
    30dp
    31dp
    32dp
    33dp
    34dp
    35dp
    36dp
    37dp
    38dp
    39dp
    40dp
    41dp
    42dp
    43dp
    44dp
    45dp
    46dp
    47dp
    48dp
    49dp
    50dp
    51dp
    52dp
    53dp
    54dp
    55dp
    56dp
    57dp
    58dp
    59dp
    60dp
    61dp
    62dp
    63dp
    64dp
    65dp
    66dp
    67dp
    68dp
    69dp
    70dp
    71dp
    72dp
    73dp
    74dp
    75dp
    76dp
    77dp
    78dp
    79dp
    80dp
    81dp
    82dp
    83dp
    84dp
    85dp
    86dp
    87dp
    88dp
    89dp
    90dp
    91dp
    92dp
    93dp
    94dp
    95dp
    96dp
    97dp
    98dp
    99dp
    100dp
    101dp
    102dp
    103dp
    104dp
    105dp
    106dp
    107dp
    108dp
    109dp
    110dp
    111dp
    112dp
    113dp
    114dp
    115dp
    116dp
    117dp
    118dp
    119dp
    120dp
    121dp
    122dp
    123dp
    124dp
    125dp
    126dp
    127dp
    128dp
    129dp
    130dp
    131dp
    132dp
    133dp
    134dp
    135dp
    136dp
    137dp
    138dp
    139dp
    140dp
    141dp
    142dp
    143dp
    144dp
    145dp
    146dp
    147dp
    148dp
    149dp
    150dp
    151dp
    152dp
    153dp
    154dp
    155dp
    156dp
    157dp
    158dp
    159dp
    160dp
    161dp
    162dp
    163dp
    164dp
    165dp
    166dp
    167dp
    168dp
    169dp
    170dp
    171dp
    172dp
    173dp
    174dp
    175dp
    176dp
    177dp
    178dp
    179dp
    180dp
    181dp
    182dp
    183dp
    184dp
    185dp
    186dp
    187dp
    188dp
    189dp
    190dp
    191dp
    192dp
    193dp
    194dp
    195dp
    196dp
    197dp
    198dp
    199dp
    200dp
    201dp
    202dp
    203dp
    204dp
    205dp
    206dp
    207dp
    208dp
    209dp
    210dp
    211dp
    212dp
    213dp
    214dp
    215dp
    216dp
    217dp
    218dp
    219dp
    220dp
    221dp
    222dp
    223dp
    224dp
    225dp
    226dp
    227dp
    228dp
    229dp
    230dp
    231dp
    232dp
    233dp
    234dp
    235dp
    236dp
    237dp
    238dp
    239dp
    240dp
    241dp
    242dp
    243dp
    244dp
    245dp
    246dp
    247dp
    248dp
    249dp
    250dp
    251dp
    252dp
    253dp
    254dp
    255dp
    256dp
    257dp
    258dp
    259dp
    260dp
    261dp
    262dp
    263dp
    264dp
    265dp
    266dp
    267dp
    268dp
    269dp
    270dp
    271dp
    272dp
    273dp
    274dp
    275dp
    276dp
    277dp
    278dp
    279dp
    280dp
    281dp
    282dp
    283dp
    284dp
    285dp
    286dp
    287dp
    288dp
    289dp
    290dp
    291dp
    292dp
    293dp
    294dp
    295dp
    296dp
    297dp
    298dp
    299dp
    300dp

    
    0.5dp

 

left_item_check_bg.xml左侧选中的背景文件:



    
    
    

 

item_right_title.xml分组标题文件:



    

 

ScrollBean实体类:

package com.example.recycleview2.entity;

import com.chad.library.adapter.base.entity.SectionEntity;

public class ScrollBean extends SectionEntity {
    public ScrollBean(boolean isHeader,String header){
        super(isHeader,header);
    }

    public ScrollBean(ScrollItemBean bean){
        super(bean);
    }

    public static class ScrollItemBean{
        private String name;
        private String price;
        private String img;
        private String type;

        public ScrollItemBean(String name,String price,String img,String type){
            this.name = name;
            this.price = price;
            this.img = img;
            this.type = type;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getPrice() {
            return price;
        }

        public void setPrice(String price) {
            this.price = price;
        }

        public String getImg() {
            return img;
        }

        public void setImg(String img) {
            this.img = img;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }
    }
}

 

在AndroidManifest.xml中加入权限:


 

转载于:https://www.cnblogs.com/Mr-Deng/p/11447629.html

你可能感兴趣的:(移动开发,java)