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>