Android 商品详情(TabLayout+RecyclerView)

Android 商品详情(TabLayout+RecyclerView)
顶部是tabLayout(包含 商品、评论、详情、推荐等)
下面是RecyclerView(多布局设计方案)

写布局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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <RelativeLayout
        android:background="@color/white"
        android:layout_width="match_parent"
        android:layout_height="50dp">

        <TextView
            android:id="@+id/tv_back"
            android:layout_width="50dp"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="返回"
            android:textColor="#333333"
            android:textSize="12dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:text="商品详情"
            android:textColor="#333333"
            android:textSize="16dp" />

    </RelativeLayout>


    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        app:tabIndicatorColor="#F61010"
        app:tabIndicatorFullWidth="false"
        app:tabIndicatorHeight="3dp"
        app:tabMode="fixed"
        app:tabBackground="@color/white"
        app:tabPaddingEnd="0dp"
        app:tabPaddingStart="0dp"
        app:tabRippleColor="#00000000"
        app:tabSelectedTextColor="#333333"
        app:tabTextColor="#666666"/>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

代码文件

public class ShopDetailActivity extends AppCompatActivity {


    private TextView tvBack;
    private TabLayout tabLayout;
    private RecyclerView recyclerView;
    private List<ShopDetailBean> list;

    private boolean canScroll; //还需要继续滑动
    private int scrollPosition = 0;
    private boolean isRecyclerScroll = false;

    private String[] titles = {"商品", "评论", "详情", "推荐"};
    private LinearLayoutManager layoutManager;

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

        tvBack = findViewById(R.id.tv_back);
        tabLayout = findViewById(R.id.tabLayout);
        recyclerView = findViewById(R.id.recyclerView);

        tvBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        if (list == null) {
            list = new ArrayList<>();
        }
        list.add(new ShopDetailBean(1));
        list.add(new ShopDetailBean(2));
        list.add(new ShopDetailBean(3, "", "商品详情"));
        list.add(new ShopDetailBean(4, "https://img0.baidu.com/it/u=2880487,4114246306&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500"));
        list.add(new ShopDetailBean(4, "https://img2.baidu.com/it/u=3311811998,3185175032&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=625"));
        list.add(new ShopDetailBean(4, "https://www.beihaiting.com/uploads/allimg/180520/10723-1P5200R55J02.jpg"));
        list.add(new ShopDetailBean(4, "https://img1.baidu.com/it/u=2995157981,91041597&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750"));
        list.add(new ShopDetailBean(4, "https://img.zhisheji.com/bbs/forum/201401/05/153945tbr7pg5torfzptso.jpg"));

        list.add(new ShopDetailBean(5, "", "推荐商品"));
        list.add(new ShopDetailBean(4, "https://img1.baidu.com/it/u=2995157981,91041597&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750"));
        list.add(new ShopDetailBean(4, "https://www.beihaiting.com/uploads/allimg/180520/10723-1P5200R55J02.jpg"));
        list.add(new ShopDetailBean(4, "https://img2.baidu.com/it/u=3311811998,3185175032&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=625"));
        list.add(new ShopDetailBean(4, "https://img0.baidu.com/it/u=2880487,4114246306&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500"));


        ShopDetailAdapter adapter = new ShopDetailAdapter(list);
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(adapter);


        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (canScroll) {
                    moveToCanScroll();
                    canScroll = false;
                }

                if (isRecyclerScroll) {
                    int firstPosition = layoutManager.findFirstVisibleItemPosition();
                    if (firstPosition <= 0) {
                        setTabSelected(0);
                    } else if (firstPosition <= 1) {
                        setTabSelected(1);
                    } else if (firstPosition > 1 && firstPosition < 8) {
                        setTabSelected(2);
                    } else if (firstPosition >= 8) {
                        setTabSelected(3);
                    }
                }
            }
        });

        recyclerView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    isRecyclerScroll = true;
                }
                return false;
            }
        });
        tabLayout.removeAllTabs();
        for (int i = 0; i < titles.length; i++) {
            TabLayout.Tab tab = tabLayout.newTab();
            if (tab != null) {
                TextView view = new TextView(this);
                view.setText(titles[i]);
                view.setGravity(Gravity.CENTER);
                view.setTextColor(ContextCompat.getColor(this, R.color.colorPrimaryDark));
                tab.setCustomView(view);
                view.getRootView().setTag(i);
                view.getRootView().setOnClickListener(mTabOnClickListener);
            }
            tabLayout.addTab(tab);
        }
    }

    /***
     * 哪个tab选中
     * @param position
     */
    private void setTabSelected(int position) {
        tabLayout.getTabAt(position).select();
        tabLayout.setScrollPosition(position,0,true);
    }

    private View.OnClickListener mTabOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int tag = (int) v.getTag();
            Log.i("======", "======tab onclick " + tag);
            setTabSelected(tag);
            int index = tag;
            int position = 0;
            if (index == 0) {
                position = 0;
            } else if (index == 1) {
                position = 1;
            } else if (index == 2) {
                position = 2;
            } else if (index == 3) {
                position = 8;
            }
            isRecyclerScroll = false;
            moveToPosition(position);
        }
    };


    /***
     * 滑动RecyclerView
     * @param position
     */
    private void moveToPosition(int position) {
        int firstPosition = layoutManager.findFirstVisibleItemPosition();
        int lastPosition = layoutManager.findLastVisibleItemPosition();
        if (position <= firstPosition) {
            //在屏幕外(划出手机屏幕了)
            recyclerView.scrollToPosition(position);
        } else if (position <= lastPosition) {
            //在屏幕内
            int y = recyclerView.getChildAt(position - firstPosition).getTop();
            recyclerView.scrollBy(0, y);
        } else {
            //在屏幕外(底部,还未出现)
            recyclerView.scrollToPosition(position);
            canScroll = true;
            scrollPosition = position;
        }
    }

    /**
     * 继续滑动
     * 在屏幕外(底部,还未出现)
     */
    private void moveToCanScroll() {
        int firstPosition = layoutManager.findFirstVisibleItemPosition();
        int y = recyclerView.getChildAt(scrollPosition - firstPosition).getTop();
        recyclerView.scrollBy(0, y);
    }
}

