BottomSheetDialog使用

说明

这里只实现基本操作,复杂的操作在基础上添加即可。

实现如下效果

Demo
添加依赖

两个依赖,一个recyclerView的,一个Material库的。BottomSheetDialog就是Material库中的。

1
2
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.android.material:material:1.0.0'
Fruit类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Fruit {
private int id;
private String name;

public Fruit(int id, String name) {
this.id = id;
this.name = name;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

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

RecyclerView中子项的布局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal">
<TextView
android:id="@+id/fruit_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="1"
android:gravity="center"/>
<TextView
android:id="@+id/fruit_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="樱桃"
android:gravity="center"/>

</LinearLayout>
FruitAdapter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {

private List<Fruit> fruits;

public FruitAdapter(List<Fruit> fruits) {
this.fruits = fruits;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,parent,false);
return new ViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Fruit fruit = fruits.get(position);
holder.tv_id.setText(fruit.getId()+"");
holder.tv_name.setText(fruit.getName());
}


@Override
public int getItemCount() {
return fruits.size();
}

class ViewHolder extends RecyclerView.ViewHolder{

TextView tv_id;
TextView tv_name;
public ViewHolder(@NonNull View view) {
super(view);
tv_id = view.findViewById(R.id.fruit_id);
tv_name = view.findViewById(R.id.fruit_name);
}
}
}
activity_bottom_sheet_dialog.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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"
tools:context=".BottomSheetDialogActivity">

<Button
android:id="@+id/btn_show"
android:text="弹出"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
dialog_bottomsheet.xml

弹窗的布局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="600dp"
android:orientation="vertical">

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="水果列表"
android:textStyle="bold"/>
</RelativeLayout>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/dialog_recycleView"
android:layout_width="match_parent"
android:layout_height="500dp"/>
</LinearLayout>
BottomSheetDialogActivity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
public class BottomSheetDialogActivity extends AppCompatActivity {

private BottomSheetDialog bottomSheetDialog;
private BottomSheetBehavior mDialogBehavior;
private RecyclerView recyclerView;
private FruitAdapter adapter;
private Button btn;
private List<Fruit> fruits = new ArrayList<>();
private String[] fruitNames = {"苹果","香蕉","樱桃","草莓","橘子"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bottom_sheet_dialog);
btn = findViewById(R.id.btn_show);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
initData();
showSheetDialog();
bottomSheetDialog.show();
}
});
}

private void showSheetDialog() {
View view = View.inflate(BottomSheetDialogActivity.this,R.layout.dialog_bottomsheet,null);
recyclerView = view.findViewById(R.id.dialog_recycleView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new FruitAdapter(fruits);
recyclerView.setAdapter(adapter);

bottomSheetDialog = new BottomSheetDialog(BottomSheetDialogActivity.this,R.style.dialog); //该style样式在最后说明了
bottomSheetDialog.setContentView(view);
bottomSheetDialog.setCanceledOnTouchOutside(true);
//设置背景为透明
bottomSheetDialog.getWindow().findViewById(R.id.design_bottom_sheet).setBackgroundResource(android.R.color.transparent);
mDialogBehavior = BottomSheetBehavior.from((View)view.getParent());
mDialogBehavior.setPeekHeight(getPeekHeight()); //设置高度

}

/**
* 弹窗高度,默认为屏幕高度的四分之三
* 子类可重写该方法返回peekHeight
*
* @return height
*/
private int getPeekHeight() {
int peekHeight = getResources().getDisplayMetrics().heightPixels;
//设置弹窗高度为屏幕高度的3/4
return peekHeight - peekHeight/4;
}


private void initData() {
Random random = new Random();
for (int i = 1; i <= 30; i++) {
fruits.add(new Fruit(i,fruitNames[random.nextInt(5)]));
}
}
}
其他文件

enter_bottom_menu:

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromYDelta="100%p"
android:toYDelta="0" />
<alpha
android:duration="300"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
</set>

exit_bottom_menu:

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromYDelta="0"
android:toYDelta="100%p"/>
<alpha
android:duration="300"
android:fromAlpha="1.0"
android:toAlpha="0.0"/>
</set>
style样式

将下面这段添加到 res -> values -> styles 中即可引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- dialog从ios效果动画 -->
<style name="BottomShowAnimation" parent="@android:style/Animation.Dialog">
<item name="android:windowEnterAnimation">@anim/enter_bottom_menu</item>
<item name="android:windowExitAnimation">@anim/exit_bottom_menu</item>

</style>

<style name="dialog" parent="@android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:background">@android:color/transparent</item>
<item name="android:windowBackground">@android:color/transparent</item>
<!-- Dialog进入及退出动画 -->
<item name="android:windowAnimationStyle">@style/BottomShowAnimation</item>
<!--弹窗背景是否变暗-->
<item name="android:backgroundDimEnabled">false</item>
</style>
0%