Android Dialog 스타일 수정 방법

16862 단어 AndroidDialog

1. Dialog 소스 분석


1.1 new AlertDialog.Builder(this).create()


    protected AlertDialog(@NonNull Context context, @StyleRes int themeResId) {
        super(context, resolveDialogTheme(context, themeResId));
        // AlertController, Dialog 
        mAlert = new AlertController(getContext(), this, getWindow());
    }

        @NonNull
        public AlertDialog create() {
            // We can't use Dialog's 3-arg constructor with the createThemeContextWrapper param,
            // so we always have to re-set the theme
            final AlertDialog dialog = new AlertDialog(P.mContext, mTheme);
            P.apply(dialog.mAlert);
            dialog.setCancelable(P.mCancelable);
            if (P.mCancelable) {
                dialog.setCanceledOnTouchOutside(true);
            }
            dialog.setOnCancelListener(P.mOnCancelListener);
            dialog.setOnDismissListener(P.mOnDismissListener);
            if (P.mOnKeyListener != null) {
                dialog.setOnKeyListener(P.mOnKeyListener);
            }
            return dialog;
        }

        public void apply(AlertController dialog) {
            if (mCustomTitleView != null) {
                dialog.setCustomTitle(mCustomTitleView);
            } else {
                if (mTitle != null) {
                    dialog.setTitle(mTitle);
                }
                if (mIcon != null) {
                    dialog.setIcon(mIcon);
                }
                if (mIconId != 0) {
                    dialog.setIcon(mIconId);
                }
            ..........
  • AlertDialog 구조 함수에 대화상자의 레이아웃을 제어하는 AlertController가 생성됩니다
  • P.apply(dialog.mAlert); 사용자 정의 구성을 AlertController에 할당
  • 1.2 AlertController

    
        public AlertController(Context context, AppCompatDialog di, Window window) {
            mContext = context;
            mDialog = di;
            mWindow = window;
            mHandler = new ButtonHandler(di);
    
            final TypedArray a = context.obtainStyledAttributes(null, R.styleable.AlertDialog,
                    R.attr.alertDialogStyle, 0);
    
            mAlertDialogLayout = a.getResourceId(R.styleable.AlertDialog_android_layout, 0);
            mButtonPanelSideLayout = a.getResourceId(R.styleable.AlertDialog_buttonPanelSideLayout, 0);
    
            mListLayout = a.getResourceId(R.styleable.AlertDialog_listLayout, 0);
            mMultiChoiceItemLayout = a.getResourceId(R.styleable.AlertDialog_multiChoiceItemLayout, 0);
            mSingleChoiceItemLayout = a
                    .getResourceId(R.styleable.AlertDialog_singleChoiceItemLayout, 0);
            mListItemLayout = a.getResourceId(R.styleable.AlertDialog_listItemLayout, 0);
            mShowTitle = a.getBoolean(R.styleable.AlertDialog_showTitle, true);
            mButtonIconDimen = a.getDimensionPixelSize(R.styleable.AlertDialog_buttonIconDimen, 0);
    
            a.recycle();
    
            /* We use a custom title so never request a window title */
            di.supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        }
    
    R.attr.alertDialogStyle은 대화 상자의 기본 스타일입니다.
    
            <item name="alertDialogStyle">@style/AlertDialog.AppCompat</item>
            <style name="AlertDialog.AppCompat" parent="Base.AlertDialog.AppCompat"/>
          	<style name="Base.AlertDialog.AppCompat" parent="android:Widget">
            	<item name="android:layout">@layout/abc_alert_dialog_material</item>
            	<item name="listLayout">@layout/abc_select_dialog_material</item>
           	 	<item name="listItemLayout">@layout/select_dialog_item_material</item>
            	<item name="multiChoiceItemLayout">@layout/select_dialog_multichoice_material</item>
            	<item name="singleChoiceItemLayout">@layout/select_dialog_singlechoice_material</item>
            	<item name="buttonIconDimen">@dimen/abc_alert_dialog_button_dimen</item>
        	</style>      
    
    상기 코드를 보면 abc_alert_dialog_material은 dialog의 기본 레이아웃입니다.
    
    <androidx.appcompat.widget.AlertDialogLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/parentPanel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="start|left|top"
        android:orientation="vertical">
    
        <include layout="@layout/abc_alert_dialog_title_material"/>
    
        <FrameLayout
            android:id="@+id/contentPanel"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="48dp">
    
            <View android:id="@+id/scrollIndicatorUp"
                  android:layout_width="match_parent"
                  android:layout_height="1dp"
                  android:layout_gravity="top"
                  android:background="?attr/colorControlHighlight"
                  android:visibility="gone"/>
    
            <androidx.core.widget.NestedScrollView
                android:id="@+id/scrollView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:clipToPadding="false">
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">
    
                    <android.widget.Space
                        android:id="@+id/textSpacerNoTitle"
                        android:layout_width="match_parent"
                        android:layout_height="@dimen/abc_dialog_padding_top_material"
                        android:visibility="gone"/>
    
                    <TextView
                        android:id="@android:id/message"
                        style="@style/TextAppearance.AppCompat.Subhead"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:paddingLeft="?attr/dialogPreferredPadding"
                        android:paddingRight="?attr/dialogPreferredPadding"/>
    
                    <android.widget.Space
                        android:id="@+id/textSpacerNoButtons"
                        android:layout_width="match_parent"
                        android:layout_height="@dimen/abc_dialog_padding_top_material"
                        android:visibility="gone"/>
                </LinearLayout>
            </androidx.core.widget.NestedScrollView>
    
            <View android:id="@+id/scrollIndicatorDown"
                  android:layout_width="match_parent"
                  android:layout_height="1dp"
                  android:layout_gravity="bottom"
                  android:background="?attr/colorControlHighlight"
                  android:visibility="gone"/>
    
        </FrameLayout>
    
        <FrameLayout
            android:id="@+id/customPanel"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="48dp">
    
            <FrameLayout
                android:id="@+id/custom"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
        </FrameLayout>
    
        <include layout="@layout/abc_alert_dialog_button_bar_material"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"/>
    
    </androidx.appcompat.widget.AlertDialogLayout>
    
    제목 레이아웃:
    
    <!-- abc_alert_dialog_title_material: -->
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:id="@+id/topPanel"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:orientation="vertical">
    
        <!-- If the client uses a customTitle, it will be added here. -->
    
        <LinearLayout
            android:id="@+id/title_template"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical|start|left"
            android:orientation="horizontal"
            android:paddingLeft="?attr/dialogPreferredPadding"
            android:paddingRight="?attr/dialogPreferredPadding"
            android:paddingTop="@dimen/abc_dialog_padding_top_material">
    
            <ImageView
                android:id="@android:id/icon"
                android:layout_width="32dip"
                android:layout_height="32dip"
                android:layout_marginEnd="8dip"
                android:layout_marginRight="8dip"
                android:scaleType="fitCenter"
                android:src="@null"/>
    
            <androidx.appcompat.widget.DialogTitle
                android:id="@+id/alertTitle"
                style="?android:attr/windowTitleStyle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="start"
                android:ellipsize="end"
                android:singleLine="true"
                android:textAlignment="viewStart"/>
    
        </LinearLayout>
    
        <android.widget.Space
            android:id="@+id/titleDividerNoCustom"
            android:layout_width="match_parent"
            android:layout_height="@dimen/abc_dialog_title_divider_material"
            android:visibility="gone"/>
    </LinearLayout>
    
    버튼 레이아웃:
    
    <!-- abc_alert_dialog_button_bar_material: -->
    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/buttonPanel"
                style="?attr/buttonBarStyle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:fillViewport="true"
                android:scrollIndicators="top|bottom">
    
        <androidx.appcompat.widget.ButtonBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="bottom"
            android:layoutDirection="locale"
            android:orientation="horizontal"
            android:paddingBottom="4dp"
            android:paddingLeft="12dp"
            android:paddingRight="12dp"
            android:paddingTop="4dp">
    
            <Button
                android:id="@android:id/button3"
                style="?attr/buttonBarNeutralButtonStyle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
    
            <android.widget.Space
                android:id="@+id/spacer"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:visibility="invisible"/>
    
            <Button
                android:id="@android:id/button2"
                style="?attr/buttonBarNegativeButtonStyle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
    
            <Button
                android:id="@android:id/button1"
                style="?attr/buttonBarPositiveButtonStyle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
    
        </androidx.appcompat.widget.ButtonBarLayout>
    
    </ScrollView>
    

    2. Dialog 스타일 수정


    2.1 findViewById를 통해

    
          AlertDialog.Builder builder = new AlertDialog.Builder(this);
          builder.setMessage(msg);
          builder.setPositiveButton(getString(R.string.yes), null);
          AlertDialog dialog = builder.create();
          dialog.show();
          // id 
          Button button = dialog.findViewById(android.R.id.button1);
          // getButton 
          Button button2 = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
    
    이 수정 방식은 show () 다음에 호출해야 합니다. 그렇지 않으면 빈 바늘 이상이 발생할 수 있습니다.이것은 show() 방법을 실행할 때 dialog가 레이아웃을 초기화하기 때문입니다. 구체적인 원본은 Dialog의 onCreate 방법을 볼 수 있습니다.

    2.2 사용자 정의 스타일


    위의 소스 코드를 통해 Dialog 세 버튼의 스타일은 다음과 같습니다.
  • buttonBarNeutralButtonStyle
  • buttonBarNegativeButtonStyle
  • buttonBarPositiveButtonStyle
  • 
            <Button
                android:id="@android:id/button3"
                style="?attr/buttonBarNeutralButtonStyle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
    
            <android.widget.Space
                android:id="@+id/spacer"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:visibility="invisible"/>
    
            <Button
                android:id="@android:id/button2"
                style="?attr/buttonBarNegativeButtonStyle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
    
            <Button
                android:id="@android:id/button1"
                style="?attr/buttonBarPositiveButtonStyle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
    
    위의 스타일을 사용자 정의 스타일로 바꾸면 수정 효과를 얻을 수 있습니다.
    스타일입니다.xml에 다음 코드를 추가합니다.
    
        <style name="accessPositiveBtnStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
            <item name="android:textColor">@color/test1</item>
        </style>
    
        <style name="accessNegativeBtnStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
            <item name="android:textColor">@color/test2</item>
        </style>
    
        <!--   -->
        <style name="testDialogTheme" parent="Theme.AppCompat.Light.Dialog.Alert">
            <item name="buttonBarPositiveButtonStyle">@style/accessPositiveBtnStyle</item>
            <item name="buttonBarNegativeButtonStyle">@style/accessNegativeBtnStyle</item>
        </style>
    
    구체적인 용도:
    
        AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.testDialogTheme);
        builder.setMessage("Test");
        builder.setCancelable(false);
        builder.setPositiveButton(" ", null);
        builder.setNegativeButton(" ", null);
        Dialog dialog = builder.create();
        dialog.show();
    
    이상은 Android가 Dialog 스타일을 수정하는 방법에 대한 상세한 내용입니다. Android가 Dialog 스타일을 수정하는 방법에 대한 더 많은 자료는 저희 다른 관련 글을 주목해 주세요!

    좋은 웹페이지 즐겨찾기