adpater文件

public class ShopDetailAdapter extends RecyclerView.Adapter {

    private List<ShopDetailBean> list;
    public ShopDetailAdapter(List<ShopDetailBean> list) {
        this.list = list;
    }
    
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case 1:
                View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_shop_title, parent, false);
                return new TitleViewHolder(view);
            case 2:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_shop_comment, parent, false);
                return new CommentViewHolder(view);
            case 3:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_shop_t, parent, false);
                return new TViewHolder(view);
            case 4:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_shop_comment, parent, false);
                return new ImageViewHolder(view);
            case 5:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_shop_t, parent, false);
                return new TViewHolder(view);
            default:
                break;
        }
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        ShopDetailBean bean = list.get(position);
        if (holder instanceof ImageViewHolder) {
            ImageView ivImg = ((ImageViewHolder) holder).ivImg;
            Glide.with(ivImg.getContext())
                    .load(bean.imageUrl)
                    .error(R.mipmap.ic_launcher)
                    .placeholder(R.mipmap.ic_launcher)
                    .into(ivImg);
        } else if (holder instanceof TViewHolder) {
            TextView tvName = ((TViewHolder) holder).tvName;
            tvName.setText(bean.name);
        }
    }

    @Override
    public int getItemCount() {
        return list != null ? list.size() : 0;
    }

    @Override
    public int getItemViewType(int position) {
        if (list != null) {
            return list.get(position).type;
        }
        return 0;
    }


    /**
     * banner + 商品标题部分
     */
    static class TitleViewHolder extends RecyclerView.ViewHolder {
        public TitleViewHolder(View itemView) {
            super(itemView);
        }
    }

    /**
     * 评论部分
     */
    static class CommentViewHolder extends RecyclerView.ViewHolder {
        public CommentViewHolder(View itemView) {
            super(itemView);
        }
    }

    /**
     * 商品详情文字
     */
    static class TViewHolder extends RecyclerView.ViewHolder {
        TextView tvName;
        public TViewHolder(View itemView) {
            super(itemView);
            tvName = itemView.findViewById(R.id.tv_name);
        }
    }


    /**
     * 商品详情图片部分
     */
    static class ImageViewHolder extends RecyclerView.ViewHolder {
        ImageView ivImg;
        public ImageViewHolder(View itemView) {
            super(itemView);
            ivImg = itemView.findViewById(R.id.iv_img);
        }
    }
}

bean文件

public class ShopDetailBean {
    public int type;   //多类型区分
    public String imageUrl;
    public String name;
    
    public ShopDetailBean(int type) {
        this.type = type;
    }

    public ShopDetailBean(int type, String imageUrl) {
        this.type = type;
        this.imageUrl = imageUrl;
    }
    
    public ShopDetailBean(int type, String imageUrl, String name) {
        this.type = type;
        this.imageUrl = imageUrl;
        this.name = name;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个实现需要以下步骤: 1. 在布局文件中添ViewPager2和TabLayout: ```xml <com.google.android.material.tabs.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabGravity="fill" app:tabMode="fixed" /> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 2. 在代码中初始化ViewPager2和TabLayout: ```java ViewPager2 viewPager = findViewById(R.id.view_pager); TabLayout tabLayout = findViewById(R.id.tab_layout); viewPager.setAdapter(new MyPagerAdapter(this)); new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> tab.setText("Tab " + (position + 1)) ).attach(); ``` 3. 创建PagerAdapter,用于管理Fragment: ```java public class MyPagerAdapter extends FragmentStateAdapter { public MyPagerAdapter(FragmentActivity fa) { super(fa); } @Override public Fragment createFragment(int position) { return new MyFragment(position + 1); } @Override public int getItemCount() { return 3; } } ``` 4. 创建Fragment,用于显示RecyclerView: ```java public class MyFragment extends Fragment { private int mTabNumber; public MyFragment(int tabNumber) { mTabNumber = tabNumber; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_my, container, false); RecyclerView recyclerView = rootView.findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); recyclerView.setAdapter(new MyRecyclerViewAdapter(mTabNumber)); return rootView; } } ``` 5. 创建RecyclerViewAdapter,用于显示数据: ```java public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> { private int mTabNumber; public MyRecyclerViewAdapter(int tabNumber) { mTabNumber = tabNumber; } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_my, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { holder.mTextView.setText("Tab " + mTabNumber + ", Item " + (position + 1)); } @Override public int getItemCount() { return 10; } public static class ViewHolder extends RecyclerView.ViewHolder { public TextView mTextView; public ViewHolder(@NonNull View itemView) { super(itemView); mTextView = itemView.findViewById(R.id.text_view); } } } ``` 6. 创建RecyclerView的item布局文件和Fragment的布局文件: item_my.xml: ```xml <TextView android:id="@+id/text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" /> ``` fragment_my.xml: ```xml <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 这样就完成了实现。每个Tab都显示一个RecyclerView,切换Tab时切换RecyclerView

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值