1.简述
DialogFragment 是谷歌官方推荐的对话框,可以高度自定义,灵活方便,非常适合编写产品经理设计的任何UI。
AlertDialog在商业项目实际开发使用率已经低到忽略不计,了解基本使用即可。
2.创建方式的区别
1.onCreateDialog
该方式是在方法内部创建AlertDialog然后返回AlertDialog对象,定制性差,不推荐。
2.onCreateView--推荐方式
在onCreateView中渲染自定义的布局,并设置交互逻辑。
3.使用
3.1 自定义对话框UI
<?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:background="@drawable/shape_white_bg_5_radius"
android:paddingLeft="17dp"
android:paddingRight="18dp"
android:paddingBottom="20dp">
<ImageView
android:id="@+id/img"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="24dp"
android:src="@mipmap/ic_launcher" />
<EditText
android:id="@+id/input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/img"
android:layout_marginTop="8dp"
android:background="@drawable/shape_gray_stroke_radius_5"
android:hint="输入"
android:inputType="text"
android:minHeight="45dp"
android:padding="8dp"
android:textColor="#404040"
android:textSize="14sp" />
<Button
android:id="@+id/btn_submit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/input"
android:layout_marginTop="12dp"
android:background="@drawable/shape_blue_radius_5"
android:text="添加"
android:textColor="#fff"
android:textSize="18sp" />
</RelativeLayout>
3.2 继承DialogFragment
重点关注onStart()中对对话框的宽高设置、居中等处理,参数及方法见名知意。
同时关注build静态方法,这是一个开发规范。
package com.cupster.easydialogfragment;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
public class AddInputDialog extends DialogFragment {
public static final String KEY_NAME ="NAME";
View mView;
ImageView mImg;
EditText mInput;
Button mBtn;
View.OnClickListener mConfirmListener;
public static AddInputDialog build(String name ){
AddInputDialog dialog = new AddInputDialog();
Bundle bundle = new Bundle();
bundle.putString(KEY_NAME ,name);
dialog.setArguments(bundle);
return dialog;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (mView == null) {
mView = inflater.inflate(R.layout.dialog_add_input, container, false);
}
setStyle(STYLE_NORMAL, R.style.ConfirmDialogStyle);
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
return mView;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
mImg = mView.findViewById(R.id.img);
mBtn = mView.findViewById(R.id.btn_submit);
mInput = mView.findViewById(R.id.input);
mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mConfirmListener != null){
view.setTag( mInput.getText().toString() );
mConfirmListener.onClick(view);
}
dismiss();
}
});
initData();
}
private void initData() {
Bundle bundle = getArguments();
if (bundle != null) {
String name = bundle.getString(KEY_NAME);
if (!TextUtils.isEmpty(name)){
mInput.setText(name);
}
}
}
@Override
public void onStart() {
super.onStart();
Window window = getDialog().getWindow();
window.setDimAmount(0.2f);//设置亮度
window.setGravity(Gravity.CENTER);
window.setWindowAnimations(R.style.PopupAnimation);
WindowManager.LayoutParams layoutParams = window.getAttributes();
layoutParams.width = (int) (0.85*deviceWidth(getContext()));
window.setLayout(layoutParams.width, layoutParams.height);
window.setBackgroundDrawableResource(android.R.color.transparent);
}
public static int deviceWidth(Context context) {
return context.getResources().getDisplayMetrics().widthPixels;
}
public void setConfirmListener(View.OnClickListener listener){
mConfirmListener = listener;
}
}
3.3 调用
package com.cupster.easydialogfragment;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showDialog();
}
});
}
private void showDialog() {
AddInputDialog dialog = AddInputDialog.build("请输入");
dialog.setConfirmListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this ,"确认",Toast.LENGTH_LONG).show();
}
});
dialog.show(getSupportFragmentManager() ,"input");
}
}
3.4 其他相关代码
res/values/styles.xml
<style name="ConfirmDialogStyle" parent="android:Theme.Holo.Light.Dialog">
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@null</item>
</style>
<!-- 弹出窗体的动画 从底部弹出 -->
<style name="PopupAnimation" parent="@android:style/Animation">
<!-- 边框 -->
<item name="android:windowFrame">@null</item>
<!-- 设置dialog的背景 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 是否浮现在activity之上 -->
<item name="android:windowIsFloating">true</item>
<!-- 半透明 -->
<item name="android:windowIsTranslucent">false</item>
<!-- 无标题 -->
<item name="android:windowNoTitle">true</item>
<!-- 模糊 -->
<item name="android:backgroundDimEnabled">true</item>
<item name="android:windowEnterAnimation">@anim/popup_enter</item>
<item name="android:windowExitAnimation">@anim/popup_exit</item>
</style>
popup_enter.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="600"
android:fromXDelta="0.0%"
android:fromYDelta="100%p"
android:toXDelta="0.0%"
android:toYDelta="0" />
</set>
popup_exit.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="600"
android:fromYDelta="0"
android:toYDelta="100%p" />
</set>
shape_blue_radius_5.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dp"/>
<solid android:color="#5577fb"/>
</shape>
shape_gray_stroke_radius_5.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:bottomLeftRadius="3dp"
android:bottomRightRadius="3dp"
android:topLeftRadius="3dp"
android:topRightRadius="3dp"
/>
<solid android:color="#fff"/>
<stroke android:color="#bfbfbf" android:width="1dp"/>
</shape>
shape_white_bg_5_radius.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<solid android:color="#fff" />
<corners android:radius="5dp"/>
</shape>