foreword
Material Design is a comprehensive guide to guide users in visual, motion and interaction design across various platforms and devices. To use Material Design in your Android app, follow the guidelines defined in the Material Design specification and use new components and styles available in the Material Design Support Library .
Main article
Material Design in Android
As a member of Google - Android , some of its most representative controls and effects are packaged in the _Material library_, which allows our developers to easily materialize their own applications without knowing Material Design. Of course, some components in the AndroidX library can also achieve some Material Design effects.
BottomSheetDialogFragment component
introduce
This component belongs to Bottom Sheets in Material Design :
edit
BottomSheetDialogFragment inherits from AppCompatDialogFragment, officially interpreted as a modal bottom table, which is a version of DialogFragment, which uses BottomSheetDialog instead of floating dialog.
Advantage
1. It has its own life cycle ;
2. It can fold, expand and destroy the entire page;
3. It can flexibly use custom styles.
Instructions
implementation 'com.google.android.material:material:1.7.0'
After the Sync Gradle is successfully added, we can add BottomSheetDialogFragment to the project. It is very simple, just like writing a Dialog that inherits DialogFragment normally, because we have seen its inheritance relationship in the above. BottomSheetDialogFragment inherits from AppCompatDialogFragment, and AppCompatDialogFragment inherits from DialogFragment
. In this way, since BottomSheetDialogFragment is a subclass of DialogFragment, it has all the characteristics of DialogFragment.
Realize requirements
The implementation code of the Dialog part :
class DialogMore : BottomSheetDialogFragment() {
private var height : Int = 0
fun newInstance(): DialogMore {
return DialogMore()
}
fun setDialogHeight(height: Int): DialogMore {
this.height = height
return this
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NORMAL, R.style.StyleBottomSheetDialogBg)
}
override fun onStart() {
super.onStart()
//拿到系统的 bottom_sheet
val bottomSheetDialog = (dialog as BottomSheetDialog?)!!
val view =
bottomSheetDialog.delegate.findViewById<FrameLayout>(com.google.android.material.R.id.design\_bottom\_sheet)!!
val behavior = BottomSheetBehavior.from(view)
//设置弹出高度
behavior.peekHeight = height
view.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
behavior.isHideable = false
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState)
val view = LayoutInflater.from(context).inflate(R.layout.layout\_item\_dialog_more, null)
dialog.setContentView(view)
view.vDownClose.setOnClickListener {
dismiss()
}
return dialog
}
}
It can be seen that this part of the implementation code is similar to our usual method of writing the bottom pop-up window, but we can use BottomSheetBehavior in the onStar() method to control the behavior of the pop-up window itself, such as height control and some property settings of the pop-up window
In the onCreateDialog method, we add the layout of the pop-up window and use the setContentView() method to get the layout. We must write this method, otherwise when we get BottomSheetBehavior * val behavior = BottomSheetBehavior.from(view)* this sentence will be empty
And our pop-up window needs rounded corners at the top and removes the background shadow, so the style is added:
<!--实现BottomSheetDialog圆角效果 且无背景阴影-->
<style name="StyleBottomSheetDialogBg" parent="Theme.Design.Light.BottomSheetDialog">
<item name="bottomSheetStyle">@style/StyleBottomSheetStyleWrapper</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
<style name="StyleBottomSheetStyleWrapper" parent="Widget.Design.BottomSheet.Modal">
<item name="android:background">@android:color/transparent</item>
</style>
The local style is called at the Dialog implementation code, and the setStyle() method is used in the onCreate method.
Also, we need to add rounded corners to our layout:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners
android:topLeftRadius="15dp"
android:topRightRadius="15dp" />
<solid android:color="@color/white" />
</shape>
Styles can be added to the outermost layout of the popup window layout we defined
The Dialog sample layout is as follows :
<?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:background="@drawable/shape\_sheet\_dialog_bg"
android:orientation="vertical">
<LinearLayout
android:layout\_width="match\_parent"
android:layout\_height="wrap\_content"
android:layout_gravity="center"
android:paddingTop="10dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:gravity="center"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/vDownClose"
android:layout_width="48dp"
android:layout\_height="wrap\_content"
android:layout_marginStart="16dp"
android:layout_gravity="center"
android:src="@drawable/vector\_invite\_comment_close" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/vTitle"
android:layout\_width="match\_parent"
android:layout\_height="wrap\_content"
android:gravity="center"
android:text="More Content"
android:textColor="@color/black"
android:textSize="16sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/vPositionEdit"
android:layout_width="48dp"
android:layout\_height="wrap\_content"
android:layout_marginEnd="16dp"
android:text=""
android:textColor="@color/black"
android:textSize="16sp" />
</LinearLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/vNsPosition"
android:layout\_width="match\_parent"
android:layout\_height="match\_parent">
<LinearLayout
android:layout\_width="match\_parent"
android:layout\_height="wrap\_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/llPtz"
android:layout\_width="match\_parent"
android:layout_height="8dp"
android:gravity="center"
android:orientation="horizontal">
</LinearLayout>
<LinearLayout
android:id="@+id/vLlPosition"
android:layout\_width="match\_parent"
android:layout\_height="match\_parent"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatImageView
android:layout\_width="match\_parent"
android:layout_height="300dp"
android:src="@mipmap/ic\_more\_content"
android:scaleType="fitCenter"/>
<androidx.appcompat.widget.AppCompatTextView
android:layout\_width="match\_parent"
android:layout\_height="wrap\_content"
android:layout_marginTop="20dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="1.可以弹出弹窗,且弹窗可以继续拉到顶部。"
android:textSize="14dp"
android:textColor="#FF666666"/>
<androidx.appcompat.widget.AppCompatTextView
android:layout\_width="match\_parent"
android:layout\_height="wrap\_content"
android:layout_marginTop="5dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="2.禁止下拉关闭弹窗,使下滑到固定位置后不会再动,关闭弹窗使用关闭按钮。"
android:textSize="14sp"
android:textColor="#FF666666"/>
</LinearLayout>
<LinearLayout
android:id="@+id/vLlNoPosition"
android:layout\_width="match\_parent"
android:layout_height="277dp"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/vNoPositionText"
android:layout\_width="match\_parent"
android:layout\_height="match\_parent"
android:layout_gravity="center"
android:gravity="center"
android:text="无更多内容"
android:textSize="14sp"
android:textColor="#FF666666"/>
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
If you are afraid of conflicts between the touch effect inside and outside the pop-up window, the easiest way is to use the NestedScrollView control instead of the ordinary ScrollView layout
Activity layout :
<?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=".MainActivity"
android:orientation="vertical">
<LinearLayout
android:layout\_width="match\_parent"
android:layout_height="56dp"
android:orientation="horizontal">
<LinearLayout
android:layout_width="56dp"
android:layout_height="56dp"
android:orientation="horizontal"
android:gravity="center">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="16dp"
android:layout\_height="match\_parent"
android:src="@drawable/vector\_arrow\_back"
android:scaleType="fitCenter"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="56dp"
android:layout_weight="1"
android:gravity="center"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatTextView
android:layout\_width="wrap\_content"
android:layout\_height="wrap\_content"
android:textStyle="bold"
android:text="弹窗样例"
android:textColor="@color/black"
android:textSize="16sp"
app:autoSizeMaxTextSize="16sp"
app:autoSizeMinTextSize="8dp"
app:autoSizeTextType="uniform"
android:maxLines="1"/>
</LinearLayout>
<LinearLayout
android:layout_width="56dp"
android:layout_height="56dp" />
</LinearLayout>
<androidx.appcompat.widget.AppCompatImageView
android:layout\_width="wrap\_content"
android:layout\_height="wrap\_content"
android:src="@mipmap/ic\_play\_demo"
android:scaleType="center"/>
<LinearLayout
android:layout\_width="match\_parent"
android:layout_height="56dp"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="0dp"
android:layout_height="56dp"
android:layout_weight="1"
android:src="@mipmap/ic\_top\_up"
android:scaleType= "fitCenter"/>
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="0dp"
android:layout_height="56dp"
android:layout_weight="1"
android:src="@mipmap/ic_transfer"
android:scaleType= "fitCenter"/>
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="0dp"
android:layout_height="56dp"
android:layout_weight="1"
android:src="@mipmap/ic_withdraw"
android:scaleType= "fitCenter"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/vMore"
android:layout_width="0dp"
android:layout_height="56dp"
android:layout_weight="1"
android:src="@mipmap/ic_more"
android:scaleType= "fitCenter"/>
</LinearLayout>
<LinearLayout
android:id="@+id/vllSize"
android:layout\_width="match\_parent"
android:layout\_height="match\_parent"
android:background="@color/white"
android:orientation="vertical"/>
</LinearLayout>
There is also the code to implement the call in the Activity :
class MainActivity : AppCompatActivity() {
private var dialogHeight : Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
// 获取dialog的高度
dialogHeight = vllSize.measuredHeight
// 获取dialog的高度
Log.d( "MainActivity" ,"height = $dialogHeight")
}
override fun onResume() {
super.onResume()
vMore.setOnClickListener {
val dialog = DialogMore().newInstance()
.setDialogHeight(dialogHeight)
val ft: FragmentTransaction =
supportFragmentManager.beginTransaction()
ft.setTransition(FragmentTransaction.TRANSIT\_FRAGMENT\_FADE)
dialog.show(ft, "DialogMore")
}
}
}
By measuring the height of the vllSize control (the remaining bottom), we can set the height of the first pop-up window to this. Of course, the height can be set by you.
In the Dialog implementation code:
override fun onStart() {
super.onStart()
//拿到系统的 bottom_sheet
val bottomSheetDialog = (dialog as BottomSheetDialog?)!!
val view =
bottomSheetDialog.delegate.findViewById<FrameLayout>(com.google.android.material.R.id.design\_bottom\_sheet)!!
val behavior = BottomSheetBehavior.from(view)
//设置弹出高度
behavior.peekHeight = height
view.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
behavior.isHideable = false
}
view.layoutParams.height We set the second time to pull the pop-up window to the entire screen
The pop-up window implemented in this article prohibits the sliding to close the pop-up window, so it will not slide to the bottom. The code is the attribute control in the Dialog implementation. If it is not written, the default is true to slide down to close the pop-up window. False means that this method is prohibited to close the pop-up window:
behavior.isHideable = false
final effect:
Author: Ru Jiayi
Original Address