android UI系列 - 自定义android4.0风格多功能对话框(dialog)(附图)
android的默认UI风格在4.0之前用一个字来形容就是“丑”,最让我们开发人员受不了的是默认的很多UI 组件修改样式非常麻烦,有些样式根本就不能直接修改,例如对话框dialog,默认的是黑灰白3色的样式,非常的简陋,更大的问题是其背景修改起来非常不便,对于此,我便自己写了一个自定义的对话框。废话不多说,直接上代码。
talertdialog.xml
<?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="match_parent"
android:id="@+id/layout_dialog_baselayout"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:gravity="center"
android:background="@android:drawable/screen_background_dark_transparent"
>
<RelativeLayout
android:id="@+id/dialog_content_baselayout"
android:padding="5dp"
android:layout_width="300dp"
android:layout_height="160dp"
android:background="@drawable/dialog_bg_drawable"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:id="@+id/dialog_topPanel"
android:layout_alignLeft="@+id/dialog_content_baselayout"
android:layout_alignTop="@+id/dialog_content_baselayout"
android:paddingLeft="5dp" android:paddingRight="5dp"
android:paddingTop="3dp" android:paddingBottom="3dp"
android:orientation="vertical"
>
<TextView
android:id="@+id/dialog_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textColor="@color/bg_normal_yellow_light"
android:maxLines="1"
android:ellipsize="end"
/>
<View android:layout_width="match_parent" android:layout_height="1dp"
android:background="@color/white_alpha"/>
</LinearLayout>
<ScrollView android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/dialog_buttonPanel"
android:layout_below="@+id/dialog_topPanel"
android:scrollbars="none"
android:gravity="center"
android:paddingTop="5dip"
android:paddingBottom="5dip"
android:paddingLeft="10dip"
android:paddingRight="10dip"
>
<TextView android:id="@+id/dialog_message"
style="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:padding="5dip" />
</ScrollView>
<LinearLayout
android:id="@+id/dialog_buttonPanel"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_centerInParent="true"
android:orientation="horizontal"
android:padding="5dp"
android:gravity="center"
>
<Button android:id="@+id/dialog_button1"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="left|center_vertical"
android:background="@drawable/yellow_light_bg_selector"
android:textColor="@android:color/white"
android:layout_marginRight="50dp"
android:maxLines="1"
android:layout_weight="1"
/>
<Button android:id="@+id/dialog_button3"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical"
android:background="@drawable/yellow_light_bg_selector"
android:textColor="@android:color/white"
android:layout_marginRight="30dp"
android:text=""
android:layout_weight="1"
android:maxLines="1"
android:visibility="gone"
/>
<Button android:id="@+id/dialog_button2"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:background="@drawable/yellow_light_bg_selector"
android:layout_gravity="right|center_vertical"
android:textColor="@android:color/white"
android:maxLines="1"
android:layout_weight="1"
/>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
此xml是自定义dialog的布局文件。
--- MyDialog.java
此类是自定义dialog的实现类,注意此dialog不是extends Dialog来实现的,而是用PopupWindow来仿真模拟实现的。其实android dialog的原理和PopupWindow实现的原理是一样的。
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.text.Spanned;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.ScaleAnimation;
import android.view.animation.Animation.AnimationListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.LinearLayout.LayoutParams;
import android.widget.PopupWindow.OnDismissListener;
/**
* @author TangXL
*
*/
public class MyDialog{
private Context mContext = null;
private LayoutInflater inflate = null;
private WindowManager mWindowManager = null;
private PopupWindow mDialog = null;
private View mContentView = null;
private View parent = null;
private RelativeLayout baseLayout = null;
private RelativeLayout contentLayout = null;
private LinearLayout buttonPanel = null;
private LinearLayout titlePanel = null;
private boolean mIsShowing = false;
private boolean isShowButton1 = false;
private boolean isShowButton2 = false;
private boolean isShowButton3 = false;
private boolean isShowTitlePan = false;
private TextView mDialogTitle = null;
private TextView mDialogMessage = null;
private String mTitle = null;
private String mMessage = null;
private int mMessageTextsize = 14;
private Button button1,button2,button3;
private Drawable mPositiveBgDrawable = null;
private Drawable mNegativeBgDrawable = null;
private Drawable mNeutralBgDrawable = null;
private int dialog_height = 160; //default
private DialogDismissListener mDialogDismissListener;
public MyDialog(Context context,View parentview) {
this.mContext = context;
this.parent = parentview;
this.inflate = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
this.mWindowManager = (WindowManager) context.getSystemService(Activity.WINDOW_SERVICE);
inIntDialogContentView();
}
private void inIntDialogContentView(){
mContentView = inflate.inflate(R.layout.talertdialog, null);
mDialogTitle = (TextView) mContentView.findViewById(R.id.dialog_title);
mDialogMessage = (TextView) mContentView.findViewById(R.id.dialog_message);
button1 = (Button) mContentView.findViewById(R.id.dialog_button1);
button2 = (Button) mContentView.findViewById(R.id.dialog_button2);
button3 = (Button) mContentView.findViewById(R.id.dialog_button3);
baseLayout = (RelativeLayout) mContentView.findViewById(R.id.layout_dialog_baselayout);
buttonPanel = (LinearLayout) mContentView.findViewById(R.id.dialog_buttonPanel);
contentLayout = (RelativeLayout) mContentView.findViewById(R.id.dialog_content_baselayout);
titlePanel = (LinearLayout) mContentView.findViewById(R.id.dialog_topPanel);
}
public interface ButtonClickListener{
public boolean handleClick();
};
public interface DialogDismissListener{
public boolean handleDismiss();
};
public MyDialog setPositiveButton(String text,final ButtonClickListener clickListener)
{
isShowButton1 = true;
button1.setText(text);
button1.setOnClickListener(new OnClickListener() {
//@Override
public void onClick(View v) {
if(clickListener == null || clickListener.handleClick())
{
dismiss();
}
}
});
return this;
}
public MyDialog setNegativeButton(String text,final ButtonClickListener clickListener)
{
isShowButton2 = true;
button2.setText(text);
button2.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(clickListener == null || clickListener.handleClick())
{
dismiss();
}
}
});
return this;
}
public MyDialog setNeutralButton(String text,final ButtonClickListener clickListener)
{
isShowButton3 = true;
button3.setText(text);
button3.setOnClickListener(new OnClickListener() {
//@Override
public void onClick(View v) {
if(clickListener == null || clickListener.handleClick())
{
dismiss();
}
}
});
return this;
}
public MyDialog setDialogHeight(int height){
dialog_height = height;
return this;
}
public MyDialog setTitle(String title){
mTitle = title;
mDialogTitle.setText(mTitle);
isShowTitlePan = true;
return this;
}
public MyDialog setMessage(String message){
mMessage = message;
mDialogMessage.setText(mMessage);
return this;
}
public MyDialog setMessage(Spanned htmlMessage){
mDialogMessage.setText(htmlMessage);
return this;
}
public MyDialog setMessageTextSize(int tsize){
mMessageTextsize = tsize;
return this;
}
public MyDialog setPozitiveDrawable(int resid){
mPositiveBgDrawable = mContext.getResources().getDrawable(resid);
return this;
}
public MyDialog setNegativeDrawable(int resid){
mNegativeBgDrawable = mContext.getResources().getDrawable(resid);
return this;
}
public MyDialog setNeutralDrawable(int resid){
mNeutralBgDrawable = mContext.getResources().getDrawable(resid);
return this;
}
public boolean isShowing()
{
return mIsShowing;
}
private void setDialogLayoutHeight() {
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) contentLayout.getLayoutParams();
layoutParams.height = dialog_height;
contentLayout.setLayoutParams(layoutParams);
}
private void setButtonBgDrawable() {
if(mPositiveBgDrawable != null){
button1.setBackgroundDrawable(mPositiveBgDrawable);
}
if(mNegativeBgDrawable != null){
button2.setBackgroundDrawable(mNegativeBgDrawable);
}
if(mNeutralBgDrawable != null){
button3.setBackgroundDrawable(mNeutralBgDrawable);
}
}
public void inint() {
isShowButton1 = false;
isShowButton2 = false;
isShowButton3 = false;
dialog_height = 160;
mMessageTextsize = 14;
isShowTitlePan = false;
if(mDialog != null && mDialog.isShowing()){
mDialog.dismiss();
}
}
private void checkShowButtonCounts(){
System.out.println("isShowButton1:"+isShowButton1+"|isShowButton2:"+isShowButton2+"|isShowButton3:"+isShowButton3);
if(isShowButton1 && isShowButton2 && isShowButton3){ //3个按钮全部显示
LinearLayout.LayoutParams params = (LayoutParams) button1.getLayoutParams();
RelativeLayout.LayoutParams params_bp = (android.widget.RelativeLayout.LayoutParams) buttonPanel.getLayoutParams();
params.rightMargin = 30;
button1.setLayoutParams(params);
params_bp.width = 310;
buttonPanel.setLayoutParams(params_bp);
button1.setVisibility(View.VISIBLE);
button2.setVisibility(View.VISIBLE);
button3.setVisibility(View.VISIBLE);
}else if(isShowButton1 && !isShowButton2 && !isShowButton3) // 只显示第一个按钮
{
button1.setWidth(130);
LinearLayout.LayoutParams params = (LayoutParams) button1.getLayoutParams();
params.rightMargin = 0;
params.weight = 0;
button1.setLayoutParams(params);
button1.setVisibility(View.VISIBLE);
button2.setVisibility(View.GONE);
button3.setVisibility(View.GONE);
}else{
LinearLayout.LayoutParams params = (LayoutParams) button1.getLayoutParams();
params.rightMargin = 50;
button1.setLayoutParams(params);
button1.setVisibility(View.VISIBLE);
button2.setVisibility(View.VISIBLE);
button3.setVisibility(View.GONE);
}
}
public interface IAnimEnd{
public void handlerAnimEnd();
}
public void show(){
if(mDialog == null )
{
mDialog = new PopupWindow(mContentView, WindowsUtils.width, WindowsUtils.height);
ColorDrawable dw = new ColorDrawable(-00000);
mDialog.setBackgroundDrawable(dw);
}
setButtonBgDrawable();
checkShowButtonCounts();
checkDialogTitle();
setDialogLayoutHeight();
mDialogMessage.setTextSize(mMessageTextsize);
setMyDialogDismissListn(mDialogDismissListener);
if(mDialog != null && !mDialog.isShowing() && (parent != null)){
mDialog.showAtLocation(parent, Gravity.CENTER, 0, 0);
setDialogInAnimation();
}
mIsShowing = true;
}
private void checkDialogTitle() {
// TODO Auto-generated method stub
if(!isShowTitlePan){
titlePanel.setVisibility(View.GONE);
dialog_height = dialog_height - 40;
}else{
titlePanel.setVisibility(View.VISIBLE);
}
}
/** 设置对话框进入显示动画 **/
private void setDialogInAnimation() {
AnimationSet anim_in = new AnimationSet(true);
anim_in.setInterpolator(new DecelerateInterpolator());
ScaleAnimation scale = new ScaleAnimation(0.8f, 1.0f, 0.8f, 1.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scale.setDuration(300);
AlphaAnimation alpha = new AlphaAnimation(0.6f, 1.0f);
alpha.setDuration(300);
anim_in.addAnimation(scale);
anim_in.addAnimation(alpha);
contentLayout.startAnimation(anim_in);
mDialog.setFocusable(true);
mDialog.update();
}
private void setDialogOutAnimation(final IAnimEnd animend){
AnimationSet anim_out = new AnimationSet(true);
anim_out.setInterpolator(new AccelerateInterpolator());
ScaleAnimation scale = new ScaleAnimation(1.0f, 0.5f, 1.0f, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scale.setDuration(150);
AlphaAnimation alpha = new AlphaAnimation(1.0f, 0.0f);
alpha.setDuration(150);
anim_out.addAnimation(scale);
anim_out.addAnimation(alpha);
anim_out.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
if(animend != null){
animend.handlerAnimEnd();
}
}
});
contentLayout.startAnimation(anim_out);
}
public void dismiss(){
if(mDialog != null && mDialog.isShowing())
{
setDialogOutAnimation(new IAnimEnd() {
//@Override
public void handlerAnimEnd() {
mDialog.dismiss();
}
});
mIsShowing = false;
}
}
public MyDialog setDialogDismissListn(DialogDismissListener dismissListn){
mDialogDismissListener = dismissListn;
return this;
}
private void setMyDialogDismissListn(final DialogDismissListener dismissListn){
if(mDialog != null){
mDialog.setOnDismissListener(new OnDismissListener() {
//@Override
public void onDismiss() {
if(dismissListn != null){
dismissListn.handleDismiss();
}
mDialog.setFocusable(false);
mDialog.update();
}
});
}
}
}
注释因为出乱码很多都删除了,不过看方法名应该是能理解的。
--- WindowsUtils 获取屏幕的尺寸
import android.app.Activity;
import android.util.DisplayMetrics;
public class WindowsUtils {
public static int width = 0;
public static int height = 0;
private static DisplayMetrics outMetrics = null;
public static void getWindowSize(Activity context){
outMetrics = new DisplayMetrics();
context.getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
width = outMetrics.widthPixels;
height = outMetrics.heightPixels;
}
}
最重要的相关类已经贴出来了,现在说明其在代码中的用法:
第1种方法:
/*
* parentview --- 弹出dialog的所属Layout(这个必须在你用的activity布局文件中获取)
* 使用方法介绍:
* 1.setDialogHeight() 可以设置自定义dialog的高度,默认为160,一般设置为140,120,160
* 2.setMessage() 设置内容,可以为html转化成的Spanned对象
* 3.setTitle() 设置标题,不设置时会自动hide
* 4.setPositiveButton() 设置前面按钮的text和点击事件
* 5.setNegativeButton() 设置后面按钮的text和点击事件
* 6.设置其他,具体到Mydialog中看,布局会根据设置的按钮个数来自动调整布局
*/
new MyDialog(LoginActivity.this, parentview).setTitle("标题").setMessage("正文内正文内容正文内容正文内容正文内容")
.setPositiveButton("确定", new ButtonClickListener() {
@Override
public boolean handleClick() {
showToast("click 确定");
return true;
}
})
.setNegativeButton("取消", new ButtonClickListener() {
@Override
public boolean handleClick() {
showToast("click 取消");
return true;
}
})
.show();
此用法弹出的是如下图所示的dialog:
第2种方法:
new MyDialog(BaseActivity.this, parentview).setDialogHeight(140)
.setMessage(ErrorUtils.getErrorInfoByCode(errorCode))
.setPositiveButton("确定", new ButtonClickListener() {
@Override
public boolean handleClick() {
showToast("click 确定");
return true;
}
})
.show();
OK,到此结束,写的仓促,欢迎拍砖,各种不足地方,各位可自行修改,源码就不上了,因为是从以前做的项目抽出来的。
此为个人原创,如需转载,敬请注明个人出处(http://blog.csdn.net/xl_tang/article/details/7711096),谢谢。- XL_Tang