中级实训Android学习记录——自定义Dialog、PopupWindow
学习记录 2020/11/23
自定义Dialog
- 自定义layout来存放dialog:layout_custom_dialog.xml
定义了两个TextView来存放文本,两个TextView用作按钮的说明文本
-
我们创建CustomDialog类,并继承Dialog类
- 创建初始化方法
public CustomDialog(Context context) { super(context); } public CustomDialog(Context context, int themeId) { super(context, themeId); }
第一个初始化方法接收一个context,第二个初始化方法接收一个context和一个themeId(目前不知道有啥用)
- 为layout中每个TextView创建一个string对象和一个TextView对象,string存放他们的文本,为每个string对象构造一个setter
public CustomDialog setTitle(String title) { this.title = title; return this; } public CustomDialog setMessage(String message) { this.message = message; return this; } public CustomDialog setConfirm(String confirm, IOnConfirmListener confirmListener) { this.confirm = confirm; this.confirmListener = confirmListener; return this; } public CustomDialog setCancel(String cancel, IOnCancelListener cancelListener) { this.cancel = cancel; this.cancelListener = cancelListener; return this; }
为了能够实现一连串的连续调用,我们声明返回类型为CustomDialog并在每个setter中都返回this
- 声明两个按钮的Listener接口
public interface IOnCancelListener { void OnCancel(CustomDialog dialog); } public interface IOnConfirmListener { void OnConfirm(CustomDialog dialog); }
- 将CustomDialog类实现View.OnClickListener并覆盖其onClick函数
public class CustomDialog extends Dialog implements View.OnClickListener { @Override public void onClick(View v) { switch (v.getId()) { case R.id.tv_confirm: if (this.confirmListener != null) confirmListener.OnConfirm(this); break; case R.id.tv_cancel: if (this.cancelListener != null) cancelListener.OnCancel(this); break; } } }
通过override他的onClick函数来达到我们点击事件的目的
- 实现onCreate函数,主要进行窗口的初始化和变量的初始化
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout_custom_dialog); // 设置dialog宽度 WindowManager manager = getWindow().getWindowManager(); Display display = getContext().getDisplay(); WindowManager.LayoutParams p = getWindow().getAttributes(); Rect size = new Rect(); size = manager.getCurrentWindowMetrics().getBounds(); p.width = (int)((size.right - size.left) * 0.8); getWindow().setAttributes(p); // 让圆角设置有效 getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); mtv_title = findViewById(R.id.tv_title); if (!TextUtils.isEmpty(title)) { mtv_title.setText(title); } mtv_Message = findViewById(R.id.tv_message); if (!TextUtils.isEmpty(message)) { mtv_Message.setText(message); } mtv_confirm = findViewById(R.id.tv_confirm); if (!TextUtils.isEmpty(confirm)) { mtv_confirm.setText(confirm); } mtv_confirm.setOnClickListener((View.OnClickListener) this); mtv_cancel = findViewById(R.id.tv_cancel); if (!TextUtils.isEmpty(cancel)) { mtv_cancel.setText(cancel); } mtv_cancel.setOnClickListener((View.OnClickListener) this); }
设置宽度可以变成一个轮子反复使用
在设置圆角的时候一直看不到效果,是因为Dialog的背景是白色的四角方框,他承载了我们自定义的CustomDialog之后,需要把Dialog的背景变成透明才能看出圆角效果。
-
使用CustomDialog
使用Button的点击事件唤出CustomDialog
mbtn_CustomDialog = findViewById(R.id.btn_CustomDialog); mbtn_CustomDialog.setOnClickListener(v -> { CustomDialog customDialog = new CustomDialog(RecyclerViewActivity.this, R.style.CustomDialog); customDialog.setTitle("提示").setMessage("确认删除?") .setConfirm("确认", new CustomDialog.IOnConfirmListener() { @Override public void OnConfirm(CustomDialog dialog) { Toast.makeText(RecyclerViewActivity.this, "确认", Toast.LENGTH_LONG).show(); } }).setCancel("取消", new CustomDialog.IOnCancelListener() { @Override public void OnCancel(CustomDialog dialog) { Toast.makeText(RecyclerViewActivity.this, "取消", Toast.LENGTH_LONG).show(); } }).show(); });
- CustomDialog设置圆角
我们先创建一个shape类型的xml文件bg_custom_dialog.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="@color/white"></solid> <corners android:radius="5dp"></corners> </shape>
其中solid设置颜色,corners设置圆角
最后在CustomDialog的layout文件layout_custom_dialog.xml中设置背景为bg_custom_dialog.xml即可
<LinearLayout ... android:background="@drawable/bg_custom_dialog"> ... </LinearLayout>
即可达到设置圆角的效果
- 在使用LinearLayout需要注意的问题
- 在声明LinearLayout之后需要设置其orientation(对齐方式),可以是
- horizontal 水平对齐
- vertical 垂直对齐
- 在声明LinearLayout之后需要设置其orientation(对齐方式),可以是
PopupWindow
- PopupWindow
- 默认用法
- 默认用法
mPop = new PopupWindow(view, mBtnPop.getWidth(), ViewGroup.LayoutParams.WRAP_CONTENT);
mPop.setOutsideTouchable(true); // 设置为true之后,点击popupwindow之外的地方会使popupwindow消失
mPop.setFocusable(true); // 设置为true之后,点击mbtnPop会使popupwindow消失,原先为点击mbtnPop会消失再出现
mPop.showAsDropDown(mBtnPop);
可以直接new一个PopupWindow,然后接受一个view作为window的布局,接受一个宽度和一个高度
调用showAsDropDown会让PopupWindow从mbtnPop这个按钮的下方弹出