Android仿Ios實現Dialog圓角彈窗
轉載請標明出處:https://blog.csdn.net/m0_38074457/article/details/84979890 ,本文出自:【陳少華的部落格】
一、先看效果
https://github.com/hnsycsxhzcsh/IosDialog/blob/master/img/18tkr-gc4gb.gif
實現原理:
1.使用控制元件DialogFragment,在初始化的時候設定背景為透明,無頭部
2.xml大布局是一個四角橢圓
3.底部左側是一個左下角橢圓,底部右側是一個右下角橢圓
二、實現大布局layout_dialog_ensure.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/dialog_fragment_circle_background" android:orientation="vertical"> <TextView android:id="@+id/tv_message" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:padding="10dp" android:textColor="@color/black" android:textSize="18sp" android:textStyle="bold" /> <include layout="@layout/view_divide" /> <include layout="@layout/dialog_ensure_bottom" /> </LinearLayout>
大布局的背景是dialog_fragment_circle_background.xml,是一個橢圓背景
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#FFFFFF" /> <size android:width="@dimen/shape_login_buttom_300px" android:height="@dimen/shape_login_buttom_64px" /> <corners android:bottomLeftRadius="@dimen/shape_login_buttom_64px" android:bottomRightRadius="@dimen/shape_login_buttom_64px" android:topLeftRadius="@dimen/shape_login_buttom_64px" android:topRightRadius="@dimen/shape_login_buttom_64px" /> </shape>
底部佈局是dialog_ensure_bottom.xml
<?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="wrap_content" android:background="@drawable/dialog_fragment_circle_background_single_ensure_selected" android:orientation="horizontal"> <TextView android:id="@+id/tv_cancel" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/dialog_fragment_ensure_cancel_selector" android:gravity="center" android:paddingBottom="10dp" android:paddingTop="10dp" android:text="@string/dialog_cancel" android:textColor="@color/actionsheet_blue" android:textSize="16sp" /> <TextView android:id="@+id/tv_ensure" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="0.1dp" android:layout_weight="1" android:background="@drawable/dialog_fragment_ensure_ensure_selector" android:gravity="center" android:paddingBottom="10dp" android:paddingTop="10dp" android:text="@string/dialog_ok" android:textColor="@color/actionsheet_red" android:textSize="16sp" /> </LinearLayout>
底部左側背景是dialog_fragment_ensure_cancel_selector.xml,放在drawable包下
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/dialog_fragment_circle_background_ensure_cancel_selected" android:state_pressed="true"/>
<item android:drawable="@drawable/dialog_fragment_circle_background_ensure_cancel_selected" android:state_selected="true"/>
<item android:drawable="@drawable/dialog_fragment_circle_background_ensure_cancel_selected" android:state_checked="true"/>
<item android:drawable="@drawable/dialog_fragment_circle_background_ensure_cancel"/>
</selector>
dialog_fragment_circle_background_ensure_cancel_selected.xml為選中狀態,放在drawable包下
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#D9D9D9" />
<size
android:width="@dimen/shape_login_buttom_300px"
android:height="@dimen/shape_login_buttom_64px" />
<corners android:bottomLeftRadius="@dimen/shape_login_buttom_64px" />
</shape>
dialog_fragment_circle_background_ensure_cancel.xml為正常狀態,放在drawable包下
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFFFFF" />
<size
android:width="@dimen/shape_login_buttom_300px"
android:height="@dimen/shape_login_buttom_64px" />
<corners android:bottomLeftRadius="@dimen/shape_login_buttom_64px" />
</shape>
同理底部右側,按照底部左側來實現
三、建立基類BaseDialogFragment物件,EnsureDialog繼承此基類
初始化的時候一定要設定 對話方塊內部背景設定透明,和無標題
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
public abstract class BaseDialogFragment extends DialogFragment {
protected static final int SIZE_DEFAULT = -1;
protected static final int SIZE_LOADING = 1;
protected static final float COLOR_DEFAULT = 1.0f;
protected static final float COLOR_TRANSPARENT = 0.0f;
private int size = -1;
private float color = 1.0f;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(getLayoutId(), container, false);
init(view);
initDialog();
return view;
}
public abstract int getLayoutId();
protected abstract void init(View view);
private void initDialog() {
//對話方塊內部背景設定透明
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
}
@Override
public void onStart() {
super.onStart();
if (color != COLOR_DEFAULT) {
//如果過不是預設顏色,就設定指定color背景顏色
Window window = getDialog().getWindow();
WindowManager.LayoutParams windowParams = window.getAttributes();
windowParams.dimAmount = color;
window.setAttributes(windowParams);
}
}
protected void initWindowSize(int size) {
this.size = size;
initWindowSize();
}
protected void initWindowSize() {
Dialog dialog = getDialog();
if (dialog != null) {
DisplayMetrics dm = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
if (size == SIZE_LOADING) {
// dialog.getWindow().setLayout((int) (dm.widthPixels * 0.5), (int) (dm.widthPixels * 0.5));
dialog.getWindow().setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
} else {
dialog.getWindow().setLayout((int) (dm.widthPixels * 0.8), ViewGroup.LayoutParams.WRAP_CONTENT);
}
}
}
protected void setOutsideColor(float color) {
this.color = color;
}
}
public class EnsureDialog extends BaseDialogFragment {
private TextView mTvCancel;
private TextView mTvEnsure;
private TextView mTvMessage;
private IDialogEnsureClickListener listener;
@Override
public int getLayoutId() {
return R.layout.layout_dialog_ensure;
}
@Override
protected void init(View view) {
mTvCancel = (TextView) view.findViewById(R.id.tv_cancel);
mTvEnsure = (TextView) view.findViewById(R.id.tv_ensure);
mTvMessage = (TextView) view.findViewById(R.id.tv_message);
Bundle args = getArguments();
if (args != null) {
if (args.containsKey("message")) {
String message = args.getString("message");
mTvMessage.setText(message);
}
if (args.containsKey("left")) {
String left = args.getString("left");
if (!TextUtils.isEmpty(left)) {
mTvCancel.setText(left);
}
}
if (args.containsKey("right")) {
String right = args.getString("right");
if (!TextUtils.isEmpty(right)) {
mTvEnsure.setText(right);
}
}
}
mTvCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.onCancelClick();
}
}
});
mTvEnsure.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.onEnsureClick();
}
}
});
}
public void setOnClickListener(IDialogEnsureClickListener listener) {
this.listener = listener;
}
@Override
public void onStart() {
super.onStart();
initWindowSize();
}
}
四、實現彈窗
建立EnsureDialog物件,通過bundle把需要的資料傳給EnsureDialog
mBtEnsure.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final EnsureDialog ensureDialog = new EnsureDialog();
Bundle bundle = new Bundle();
bundle.putString("message", "這是簡單的dialog");
ensureDialog.setArguments(bundle);
ensureDialog.show(getSupportFragmentManager(), "ensure");
ensureDialog.setOnClickListener(new IDialogEnsureClickListener() {
@Override
public void onEnsureClick() {
Toast.makeText(MainActivity.this, "點選了OK", Toast.LENGTH_SHORT).show();
ensureDialog.dismiss();
}
@Override
public void onCancelClick() {
Toast.makeText(MainActivity.this, "點選了Cancel", Toast.LENGTH_SHORT).show();
ensureDialog.dismiss();
}
});
}
});
備註:可在github上檢視具體實現程式碼地址為 https://github.com/hnsycsxhzcsh/IosDialog,進入github後點擊右上角star謝謝支援!
gradle可直接引用
1、根目錄的build.gradle中設定
allprojects {
repositories {
maven { url "https://jitpack.io" }
}
}
2、app的build.gradle中引用,最後的版本可能會變化,以github上最新版本為準
implementation "com.github.hnsycsxhzcsh:IosDialog:V1.1"