Android 仿百度搜索地点列表Rv Pager Snap横向

2023-12-10  本文已影响0人  Pino

废话少说,先看百度的效果

Rv Pager Snap.gif
分析功能

1.rv是Snap模式,单个滑动
2.然后item可以上拉展开详细信息

一开始我的思路错了,给每一个 item添加手势监听,结果是item在rv范围内根本没法上拉
后来转换了一种思路会不会rv就是嵌套上啦的面板里面呢?

然后通过使用代码实现了一下,发现还是真是如此
具体效果如下


Rv Pager Snap_01.gif
思路主要是把rv嵌套早bottomSheet当中,这样其实rv也会被上拉起来

当我们上拉的时候,隐藏掉rv,同时显示rv当前item的内容,具体可以查看代码
我使用的viewmodel封装的基类,如果没有使用可以自己魔改一下,最主要核心是上拉的时候,判断上拉了多少后开始隐藏rv
并实现rv对应item的内容

public class RvPagerSnapActivity extends BaseVMActivity<ActivityRvPagerSnapBinding, HouseListViewModel> {
    int currentPostion = -1;
    BottomSheetBehavior behavior;
    float slideOffset;
    boolean isDragUp=false;
    float centerValue=0.26f;

    @Override
    protected int initLayout() {
        return R.layout.activity_rv_pager_snap;
    }

    @Override
    protected void initView() {
//        setToolbarShow(false);
        initList();
//        Drawable background = binding.bottomSheet.getBackground();
//        int color = ((ColorDrawable) background).getColor();
//        binding.bottomSheet.setBackground(getBgDrawable(16,color));
        // 获取底部抽屉
        behavior = BottomSheetBehavior.from(binding.bottomSheet);
        behavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                Log.e(TAG, "newState: " + newState);
                if (newState == BottomSheetBehavior.STATE_SETTLING) {
                    // 在用户松开手指后,滚动到最终位置时执行操作
                    if(isDragUp){
                        if (0.02 < slideOffset && slideOffset < centerValue) {
                            behavior.setState(BottomSheetBehavior.STATE_HALF_EXPANDED);
                        } else if (slideOffset > centerValue) {
                            behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                        } else {
                            behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
                        }
                    }else{
                        if (slideOffset < centerValue) {
                            behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
                        } else if (slideOffset > centerValue && slideOffset < 1.0) {
                            behavior.setState(BottomSheetBehavior.STATE_HALF_EXPANDED);
                        }
                    }

                }
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float newSlideOffset) {
                binding.rvList.setVisibility(slideOffset > 0.02f ? View.GONE : View.VISIBLE);
                binding.llyContent.setVisibility(slideOffset > 0.02f ? View.VISIBLE : View.GONE);
                isDragUp=newSlideOffset-slideOffset>0;
                slideOffset = newSlideOffset;
            }
        });
    }

    @Override
    public int initVariableId() {
        return BR.viewModel;
    }

    @Override
    protected void initVMObserve() {
        viewModel.initData();
        viewModel.selectIndex.setValue(0);
    }

    private void initList() {
        PagerSnapHelper snapHelper = new PagerSnapHelper();
        snapHelper.attachToRecyclerView(binding.rvList);

        binding.rvList.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
                    View snapView = snapHelper.findSnapView(layoutManager);
                    if (layoutManager != null && snapView != null) {
                        int currentPageIndex = layoutManager.getPosition(snapView);
                        if (currentPostion != currentPageIndex) {// 防止重复提示
                            currentPostion = currentPageIndex;
                            Log.e("Tag", "当前是第" + currentPostion + "页");
                            viewModel.selectIndex.setValue(currentPostion);
                        }
                    }
                }
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                Log.d(TAG, "dy:" + dy);
            }
        });
    }


    public GradientDrawable getBgDrawable(int radius1, int color){
        int radius= dip2px(radius1); // 转化为dp
        float[] newRadius = {radius, radius, radius, radius, 0, 0, 0, 0};
        GradientDrawable drawable = new GradientDrawable();
        drawable.setCornerRadii(newRadius);
        drawable.setColor(color);
        return drawable;
    }

    public  int dip2px(float dipValue) {
        final float scale = getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }
}

布局文件如下

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable
            name="viewModel"
            type="com.uni.databindingdemo.viewModel.HouseListViewModel" />
    </data>
    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:id="@+id/cdl_root"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/main_blue"
        >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:gravity="center">
        </LinearLayout>

        <FrameLayout
            android:id="@+id/bottom_sheet"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/white"
            app:behavior_hideable="true"
            app:behavior_peekHeight="230dp"
            app:elevation="6dp"
            app:layout_behavior="@string/bottom_sheet_behavior">
            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/rv_list"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                app:itemBinding="@{viewModel.itemBinding}"
                app:items="@{viewModel.list}"
                app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
                />
           <LinearLayout
               android:id="@+id/lly_content"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:orientation="vertical"
               android:gravity="center"
               android:visibility="invisible"
               >
               <LinearLayout
                   android:id="@+id/lly_top_btn"
                   android:layout_width="match_parent"
                   android:layout_height="24dp"
                   android:gravity="center"
                   android:orientation="horizontal"
                   android:clickable="false"
                   >
                   <View
                       android:layout_width="80dp"
                       android:layout_height="5dp"
                       android:background="@drawable/half_round_backgroud_gray" />
               </LinearLayout>
               <TextView
                   android:layout_width="wrap_content"
                   android:layout_height="wrap_content"
                   android:padding="@dimen/dp_10"
                   android:textColor="@color/white"
                   android:text="@{`当前选中position:`+viewModel.selectIndex}"
                   />
               <ImageView
                   android:id="@+id/iv_logo"
                   android:layout_width="wrap_content"
                   android:layout_height="wrap_content"
                   android:src="@mipmap/ic_logo"
                   />
           </LinearLayout>
        </FrameLayout>
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

half_round_backgroud_gray.xml

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle"
    android:color="@color/white">
    <corners
        android:radius="60dip"
        />
    <stroke
        android:width="0dp"
        android:color="@color/white" />
    <solid
        android:color=" #D3D3D3" />
</shape>

上一篇下一篇

猜你喜欢

热点阅读