最近在实现一个自定义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>
最终修改的效果:
本文详细解释了如何在Android应用中自定义dialog的宽度,使其完全匹配手机屏幕宽度,通过深入分析dialog构造函数及主题配置,提供了解决方案及修改示例。

1万+

被折叠的 条评论
为什么被折叠?



