Android custom AlertDialog and setting width and height are invalid

This article records custom AlertDialog and the problems encountered

Customize AlertDialog

First on the renderings
Insert picture description here

Create layout

First we have to create the desired dialog layout file

<?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="200dp"
    android:background="@drawable/style_linearlayout_round_bg"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
        <TextView
            android:layout_width="100dp"
            android:layout_height="match_parent"
            android:text="@string/penaltyType"
            android:gravity="center"
            android:textColor="@color/colorAccent" />
        <Spinner
            android:id="@+id/sp_penalty"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:entries="@array/penaltyArray" />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
        <TextView
            android:layout_width="100dp"
            android:layout_height="match_parent"
            android:text="@string/penaltyContent"
            android:gravity="center"
            android:textColor="@color/colorAccent" />
        <EditText
            android:id="@+id/et_penaltyContent"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@null"
            android:inputType="text" />
    </LinearLayout>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:background="@color/gray" />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal"
        android:gravity="center">
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.6"
            android:visibility="invisible" />
        <Button
            android:id="@+id/btn_save"
            android:layout_width="wrap_content"
            android:layout_height="32dp"
            android:background="@drawable/style_button_round_bg"
            android:textColor="@color/white"
            android:text="@string/save" />
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.8"
            android:visibility="invisible" />
        <Button
            android:id="@+id/btn_close"
            android:layout_width="wrap_content"
            android:layout_height="32dp"
            android:background="@drawable/style_button_round_bg"
            android:textColor="@color/white"
            android:text="@string/close" />
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.6"
            android:visibility="invisible" />
    </LinearLayout>

</LinearLayout>

We want to make the AlertDialog look like this, and then after creating a custom layout, we need to operate in Activity/Fragment.

Add layout

Add the created layout to our AlertDialog in the Activity, and that's it.

        View customPenaltyView = LayoutInflater.from(mContext).inflate(R.layout.widget_custom_select_penalty, null, false);
        ......
        
        // 设置自定义布局
        dialog.setView(customPenaltyView);
        // 也可以通过这种方式设置布局
        Objects.requireNonNull(dialog.getWindow()).setContentView(customPenaltyView);

There are two ways here, because some custom Dialog on the Internet will fill the area between the Title and Button of the Dialog when setting the layout in the first way. In this case, use the second Chinese way can be solved. (Ps: I haven't encountered it yet). Generally, the first method is used.

Increase monitoring

After the layout is set, you can basically do some monitoring processing on the controls on the layout.

        final AlertDialog dialog = new AlertDialog.Builder(mContext).create();
        final Spinner penaltyType = customPenaltyView.findViewById(R.id.sp_penalty);
        final EditText penaltyContent = customPenaltyView.findViewById(R.id.et_penaltyContent);
        final String [] penaltyTypeArray = getResources().getStringArray(R.array.penaltyArray);
        final String[] penaltyTypeString = new String[1];
        dialog.setView(customPenaltyView);
        Button save  = customPenaltyView.findViewById(R.id.btn_save);
        Button close  = customPenaltyView.findViewById(R.id.btn_close);
        penaltyType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    
    
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
    
    
                penaltyTypeString[0] = penaltyTypeArray[position];
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
    
    

            }
        });
        save.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                dialog.dismiss();
                Toast.makeText(mContext, penaltyTypeString[0] + penaltyContent.getText().toString(), Toast.LENGTH_SHORT).show();
            }
        });
        close.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                dialog.dismiss();
            }
        });
        dialog.show();
        Objects.requireNonNull(dialog.getWindow()).setBackgroundDrawableResource(R.color.transparent);

to sum up

With the above three steps, you can basically make AlertDIalog what you want.

It can also be concise and do this.

		// 自定义的布局
		View addPlayerView = LayoutInflater.from(mContext).inflate(R.layout.widget_custom_alertdialog_addplayer, null, false);
		// 把布局添加到dialog
        final AlertDialog dialog = new AlertDialog.Builder(mContext, R.style.AlertDialog_AppCompat_Transparent).setView(addPlayerView).create();
        // 监听
        final EditText addPlayerName = addPlayerView.findViewById(R.id.et_addPlayerName);
        TextView addPlayerData = addPlayerView.findViewById(R.id.tv_addPlayerButton);
        addPlayerData.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                dialog.dismiss();
                Toast.makeText(TruthOrDareActivity.this, "添加玩家" + addPlayerName.getText().toString(), Toast.LENGTH_SHORT).show();
            }
        });
        dialog.show();

Finally, the problem encountered

  1. The layout fills the area incorrectly

In adding a layout, the layout file is filled into a part of the Dialog area, which can be set by the setContentView method of Dialog's getWindow. You can see the second step above to add a layout.

  1. Invalid setting width and height

The problem of invalid setting of width and height in the layout file can still be achieved by setting relevant properties in Window. We can get the screen height and width, and then set the desired position.

  1. Relative layout

The layout file uses RelativeLayout. If you use LinearLayout, the size (width and height) of the custom xml cannot be adjusted.

  1. RelativeLayout setting height is invalid

When using relative layout to set the height, the height is invalid. In fact, the layout_height is not invalid, but it is set according to the maximum control height in the child control.
Means: Set the height in the outermost RelativeLayout to match_parent or a specific height. If the height of the child control is set to match_parent, and the height of the child control is less than the maximum height of the outermost layer, it will fail. In fact, it is not invalid, but it is set according to the maximum height in the child control . It is equivalent to wrap_parent.
Reference:
Custom Dialog
Custom Dialog width and height are invalid

Guess you like

Origin blog.csdn.net/A_Intelligence/article/details/109956097