实现的效果图:
自定义Fragment继承BottomSheetDialogFragment
重写它的三个方法:
onCreateDialog()
onCreateView()
onStart()
他们的执行顺序是从上到下
import android.app.Dialog; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.ImageView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.bottomsheet.BottomSheetDialog; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import java.util.ArrayList; import java.util.List; /** * @Author: david.lvfujiang * @Date: 2019/11/14 * @Describe: */ public class BaseFullBottomSheetFragment extends BottomSheetDialogFragment { private List<ShareItem> mShareList = new ArrayList<>(); private int[] imgArry= {R.mipmap.five,R.mipmap.four,R.mipmap.one,R.mipmap.three}; private Context mContext; private View view; public static BaseFullBottomSheetFragment getInstance() { return new BaseFullBottomSheetFragment(); } @NonNull @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { Log.e("TAG", "onCreateDialog: "); //返回BottomSheetDialog的实例 return new BottomSheetDialog(this.getContext()); } @Override public void onStart() { Log.e("TAG", "onStart: "); super.onStart(); //获取dialog对象 BottomSheetDialog dialog = (BottomSheetDialog) getDialog(); //把windowsd的默认背景颜色去掉,不然圆角显示不见 dialog.getWindow().findViewById(R.id.design_bottom_sheet).setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); //获取diglog的根部局 FrameLayout bottomSheet = dialog.getDelegate().findViewById(R.id.design_bottom_sheet); if (bottomSheet != null) { //获取根部局的LayoutParams对象 CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) bottomSheet.getLayoutParams(); layoutParams.height = getPeekHeight(); //修改弹窗的最大高度,不允许上滑(默认可以上滑) bottomSheet.setLayoutParams(layoutParams); final BottomSheetBehavior<FrameLayout> behavior = BottomSheetBehavior.from(bottomSheet); //peekHeight即弹窗的最大高度 behavior.setPeekHeight(getPeekHeight()); // 初始为展开状态 behavior.setState(BottomSheetBehavior.STATE_EXPANDED); ImageView mReBack = view.findViewById(R.id.re_back_img); //设置监听 mReBack.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //关闭弹窗 behavior.setState(BottomSheetBehavior.STATE_HIDDEN); } }); } } /** * 弹窗高度,默认为屏幕高度的四分之三 * 子类可重写该方法返回peekHeight * * @return height */ protected int getPeekHeight() { int peekHeight = getResources().getDisplayMetrics().heightPixels; //设置弹窗高度为屏幕高度的3/4 return peekHeight - peekHeight / 3; } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { mContext = getContext(); Log.e("TAG", "onCreateView: "); view = inflater.inflate(R.layout.layoyt_bottomsheet, container, false); initData(); initViews(view); return view; } private void initViews(View view) { RecyclerView recyclerView = view.findViewById(R.id.fragment_share_recyclerView); recyclerView.setLayoutManager(new GridLayoutManager(mContext, 3)); RecyclerCommonAdapter adapter = new RecyclerCommonAdapter(R.layout.recyclear_item, mShareList); recyclerView.setAdapter(adapter); } private void initData() { for (int i = 0; i < 30; i++) { ShareItem item = new ShareItem(); item.setIcon(imgArry[i%4]); mShareList.add(item); } } }
有以下几点需要注意:
1.去掉窗口的background,窗口的background默认是白色的,如果不处理我们的根部局设置圆角背景的时候是没有效果的
dialog.getWindow().findViewById(R.id.design_bottom_sheet).setBackgroundDrawable (new ColorDrawable (Color.TRANSPARENT));
2.固定窗口的高度,窗口默认可以向上滑动直到铺满整个屏幕RecyclerView才开始滑动
BottomSheetDialog dialog = (BottomSheetDialog) getDialog(); //把windowsd的默认背景颜色去掉,不然圆角显示不见 dialog.getWindow().findViewById(R.id.design_bottom_sheet).setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); //获取diglog的根部局 FrameLayout bottomSheet = dialog.getDelegate().findViewById(R.id.design_bottom_sheet); if (bottomSheet != null) { //获取根部局的LayoutParams对象 CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) bottomSheet.getLayoutParams(); layoutParams.height = getPeekHeight(); //修改弹窗的最大高度,不允许上滑(默认可以上滑) bottomSheet.setLayoutParams(layoutParams); final BottomSheetBehavior<FrameLayout> behavior = BottomSheetBehavior.from(bottomSheet); //peekHeight即弹窗的最大高度 behavior.setPeekHeight(getPeekHeight()); // 初始为展开状态 behavior.setState(BottomSheetBehavior.STATE_EXPANDED); ImageView mReBack = view.findViewById(R.id.re_back_img); //设置监听 mReBack.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //关闭弹窗 behavior.setState(BottomSheetBehavior.STATE_HIDDEN); } }); }
3.Fragment加载的布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/leave_message_radiobutton_background" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="@dimen/dp_40"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="100条评论" android:textSize="15dp" android:textStyle="bold"></TextView> <ImageView android:id="@+id/re_back_img" android:layout_width="25dp" android:layout_height="25dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="20dp" android:src="@mipmap/back"></ImageView> </RelativeLayout> <androidx.recyclerview.widget.RecyclerView android:id="@+id/fragment_share_recyclerView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginBottom="8dp" /> </LinearLayout>
4.Fragment布局的圆角背景
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <!-- 填充 --> <solid android:color="#ffffff" /> <!-- 圆角 --> <corners android:radius="15dp" /> </shape>
5.RecyclerView的item布局
<?xml version="1.0" encoding="utf-8"?> <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="140dp" android:layout_margin="8dp" app:cardCornerRadius="8dp" app:cardElevation="4dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:padding="8dp"> <ImageView android:id="@+id/img_recy_item_1_pic" android:layout_width="140dp" android:src="@mipmap/three" android:layout_height="match_parent" android:scaleType="centerCrop" /> </RelativeLayout> </androidx.cardview.widget.CardView>
6.RecyclerView适配器是用BaseRecyclerViewAdapterHelper
Android 中RecyclerView通用适配器的实现
package com.example.bottomsheetdialogapplication; import androidx.annotation.Nullable; import com.chad.library.adapter.base.BaseQuickAdapter; import com.chad.library.adapter.base.BaseViewHolder; import java.util.List; import java.util.Map; /** * @Author: david.lvfujiang * @Date: 2019/10/30 * @Describe: */ public class RecyclerCommonAdapter extends BaseQuickAdapter<ShareItem, BaseViewHolder> { public RecyclerCommonAdapter(int layoutResId, @Nullable List<ShareItem> data) { super(layoutResId, data); } @Override protected void convert(BaseViewHolder helper, ShareItem item) { helper.setImageResource(R.id.img_recy_item_1_pic, item.getIcon()); helper.addOnClickListener(R.id.img_recy_item_1_pic); } }
7. 调用
Button button = findViewById(R.id.on); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { new BaseFullBottomSheetFragment().show(getSupportFragmentManager(), "dialog"); } });