Android開発のためのUIデザイン——マテリアルデザイン

序文

マテリアル デザインは、さまざまなプラットフォームやデバイスにわたるビジュアル、モーション、インタラクションのデザインをユーザーにガイドするための包括的なガイドです。Android アプリでマテリアル デザインを使用するには、マテリアル デザイン仕様で定義されているガイドラインに従い、マテリアル デザイン サポート ライブラリで利用可能な新しいコンポーネントとスタイルを使用します。

主な記事

Android のマテリアル デザイン

Google - Androidのメンバーとして、その最も代表的なコントロールとエフェクトのいくつかは _マテリアル ライブラリ_ にパッケージ化されており、これにより開発者はマテリアル デザインを知らなくても独自のアプリケーションを簡単に具体化できます。もちろん、AndroidX ライブラリの一部のコンポーネントはマテリアル デザイン効果を実現することもできます。

BottomSheetDialogFragment コンポーネント

導入

このコンポーネントは、マテリアル デザインのボトム シートに属します。

編集

BottomSheetDialogFragment は、フローティング ダイアログの代わりに BottomSheetDialog を使用する DialogFragment のバージョンであるモーダル ボトム テーブルとして正式に解釈される AppCompatDialogFragment を継承します。

アドバンテージ

1. 独自のライフサイクルを持っています;
2. ページ全体を折りたたんだり、展開したり、破棄したりできます;
3. カスタム スタイルを柔軟に使用できます。

手順

implementation 'com.google.android.material:material:1.7.0'

Sync Gradle が正常に追加されたら、BottomSheetDialogFragment をプロジェクトに追加できます。これは、DialogFragment を継承する Dialog を通常に記述するのと同じように非常に簡単です。これは、その継承関係を上記で確認したためです。BottomSheetDialogFragment は AppCompatDialogFragment から継承し、AppCompatDialogFragment は DialogFragment から継承します
このように、BottomSheetDialogFragment は DialogFragment のサブクラスであるため、DialogFragment のすべての特性を備えています。

要件を実現する

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
    }

}

実装コードのこの部分は、下部のポップアップ ウィンドウを記述する通常の方法と似ていることがわかりますが、onStar() メソッドで BottomSheetBehavior を使用して、高さの制御やポップアップ ウィンドウの一部のプロパティ設定など、ポップアップ ウィンドウ自体の動作を制御できます。

onCreateDialog メソッドでは、ポップアップ ウィンドウのレイアウトを追加し、setContentView() メソッドを使用してレイアウトを取得します。このメソッドを書かないと、BottomSheetBehavior * val behavior = BottomSheetBehavior.from(view)* を取得したときにこの文が空になります。

また、ポップアップ ウィンドウの上部の角を丸くする必要があり、背景の影を削除するため、スタイルが追加されます。

<!--实现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>

ローカル スタイルは Dialog 実装コードで呼び出され、onCreate メソッドで setStyle() メソッドが使用されます。


また、レイアウトに丸い角を追加する必要があります。

<?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>

スタイルは、定義したポップアップ ウィンドウ レイアウトの最も外側のレイアウトに追加できます。

ダイアログのサンプル レイアウトは次のとおりです

<?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>

ポップアップ ウィンドウの内側と外側のタッチ効果の競合が心配な場合、最も簡単な方法は、通常の ScrollView レイアウトの代わりに NestedScrollView コントロールを使用することです。

アクティビティのレイアウト:

<?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>

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")
        }
    }
}

vllSize コントロール (残りの下部) の高さを測定することで、最初のポップアップ ウィンドウの高さをこれに設定できます。もちろん、高さはユーザーが設定できます。

Dialog 実装コードでは次のようになります。

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 ポップアップ ウィンドウを画面全体にプルする 2 回目の時間を設定します

この記事で実装されたポップアップ ウィンドウは、ポップアップ ウィンドウを閉じるためのスライドを禁止しているため、下にスライドしません。コードは、Dialog 実装の属性コントロールです。記述されていない場合、デフォルトは true で、下にスライドしてポップアップ ウィンドウを閉じます。False は、このメソッドがポップアップ ウィンドウを閉じることが禁止されていることを意味します。

behavior.isHideable = false

最終的な効果:


著者: Ru Jiayi
元アドレス

おすすめ

転載: blog.csdn.net/fjnu_se/article/details/128173238