消息对话框在实现Android原生态开发的过程中是十分重要的。该篇文章将讲述仿IOS的消息对话框的实现。具体代码来源于网路(忘记了具体文章来源)。
实现效果如下图:

该消息对话框的实现主要使用到了listview和Dialog。当点击某个按钮时,弹出Dialog,Dialog上的view由listview实现。这样就实现了一个灵活的可复用的工具Dialog。具体代码如下。
首先给出XML布局文件和背景设置。
XML文件
<!-- dialog的布局view_dialog_select dialog打开的实际上是这个view -->
<?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="match_parent"
android:background="#00000000"
android:gravity="bottom"
android:orientation="vertical"
android:padding="5dip" >
<TextView
android:id="@+id/mTv_Title"
android:layout_width="match_parent"
android:layout_height="68dp"
android:layout_marginTop="5dip"
android:background="@drawable/dialog_item_bg_only"
android:padding="10dip"
android:textColor="#0073FF"
android:textSize="18sp"
android:gravity="center"
android:visibility="gone"/>
<ListView
android:id="@+id/dialog_list"
android:layout_width="match_parent"
android:dividerHeight="0.5dp"
android:divider="#DAD9DB"
android:layout_marginTop="5dip"
android:listSelector="@android:color/transparent"
android:cacheColorHint="@android:color/transparent"
android:layout_height="wrap_content" >
</ListView>
<Button
android:id="@+id/mBtn_Cancel"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="5dip"
android:background="@drawable/dialog_item_bg_only"
android:text="取消"
android:gravity="center"
android:textColor="#0073FF"
android:textSize="18sp" />
</LinearLayout>
listview所展示的每个item的布局文件view_dialog_item
<?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:orientation="vertical"
>
<TextView
android:id="@+id/dialog_item_bt"
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center"
android:textColor="#0073FF"
android:textSize="18sp" />
</RelativeLayout>
布局文件用到的样式:
dialog_item_bg_buttom
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"><shape>
<solid android:color="#CACACB" />
<corners android:bottomLeftRadius="5dp" android:bottomRightRadius="5dp" android:topLeftRadius="0dp" android:topRightRadius="0dp" />
</shape></item>
<item><shape>
<solid android:color="#EBEBEB" />
<corners android:bottomLeftRadius="5dp" android:bottomRightRadius="5dp" android:topLeftRadius="0dp" android:topRightRadius="0dp" />
</shape></item>
</selector>
dialog_item_bg_center
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"><shape>
<solid android:color="#CACACB" />
</shape></item>
<item><shape>
<solid android:color="#EBEBEB" />
</shape></item>
</selector>
dialog_item_bg_only
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"><shape>
<solid android:color="#CACACB" />
<corners android:bottomLeftRadius="5dp" android:bottomRightRadius="5dp" android:topLeftRadius="5dp" android:topRightRadius="5dp" />
</shape></item>
<item><shape>
<solid android:color="#EBEBEB" />
<corners android:bottomLeftRadius="5dp" android:bottomRightRadius="5dp" android:topLeftRadius="5dp" android:topRightRadius="5dp" />
</shape></item>
</selector>
dialog_item_bg_top
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"><shape>
<solid android:color="#CACACB" />
<corners android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp" android:topLeftRadius="5dp" android:topRightRadius="5dp" />
</shape></item>
<item><shape>
<solid android:color="#EBEBEB" />
<corners android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp" android:topLeftRadius="5dp" android:topRightRadius="5dp" />
</shape></item>
</selector>
上述为所有布局文件和背景设置,最主要的是view_dialog_select布局文件,在该文件中主要声明了一个listview控件。
Dialog的java代码
import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import java.util.List;
/**
* dialog
*
*/
public class SelectDialog extends Dialog implements OnClickListener,OnItemClickListener {
private SelectDialogListener mListener;
private Activity mActivity;
private Button mMBtn_Cancel;
private TextView mTv_Title;
private List<String> mName;
private String mTitle;
private boolean mUseCustomColor = false;
private int mFirstItemColor;
private int mOtherItemColor;
public interface SelectDialogListener {
public void onItemClick(AdapterView<?> parent, View view, int position, long id);
}
private SelectDialogCancelListener mCancelListener;
public interface SelectDialogCancelListener {
public void onCancelClick(View v);
}
public SelectDialog(Activity activity, int theme,
SelectDialogListener listener,List<String> names) {
super(activity, theme);
mActivity = activity;
mListener = listener;
this.mName=names;
// 设置是否点击外围解散
setCanceledOnTouchOutside(true);
}
/**
* @param activity 调用弹出菜单的activity
* @param theme 主题
* @param listener 菜单项单击事件
* @param cancelListener 取消事件
* @param names 菜单项名称
*
*/
public SelectDialog(Activity activity, int theme,SelectDialogListener listener,SelectDialogCancelListener cancelListener ,List<String> names) {
super(activity, theme);
mActivity = activity;
mListener = listener;
mCancelListener = cancelListener;
this.mName=names;
// 设置是否点击外围不解散
setCanceledOnTouchOutside(false);
}
/**
* @param activity 调用弹出菜单的activity
* @param theme 主题
* @param listener 菜单项单击事件
* @param names 菜单项名称
* @param title 菜单标题文字
*
*/
public SelectDialog(Activity activity, int theme,SelectDialogListener listener,List<String> names,String title) {
super(activity, theme);
mActivity = activity;
mListener = listener;
this.mName=names;
mTitle = title;
// 设置是否点击外围可解散
setCanceledOnTouchOutside(true);
}
public SelectDialog(Activity activity, int theme,SelectDialogListener listener,SelectDialogCancelListener cancelListener,List<String> names,String title) {
super(activity, theme);
mActivity = activity;
mListener = listener;
mCancelListener = cancelListener;
this.mName=names;
mTitle = title;
// 设置是否点击外围可解散
setCanceledOnTouchOutside(true);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = getLayoutInflater().inflate(R.layout.view_dialog_select,
null);
setContentView(view, new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
Window window = getWindow();
// 设置显示动画
window.setWindowAnimations(R.style.main_menu_animstyle);
WindowManager.LayoutParams wl = window.getAttributes();
wl.x = 0;
wl.y = mActivity.getWindowManager().getDefaultDisplay().getHeight();
// 以下这两句是为了保证按钮可以水平满屏
wl.width = LayoutParams.MATCH_PARENT;
wl.height = LayoutParams.WRAP_CONTENT;
// 设置显示位置
onWindowAttributesChanged(wl);
//setCanceledOnTouchOutside(false);
initViews();
}
private void initViews() {
DialogAdapter dialogAdapter=new DialogAdapter(mName);
ListView dialogList=(ListView) findViewById(R.id.dialog_list);
dialogList.setOnItemClickListener(this);
dialogList.setAdapter(dialogAdapter);
mMBtn_Cancel = (Button) findViewById(R.id.mBtn_Cancel);
mTv_Title = (TextView) findViewById(R.id.mTv_Title);
//mMBtn_Cancel.setOnClickListener(this);
mMBtn_Cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(mCancelListener != null){
mCancelListener.onCancelClick(v);
}
dismiss();
}
});
if(!TextUtils.isEmpty(mTitle) && mTv_Title != null){
mTv_Title.setVisibility(View.VISIBLE);
mTv_Title.setText(mTitle);
}else{
mTv_Title.setVisibility(View.GONE);
}
}
@Override
public void onClick(View v) {
dismiss();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
mListener.onItemClick(parent, view, position, id);
dismiss();
}
private class DialogAdapter extends BaseAdapter {
private List<String> mStrings;
private Viewholder viewholder;
private LayoutInflater layoutInflater;
public DialogAdapter(List<String> strings) {
this.mStrings = strings;
this.layoutInflater=mActivity.getLayoutInflater();
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mStrings.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return mStrings.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (null == convertView) {
viewholder=new Viewholder();
convertView=layoutInflater.inflate(R.layout.view_dialog_item, null);
viewholder.dialogItemButton=(TextView) convertView.findViewById(R.id.dialog_item_bt);
convertView.setTag(viewholder);
}else{
viewholder=(Viewholder) convertView.getTag();
}
viewholder.dialogItemButton.setText(mStrings.get(position));
if (!mUseCustomColor) {
mFirstItemColor = mActivity.getResources().getColor(R.color.dialog_blue);
mOtherItemColor = mActivity.getResources().getColor(R.color.dialog_blue);
}
if (1 == mStrings.size()) {
viewholder.dialogItemButton.setTextColor(mFirstItemColor);
viewholder.dialogItemButton.setBackgroundResource(R.drawable.dialog_item_bg_only);
} else if (position == 0) {
viewholder.dialogItemButton.setTextColor(mFirstItemColor);
viewholder.dialogItemButton.setBackgroundResource(R.drawable.dialog_item_bg_top);
} else if (position == mStrings.size() - 1) {
viewholder.dialogItemButton.setTextColor(mOtherItemColor);
viewholder.dialogItemButton.setBackgroundResource(R.drawable.dialog_item_bg_buttom);
} else {
viewholder.dialogItemButton.setTextColor(mOtherItemColor);
viewholder.dialogItemButton.setBackgroundResource(R.drawable.dialog_item_bg_center);
}
return convertView;
}
}
public static class Viewholder {
public TextView dialogItemButton;
}
/**
* 设置列表项的文本颜色
*/
public void setItemColor(int firstItemColor, int otherItemColor) {
mFirstItemColor = firstItemColor;
mOtherItemColor = otherItemColor;
mUseCustomColor = true;
}
}
通过代码我们可以看到该类继承了Dialog类,并实现了两个点击事件的接口。可以通过查看Dialog类的代码得知,Dialog本质上和一个Activity存在的区别并不明显,当我们调用dialog.show方法时,Dialog开始调用太自身的onCreate方法。
在这个SelectDialog类中我们提供了几个构造方法
public SelectDialog(Activity activity, int theme,SelectDialogListener listener,SelectDialogCancelListener cancelListener ,List<String> names);
以这个构造方法为例,他需要提供一个显示该Dialog的activity,以及两种监听器的实现和一个String链表。
其中activity表明Dialog在哪个主体界面上显示,而themo是表明显示的样式,SelectDialogListener 接口是指明listview的点击事件,SelectDialogCancelListener接口是点击取消按钮的点击事件,names是listview所要显示的内容。
不得不说,Android开发在一定程度上写出的代码要比Java后台开发更惊艳,由于各种框架的出现,Java后台开发更偏重于业务,而对编码思想的运用并不常见(架构师负责的),Android的整体框架比较少见,因此Android开发更侧重基础。
SelectDialog的使用
private void showDialog() {
List<String> list = new ArrayList<>();
list.add("拍照");
list.add("相册");
showDialog(new SelectDialog.SelectDialogListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch (position){
case 0:
break;
case 1:
break;
default:
break;
}
}
},list);
}
private SelectDialog showDialog(SelectDialog.SelectDialogListener listener, List<String> list){
SelectDialog dialog = new SelectDialog(this,
R.style.transparentFrameWindowStyle,listener,list);
dialog.show();
return dialog;
}

本文详细介绍了如何在Android开发中仿照iOS设计风格创建一个可复用的消息对话框,利用ListView和Dialog结合,通过XML布局和Java代码展示了从布局文件到Dialog实现的全过程,包括选中监听和取消按钮功能。
2154

被折叠的 条评论
为什么被折叠?



