Android开发之Dialog
6种对话框的使用
相关API:
AlertDialog
AlertDialog.Builder
DialogInterface
以下为demo:
MainActivity.class:
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private final static String TAG=MainActivity.class.getSimpleName();
private int itemPosition;
private List<Integer> whoChoice=new ArrayList<>();
private int length;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
showMyDialog(6);
}
private void showMyDialog(int type){
AlertDialog.Builder dialog=new AlertDialog.Builder(this,R.style.dialog);
final String[] items={"1","2","3"};
final boolean[] itemChoice={false,true,false};
switch(type){
case 1:
dialog.setTitle("normal dialog");
dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Log.i(TAG,"normal dialog: "+"确定");
}
});
dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Log.i(TAG,"normal dialog: "+"取消");
}
});
break;
case 2:
dialog.setTitle("Item Dialog");
dialog.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
//注意:下标从0开始
Log.i(TAG,"Item dialog: "+"i: "+i);
}
});
break;
case 3:
itemPosition=-1;
dialog.setTitle("Single Dialog");
//checkedItem参数是指默认选中项,但默认选中项与i的值无关
dialog.setSingleChoiceItems(items, 1, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
itemPosition=i;
}
});
dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Log.i(TAG,"Single Dialog: "+"itemPosition: "+itemPosition);
if(itemPosition!=-1){
Log.i(TAG,"Single Dialog: "+"items[itemPosition]: "+items[itemPosition]);
}
}
});
break;
case 4:
dialog.setTitle("MultiChoice Dialog");
dialog.setMultiChoiceItems(items, itemChoice, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i, boolean b) {
if(b){
whoChoice.add(i);
}else{
//由于多选框会默认选中一个,此时不能首先取消选中项,因为该默认选中项尚未添加进容器
whoChoice.remove(i);
}
Log.i(TAG,"MultiChoice Dialog: "+"i: "+i);
}
});
dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
length=whoChoice.size();
Log.i(TAG,"MultiChoice Dialog: "+"length: "+length);
while(length>-1){
Log.i(TAG,"MultiChoice Dialog: "+"itemPosition: "+length+" itemChoice: "+itemChoice[length]);
--length;
}
}
});
break;
case 5:
final EditText editText=new EditText(this);
dialog.setTitle("Editext Dialog");
dialog.setView(editText);
dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Log.i(TAG,"Editext Dialog: "+"Editext: "+editText.getText().toString());
}
});
break;
case 6:
final View dialogStyle=LayoutInflater.from(this).inflate(R.layout.dialog_style,null,false);
dialog.setView(dialogStyle);
// dialog.setTitle("Dialog Style");
// dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
// @Override
// public void onClick(DialogInterface dialogInterface, int i) {
// final EditText edit=dialogStyle.findViewById(R.id.edit);
// Log.i(TAG,"Dialog Style: "+"Editext: "+edit.getText().toString());
// }
// });
break;
default:
break;
}
dialog.show();
}
}
注意:
case 1-6分别为普通对话框,菜单对话框,单选对话框,多选对话框,自定义控件对话框和自定义布局对话框。单选对话框中的setSingleChoiceItems(int itemsId, int checkedItem, DialogInterface.OnClickListener listener)的checkedItem参数指默认选中项,但该默认选中项并不指重写方法onClick中的i参数,即如果我们不进行选择,即使默认选中了第一个,返回的i也还是-1。多选对话框也类似。
dialog.style.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.widget.FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="50dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center">
<TextView
android:gravity="center"
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="请输入信息" />
<RelativeLayout
android:id="@+id/rela"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
/>
<Button
android:id="@+id/butt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="确定"
android:layout_centerHorizontal="true"
android:layout_alignTop="@+id/edit"
android:layout_marginTop="50dp"/>
</RelativeLayout>
</LinearLayout>
</android.widget.FrameLayout>
注意:
dialog的自定义布局中的所有控件宽度都应该为match_parent,否则宽度无效,若要控制控件的大小可通过view或layout_margin来控制,控制对话框的大小可以在最外层布局加padding
style.xml:
<style name="dialog" parent="@android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item>
<!--边框-->
<item name="android:windowIsFloating">true</item>
<!--是否浮现在activity之上-->
<item name="android:windowIsTranslucent">false</item>
<!--半透明-->
<item name="android:windowNoTitle">true</item>
<!--无标题-->
<item name="android:windowBackground">@android:color/transparent</item>
<!--背景透明-->
<item name="android:backgroundDimEnabled">true</item>
<!--模糊-->
</style>
自定义Dialog类:
通过写一个自己的继承于Dialog的类可以为自己量身订做一个方便于实现自己样式的对话框的类
Dialoger.class:
import android.app.Dialog;
import android.content.Context;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
/**
* Created by ASUS on 2018/2/10.
*/
public class Dialoger extends Dialog{
private yesOnClickListner yes;
private noOnclickListner no;
private View layout;
private String title="", message="";
private Context context;
private EditText messageEdit;
private TextView titleText,messageText;
public Dialoger(@NonNull Context context) {
super(context);
this.context=context;
}
public Dialoger(@NonNull Context context, int themeResId) {
super(context, themeResId);
this.context=context;
}
public Dialoger(@NonNull Context context,String title) {
super(context);
this.context=context;
this.title=title;
}
public Dialoger(@NonNull Context context,String title,String message) {
super(context);
this.context=context;
this.title=title;
this.message=message;
}
public Dialoger(@NonNull Context context, int themeResId,String title) {
super(context, themeResId);
this.context=context;
this.title=title;
}
public Dialoger(@NonNull Context context, int themeResId,String title,String message) {
super(context, themeResId);
this.context=context;
this.title=title;
this.message=message;
}
public void setYesOnClickListner(yesOnClickListner yes){
this.yes=yes;
}
public void setNoOnClickListner(noOnclickListner no){
this.no=no;
}
/**
* 设置对话框布局
* @param layoutId
* @param titleTextId
* @param messageId
* @param type : 1表示内容框是EditText,2表示内容框是TextView
*/
public void setLayout(int layoutId,int titleTextId,int messageId,int type){
layout=LayoutInflater.from(context).inflate(layoutId,null);
titleText=layout.findViewById(titleTextId);
switch (type){
case 1:
messageEdit=layout.findViewById(messageId);
break;
case 2:
messageText=layout.findViewById(messageId);
break;
}
}
public void setTitle(String title){
this.title=title;
titleText.setText(title);
}
public void setMessage(String message){
this.message=message;
titleText.setText(message);
}
public String getMessage(){
if (!message.equals("")) {
return message;
}
return "";
}
public String getTitle(){
if (!title.equals("")) {
return title;
}
return "";
}
public void initDialog(){
if(layout!=null){
setContentView(layout);
if(!title.equals("")){
titleText.setText(title);
}
if(!message.equals("")){
if(messageText!=null){
messageText.setText(message);
}
else if(messageEdit!=null){
messageEdit.setText(message);
}
}
Button yesButt=layout.findViewById(R.id.yes_butt);
yesButt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
yes.onYesClick();
}
});
Button noButt=layout.findViewById(R.id.no_butt);
noButt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
no.onNoClick();
}
});
}
}
public interface yesOnClickListner{
public void onYesClick();
}
public interface noOnclickListner{
public void onNoClick();
}
}
我在本类为自己定义了两种风格的dialog供我自己使用,一种是一个TextView加一个EditextView,另一种是两个TextView,两种都有两个按钮,确定和取消。
写这两个按钮的监听事件,首先在该类定义两个接口,然后写两个方法用来传用户传过来的已经重写好接口方法的这两个接口,最后再写这两个按钮的监听事件,调用重写好的接口方法
MainActivity.class:
private void showDialoger(){
final Dialoger dialoger=new Dialoger(this,"Title","Message");
dialoger.setLayout(R.layout.dialog_style,R.id.title_text,R.id.message_edit,1);
dialoger.initDialog();
dialoger.setYesOnClickListner(new Dialoger.yesOnClickListner() {
@Override
public void onYesClick() {
Log.i(TAG,"Editext: "+dialoger.getMessage());
}
});
dialoger.show();
}
乍眼一看,感觉这样有点多此一举,想想也是,这样并不能方便多少,但自定义Dialog类的基本思路便是如此,我们可以利用设计模式封装思想将此封装的更加方便和漂亮