prefacio
Material Design es una guía completa para guiar a los usuarios en el diseño visual, de movimiento y de interacción en varias plataformas y dispositivos. Para usar Material Design en su aplicación de Android, siga las pautas definidas en la especificación de Material Design y use nuevos componentes y estilos disponibles en la Biblioteca de soporte de Material Design .
articulo principal
Diseño de materiales en Android
Como miembro de Google - Android , algunos de sus controles y efectos más representativos están empaquetados en la _Biblioteca de materiales_, lo que permite a nuestros desarrolladores materializar fácilmente sus propias aplicaciones sin saber Material Design. Por supuesto, algunos componentes de la biblioteca de AndroidX también pueden lograr algunos efectos de Material Design.
Componente BottomSheetDialogFragment
introducir
Este componente pertenece a Bottom Sheets en Material Design :
editar
BottomSheetDialogFragment hereda de AppCompatDialogFragment, interpretado oficialmente como una tabla inferior modal, que es una versión de DialogFragment, que usa BottomSheetDialog en lugar de un cuadro de diálogo flotante.
Ventaja
1. Tiene su propio ciclo de vida 2.
Puede plegar, expandir y destruir toda la página
3. Puede usar estilos personalizados de forma flexible.
Instrucciones
implementation 'com.google.android.material:material:1.7.0'
Después de agregar correctamente Sync Gradle, podemos agregar BottomSheetDialogFragment al proyecto. Es muy simple, como escribir un diálogo que hereda DialogFragment normalmente, porque hemos visto su relación de herencia en lo anterior. BottomSheetDialogFragment hereda de AppCompatDialogFragment, y AppCompatDialogFragment hereda de DialogFragment
. De esta forma, al ser BottomSheetDialogFragment una subclase de DialogFragment, tiene todas las características de DialogFragment.
Darse cuenta de los requisitos
El código de implementación de la parte Dialog :
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
}
}
Se puede ver que esta parte del código de implementación es similar a nuestro método habitual de escribir la ventana emergente inferior, pero podemos usar BottomSheetBehavior en el método onStar() para controlar el comportamiento de la ventana emergente, como el control de altura y algunas configuraciones de propiedades de la ventana emergente.
En el método onCreateDialog, agregamos el diseño de la ventana emergente y usamos el método setContentView() para obtener el diseño.Debemos escribir este método, de lo contrario, cuando obtengamos BottomSheetBehavior * val comportamiento = BottomSheetBehavior.from(view)* esta oración estará vacía
Y nuestra ventana emergente necesita esquinas redondeadas en la parte superior y elimina la sombra de fondo, por lo que se agrega el estilo:
<!--实现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>
El estilo local se llama en el código de implementación de Dialog y el método setStyle() se usa en el método onCreate.
Además, necesitamos agregar esquinas redondeadas a nuestro diseño:
<?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>
Los estilos se pueden agregar al diseño más externo del diseño de la ventana emergente que definimos
El diseño de muestra del cuadro de diálogo es el siguiente :
<?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>
Si tiene miedo de los conflictos entre el efecto táctil dentro y fuera de la ventana emergente, la forma más fácil es usar el control NestedScrollView en lugar del diseño ScrollView común.
Diseño de actividad :
<?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>
También está el código para implementar la llamada en la Actividad :
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")
}
}
}
Al medir la altura del control vllSize (la parte inferior restante), podemos establecer la altura de la primera ventana emergente a esto. Por supuesto, usted puede establecer la altura.
En el código de implementación de diálogo:
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 Configuramos la segunda vez para tirar de la ventana emergente a toda la pantalla
La ventana emergente implementada en este artículo prohíbe el deslizamiento para cerrar la ventana emergente, por lo que no se deslizará hacia abajo. El código es el control de atributo en la implementación de Diálogo. Si no está escrito, el valor predeterminado es verdadero para deslizar hacia abajo para cerrar la ventana emergente. Falso significa que este método está prohibido para cerrar la ventana emergente:
behavior.isHideable = false
efecto final:
Autor: Ru Jiayi
Dirección original