UI Design for Android Development——Material Design

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

Guess you like

Origin blog.csdn.net/fjnu_se/article/details/128173238