1. 程式人生 > >自定義dialog的寬度充滿整個螢幕寬度的問題

自定義dialog的寬度充滿整個螢幕寬度的問題

最近在實現一個自定義dialog的時候,效果要求自定義dialog的寬度必須跟手機螢幕的寬度一樣寬。

自定義dialog:

public class CustomDialog extends Dialog{

    private Context mContext;

    public CustomDialog(Context context) {
        super(context);
        this.mContext = context;
        View view = getLayoutInflater().inflate(R.layout.dialog_quick_option2, null
); requestWindowFeature(Window.FEATURE_NO_TITLE); super.setContentView(view); } @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); getWindow().setGravity(Gravity.BOTTOM); //顯示在底部 WindowManager m = getWindow().getWindowManager(); Display d = m.getDefaultDisplay(); WindowManager.LayoutParams p = getWindow().getAttributes(); p.width = d.getWidth(); //設定dialog的寬度為當前手機螢幕的寬度
getWindow().setAttributes(p); } }

自定義dialog佈局dialog_quick_option2.xml :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity
="bottom" android:background="#f6f6f6">
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="20dp" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_horizontal" android:padding="18dp" android:orientation="vertical"> <ImageView android:layout_width="48dp" android:layout_height="48dp" android:src="@drawable/quick_option_text_nor"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:textSize="12dp" android:gravity="center" android:text="你好"/> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_horizontal" android:padding="18dp" android:orientation="vertical"> <ImageView android:layout_width="48dp" android:layout_height="48dp" android:src="@drawable/quick_option_text_nor"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:textSize="12dp" android:gravity="center" android:text="你好"/> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_horizontal" android:padding="18dp" android:orientation="vertical"> <ImageView android:layout_width="48dp" android:layout_height="48dp" android:src="@drawable/quick_option_text_nor"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:textSize="12dp" android:gravity="center" android:text="你好"/> </LinearLayout> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_horizontal" android:padding="18dp" android:orientation="vertical"> <ImageView android:layout_width="48dp" android:layout_height="48dp" android:src="@drawable/quick_option_text_nor"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:textSize="12dp" android:gravity="center" android:text="你好"/> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_horizontal" android:padding="18dp" android:orientation="vertical"> <ImageView android:layout_width="48dp" android:layout_height="48dp" android:src="@drawable/quick_option_text_nor"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:textSize="12dp" android:gravity="center" android:text="你好"/> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_horizontal" android:padding="18dp" android:orientation="vertical"> <ImageView android:layout_width="48dp" android:layout_height="48dp" android:src="@drawable/quick_option_text_nor"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:textSize="12dp" android:gravity="center" android:text="你好"/> </LinearLayout> </LinearLayout> </LinearLayout> </RelativeLayout>

最終效果:

這裡寫圖片描述

從上圖看,我們要求的自定義dialog的寬度沒有到達我們手機螢幕的寬度。那咋們跟蹤程式碼看看,首先看看咋們繼承的dialog的建構函式:

Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) {
        if (createContextThemeWrapper) {
            if (themeResId == 0) {
                final TypedValue outValue = new TypedValue();
                context.getTheme().resolveAttribute(R.attr.dialogTheme, outValue, true);
                themeResId = outValue.resourceId;
            }
            mContext = new ContextThemeWrapper(context, themeResId);
        } else {
            mContext = context;
        }

        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

        final Window w = new PhoneWindow(mContext);
        mWindow = w;
        w.setCallback(this);
        w.setOnWindowDismissedCallback(this);
        w.setWindowManager(mWindowManager, null, null);
        w.setGravity(Gravity.CENTER);

        mListenersHandler = new ListenersHandler(this);
    }

這塊程式碼中在第5行有使用一個主題context.getTheme().resolveAttribute(R.attr.dialogTheme, outValue, true);
咋們可以全域性搜尋ctrl+h一下dialog預設的主題dialogTheme
這裡寫圖片描述

咋們一層一層跟進去看看,這裡有一個預設配置的屬性:

<item name="android:windowBackground">@drawable/abc_dialog_material_background_dark</item>

再次跟進這個屬性裡面看看,如下:

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<inset xmlns:android="http://schemas.android.com/apk/res/android"
       android:insetLeft="16dp"
       android:insetTop="16dp"
       android:insetRight="16dp"
       android:insetBottom="16dp">
    <shape android:shape="rectangle">
        <corners android:radius="2dp" />
        <solid android:color="@color/background_floating_material_dark" />
    </shape>
</inset><!-- From: file:/usr/local/google/buildbot/src/googleplex-android/mnc-supportlib-release/frameworks/support/v7/appcompat/res/drawable/abc_dialog_material_background_dark.xml -->

可以看到
android:insetLeft=”16dp”
android:insetTop=”16dp”
android:insetRight=”16dp”
android:insetBottom=”16dp”
這段程式碼其實就是咋們為什麼設定了自定義dialog的寬度為當前手機螢幕的寬度,但是最終顯示的效果卻沒有達到我們需求的原因了。顯示的背景寬度距離手機螢幕的左右兩邊各有16dp的間隔。所以如果要想實現之前的效果需求,咋們可以重新定義主題。修改
android:windowBackground屬性的配置。

下面我就直接列出大體程式碼和最終效果圖:


public class CustomDialog extends Dialog{

    public CustomDialog(Context context) {
        //重寫dialog預設的主題
        this(context, R.style.quick_option_dialog);
    }

    public CustomDialog(Context context, int themeResId) {
        super(context, themeResId);
        View convertView = getLayoutInflater().inflate(R.layout.dialog_quick_option, null);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(convertView);
    }

    @Override
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        getWindow().setGravity(Gravity.BOTTOM); //顯示在底部

        WindowManager m = getWindow().getWindowManager();
        Display d = m.getDefaultDisplay();
        WindowManager.LayoutParams p = getWindow().getAttributes();
        p.width = d.getWidth(); //設定dialog的寬度為當前手機螢幕的寬度
        getWindow().setAttributes(p);
    }
}

重寫預設主題並修改android:windowBackground屬性:

<style name="quick_option_dialog" parent="@style/Theme.AppCompat.Dialog">
        <item name="android:windowBackground">@color/white40</item>
</style>

最終修改的效果:
這裡寫圖片描述

原始碼下載