1、Dialog布局
根据上图的对话框样式,我们看一下Dialog的布局定义(custom_dialog.xml)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/log_in_layout"android:layout_width="fill_parent"android:layout_height="wrap_content"android:orientation="horizontal"><ImageView android:layout_width="match_parent" android:layout_height="100dip" android:src="@drawable/animal1" android:clickable="true" android:layout_weight="1"/><ImageView android:layout_width="match_parent" android:layout_height="100dip" android:src="@drawable/animal2" android:clickable="true" android:layout_weight="1"/><ImageView android:layout_width="match_parent" android:layout_height="100dip" android:src="@drawable/animal3" android:clickable="true" android:layout_weight="1"/><ImageView android:layout_width="match_parent" android:layout_height="100dip" android:src="@drawable/animal4" android:clickable="true" android:layout_weight="1"/> </LinearLayout>2、从Dialog派生对话框类
public class CustomDialog extends Dialog {Context mContext;public CustomDialog (Context context){ super(context); mContext = context;}public CustomDialog(Context context, int theme) { super(context, theme); mContext = context;}@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LayoutInflater inflater = (LayoutInflater) mContext .getSystemService(Context.LAYOUT_INFLATER_SERVICE); View layout = inflater.inflate(R.layout.custom_dialog, null); this.setContentView(layout);} }3、主函数(MainActivity)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><Button android:id="@+id/btn_pop_dialog" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="弹出对话框"/> </RelativeLayout>代码中的处理:(MainActivity.java)
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button)findViewById(R.id.btn_pop_dialog); btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) { CustomDialog dialog = new CustomDialog(MainActivity.this); dialog.show();} });} }这部分源码在文章最底部给出;
在布局中,我们只定义了一个水平布局,里面放了四个ImageView,即那四个小动物,那上面那一坨是哪来的呢(我用红笔圈出来的那块)?能不能去掉?这节,我们就说说有关样式的问题。
第一个问题,只所有上面那一坨,是因为我们没有指定对话框样式,系统会使用默认样式,那一坨就是标题栏。
要去掉的话,我们就需要自定义样式。
1、自定义样式
我们的样式是写在res/values文件夹下的style.xml文件中的,如图,如果没有style.xml,自已新建一个,位置如图:
这里定义的样式代码是这样的:
<style name="dialog" parent="android:Theme.Dialog"><item name="android:windowFrame">@null</item><item name="android:windowIsFloating">true</item><item name="android:windowContentOverlay">@null</item><item name="android:windowNoTitle">true</item> </style>先对这几个参数解释一下:
public class CustomDialog extends Dialog {Context mContext;public CustomDialog(Context context) { super(context); mContext = context;}public CustomDialog(Context context, int theme) { super(context, theme); mContext = context;}………… }看第二个就是我们的Theme样式,所以第一种使用样式的方法是在构造时直接将样式传进来,如果这样使用,那我们在构造对话框时应该是这样的“:
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button)findViewById(R.id.btn_pop_dialog); btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) { CustomDialog dialog = new CustomDialog(MainActivity.this,R.style.dialog); dialog.show();} });} }即在新建CustomDialog实例时,第二个参数传进来我们上面定义的样式。
public class CustomDialog extends Dialog {Context mContext;public CustomDialog(Context context) { super(context,R.style.dialog); mContext = context;}………… }这种情况一般用在我们封装代码时,不让其它人在外部改变我们的样式时使用的。
1、传进去
往对话框里传参数,一般就是利用构造函数来完成的,很简单,即在对话框的构造函数上加上我们自己想要传的参数,这里我们需要额外传一个字符串,来表示从哪个BTN来的。
所以对话框的构造函数就变成了这样:
public class CustomDialog extends Dialog{private Context mContext;private String mStr;public CustomDialog(Context context, String str, int theme) { super(context, theme); mContext = context; mStr = str;}………… }在使用的时候,也很简单:
Button btn2 = (Button)findViewById(R.id.btn_pop_dialog_2); btn2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) { CustomDialog dialog = new CustomDialog(MainActivity.this,"From btn 2",R.style.dialog); dialog.show();} });直接利用构造函数传参即可
public class CustomDialog extends Dialog {// 利用interface来构造一个回调函数public interface ICustomDialogEventListener { public void customDialogEvent(int valueYouWantToSendBackToTheActivity);}private ICustomDialogEventListener onCustomDialogEventListener;// 在构造函数中,设置进去回调函数public CustomDialog(Context context, ICustomDialogEventListener onCustomDialogEventListener) { super(context); this.onCustomDialogEventListener = onCustomDialogEventListener;}//当你想把值传回去的时候,调用回调函数将值设置进去@Overridepublic void onCreate(Bundle savedInstanceState){ Button btnOk = (Button) findViewById(R.id.customDialogButton); btnOk.setOnClickListener( new Button.OnClickListener() {public void onClick(View v) { onCustomDialogEventListener.customDialogEvent(valueYouWantToSendBackToTheActivity); dismiss();} });} }在构造对话框时:
final CustomDialog dialog = new CustomDialog(this, new ICustomDialogEventListener() {public void customDialogEvent(int value) { //在这里就获取到了从对话框传回来的值} });大致使用流程就是这样的,下面就把我们上面的效果利用回调函数实现出来;
public class CustomDialog extends Dialog implements View.OnClickListener {//增加一个回调函数,用以从外部接收返回值public interface ICustomDialogEventListener { public void customDialogEvent(int id);}private ICustomDialogEventListener mCustomDialogEventListener;private Context mContext;private String mStr;//把回调函数传进来public CustomDialog(Context context, String str, ICustomDialogEventListener listener, int theme) { super(context, theme); mContext = context; mStr = str; mCustomDialogEventListener = listener;}………… }然后在OnCreate() 函数中设定ImageView的点击事件,我们将CustomDialog类继承View.OnClickListener接口,对点击事件统一处理:
private void bindImageClickEvent(View layout){ImageView img1 = (ImageView)layout.findViewById(R.id.dialog_image1);ImageView img2 = (ImageView)layout.findViewById(R.id.dialog_image2);ImageView img3 = (ImageView)layout.findViewById(R.id.dialog_image3);ImageView img4 = (ImageView)layout.findViewById(R.id.dialog_image4);img1.setOnClickListener(this);img2.setOnClickListener(this);img3.setOnClickListener(this);img4.setOnClickListener(this); } @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);View layout = inflater.inflate(R.layout.custom_dialog, null);TextView tv = (TextView)layout.findViewById(R.id.dialog_text);tv.setText(mStr);bindImageClickEvent(layout);//绑定ImageView点击事件this.setContentView(layout); }在OnCreate()中,首先将传进来的String字符串设置到对话框的TextView中;然后绑定各个ImageView的点击事件
public void onClick(View view) {int id = view.getId();int drawableID = -1;switch (id){ case R.id.dialog_image1:drawableID = R.drawable.animal1;break; case R.id.dialog_image2:drawableID = R.drawable.animal2;break; case R.id.dialog_image3:drawableID = R.drawable.animal3;break; case R.id.dialog_image4:drawableID = R.drawable.animal4;break;}if (drawableID != -1) { mCustomDialogEventListener.customDialogEvent(drawableID);}dismiss(); }这样就把对话框的构造过程讲完了,完整的对话框代码是这样的:
public class CustomDialog extends Dialog implements View.OnClickListener{//增加一个回调函数,用以从外部接收返回值public interface ICustomDialogEventListener { public void customDialogEvent(int id);}private ICustomDialogEventListener mCustomDialogEventListener;private Context mContext;private String mStr;public CustomDialog(Context context) { super(context); mContext = context;}public CustomDialog(Context context, String str,ICustomDialogEventListener listener,int theme) { super(context, theme); mContext = context; mStr = str; mCustomDialogEventListener = listener;}private void bindImageClickEvent(View layout){ ImageView img1 = (ImageView)layout.findViewById(R.id.dialog_image1); ImageView img2 = (ImageView)layout.findViewById(R.id.dialog_image2); ImageView img3 = (ImageView)layout.findViewById(R.id.dialog_image3); ImageView img4 = (ImageView)layout.findViewById(R.id.dialog_image4); img1.setOnClickListener(this); img2.setOnClickListener(this); img3.setOnClickListener(this); img4.setOnClickListener(this);}@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LayoutInflater inflater = (LayoutInflater) mContext .getSystemService(Context.LAYOUT_INFLATER_SERVICE); View layout = inflater.inflate(R.layout.custom_dialog, null); TextView tv = (TextView)layout.findViewById(R.id.dialog_text); tv.setText(mStr); bindImageClickEvent(layout); this.setContentView(layout);}@Overridepublic void onClick(View view) { int id = view.getId(); int drawableID = -1; switch (id){case R.id.dialog_image1: drawableID = R.drawable.animal1; break;case R.id.dialog_image2: drawableID = R.drawable.animal2; break;case R.id.dialog_image3: drawableID = R.drawable.animal3; break;case R.id.dialog_image4: drawableID = R.drawable.animal4; break; } if (drawableID != -1) {mCustomDialogEventListener.customDialogEvent(drawableID); } dismiss();} }下面就是构造对话框的过程了:
Button btn = (Button)findViewById(R.id.btn_pop_dialog_1); btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) { CustomDialog dialog = new CustomDialog(MainActivity.this,"From btn 1",new CustomDialog.ICustomDialogEventListener() {@Overridepublic void customDialogEvent(int id) { ImageView imageView = (ImageView)findViewById(R.id.main_image); imageView.setImageDrawable(getResources().getDrawable(id));} },R.style.dialog); dialog.show();} });在我们收到传过来的DrawableID时,把它设置gc主页面ImageVIew里显示出来,这就完成了我们上面的功能。