...
先上效果图,自定义Dialog仿iOS弹出底部菜单如下所示:
根据弹出的效果可以确定其中 取消按钮跟上面的功能按钮有一定的间距,而且取消按钮是固定存在的,上面的功能按钮可以动态添加一个或者多个。
看到这种自定义控件一般都会感叹ios的UI确实很美观,所以安卓端各个大神们就会有更高大上的自定义控件来实现想要的各种效果。作为后辈自然也是很幸运,前辈们已经封装好了很多各种各样的功能demo分享给我们用,但是在实行cp大法(copy
and paste大法)肯定也不能忘了学习前辈们的实现思路和过程。菜鸟级别的我没做之前看着UI需求是处于有思路但敲不出代码的发呆状态,看完大神的demo后便恍然大悟,赶紧cp实现功能。
然后来看看大神的代码封装得好看起来也就通俗易懂了,首先自定义Dialog类ActionSheetDialog.class
-
public class ActionSheetDialog {
-
private Context context;
-
private Dialog dialog;
-
private TextView txt_title;
-
private TextView txt_cancel;
-
private LinearLayout lLayout_content;
-
private ScrollView sLayout_content;
-
private boolean showTitle = false;
-
private List<SheetItem> sheetItemList;
-
private Display display;
-
-
public ActionSheetDialog(Context context) {
-
this.context = context;
-
WindowManager windowManager = (WindowManager) context
-
.getSystemService(Context.WINDOW_SERVICE);
-
display = windowManager.getDefaultDisplay();
-
}
-
-
public ActionSheetDialog builder() {
-
// 获取Dialog布局
-
View view = LayoutInflater.from(context).inflate(
-
R.layout.toast_view_actionsheet, null);
-
-
// 设置Dialog最小宽度为屏幕宽度
-
view.setMinimumWidth(display.getWidth());
-
-
// 获取自定义Dialog布局中的控件
-
sLayout_content = (ScrollView) view.findViewById(R.id.sLayout_content);
-
lLayout_content = (LinearLayout) view
-
.findViewById(R.id.lLayout_content);
-
txt_title = (TextView) view.findViewById(R.id.txt_title);
-
txt_cancel = (TextView) view.findViewById(R.id.txt_cancel);
-
txt_cancel.setOnClickListener(new OnClickListener() {
-
@Override
-
public void onClick(View v) {
-
dialog.dismiss();
-
}
-
});
-
-
// 定义Dialog布局和参数
-
dialog = new Dialog(context, R.style.ActionSheetDialogStyle);
-
dialog.setContentView(view);
-
Window dialogWindow = dialog.getWindow();
-
dialogWindow.setGravity(Gravity.LEFT | Gravity.BOTTOM);
-
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
-
lp.x = 0;
-
lp.y = 0;
-
dialogWindow.setAttributes(lp);
-
-
return this;
-
}
-
-
public ActionSheetDialog setTitle(String title) {
-
showTitle = true;
-
txt_title.setVisibility(View.VISIBLE);
-
txt_title.setText(title);
-
return this;
-
}
-
-
public ActionSheetDialog setCancelable(boolean cancel) {
-
dialog.setCancelable(cancel);
-
return this;
-
}
-
-
public ActionSheetDialog setCanceledOnTouchOutside(boolean cancel) {
-
dialog.setCanceledOnTouchOutside(cancel);
-
return this;
-
}
-
-
/**
-
*
-
* @param strItem
-
* 条目名称
-
* @param color
-
* 条目字体颜色,设置null则默认蓝色
-
* @param listener
-
* @return
-
*/
-
public ActionSheetDialog addSheetItem(String strItem, SheetItemColor color,
-
OnSheetItemClickListener listener) {
-
if (sheetItemList == null) {
-
sheetItemList = new ArrayList<SheetItem>();
-
}
-
sheetItemList.add(new SheetItem(strItem, color, listener));
-
return this;
-
}
-
-
/** 设置条目布局 */
-
private void setSheetItems() {
-
if (sheetItemList == null || sheetItemList.size() <= 0) {
-
return;
-
}
-
-
int size = sheetItemList.size();
-
-
// TODO 高度控制,非最佳解决办法
-
// 添加条目过多的时候控制高度
-
if (size >= 7) {
-
LinearLayout.LayoutParams params = (LayoutParams) sLayout_content
-
.getLayoutParams();
-
params.height = display.getHeight() / 2;
-
sLayout_content.setLayoutParams(params);
-
}
-
-
// 循环添加条目
-
for (int i = 1; i <= size; i++) {
-
final int index = i;
-
SheetItem sheetItem = sheetItemList.get(i - 1);
-
String strItem = sheetItem.name;
-
SheetItemColor color = sheetItem.color;
-
final OnSheetItemClickListener listener = (OnSheetItemClickListener) sheetItem.itemClickListener;
-
-
TextView textView = new TextView(context);
-
textView.setText(strItem);
-
textView.setTextSize(18);
-
textView.setGravity(Gravity.CENTER);
-
-
// 背景图片
-
if (size == 1) {
-
if (showTitle) {
-
textView.setBackgroundResource(R.drawable.actionsheet_bottom_selector);
-
} else {
-
textView.setBackgroundResource(R.drawable.actionsheet_single_selector);
-
}
-
} else {
-
if (showTitle) {
-
if (i >= 1 && i < size) {
-
textView.setBackgroundResource(R.drawable.actionsheet_middle_selector);
-
} else {
-
textView.setBackgroundResource(R.drawable.actionsheet_bottom_selector);
-
}
-
} else {
-
if (i == 1) {
-
textView.setBackgroundResource(R.drawable.actionsheet_top_selector);
-
} else if (i < size) {
-
textView.setBackgroundResource(R.drawable.actionsheet_middle_selector);
-
} else {
-
textView.setBackgroundResource(R.drawable.actionsheet_bottom_selector);
-
}
-
}
-
}
-
-
// 字体颜色
-
if (color == null) {
-
textView.setTextColor(Color.parseColor(SheetItemColor.Blue
-
.getName()));
-
} else {
-
textView.setTextColor(Color.parseColor(color.getName()));
-
}
-
-
// 高度
-
float scale = context.getResources().getDisplayMetrics().density;
-
int height = (int) (45 * scale + 0.5f);
-
textView.setLayoutParams(new LinearLayout.LayoutParams(
-
LayoutParams.MATCH_PARENT, height));
-
-
// 点击事件
-
textView.setOnClickListener(new OnClickListener() {
-
@Override
-
public void onClick(View v) {
-
listener.onClick(index);
-
dialog.dismiss();
-
}
-
});
-
-
lLayout_content.addView(textView);
-
}
-
}
-
-
public void show() {
-
setSheetItems();
-
dialog.show();
-
}
-
-
public interface OnSheetItemClickListener {
-
void onClick(int which);
-
}
-
-
public class SheetItem {
-
String name;
-
OnSheetItemClickListener itemClickListener;
-
SheetItemColor color;
-
-
public SheetItem(String name, SheetItemColor color,
-
OnSheetItemClickListener itemClickListener) {
-
this.name = name;
-
this.color = color;
-
this.itemClickListener = itemClickListener;
-
}
-
}
-
-
public enum SheetItemColor {
-
Blue("#037BFF"), Red("#FD4A2E");
-
-
private String name;
-
-
private SheetItemColor(String name) {
-
this.name = name;
-
}
-
-
public String getName() {
-
return name;
-
}
-
-
public void setName(String name) {
-
this.name = name;
-
}
-
}
-
}
xml:
-
<?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="wrap_content"
-
android:orientation="vertical"
-
android:padding="8dp" >
-
-
<TextView
-
android:id="@+id/txt_title"
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:background="@drawable/toast_actionsheet_top_normal"
-
android:gravity="center"
-
android:minHeight="45dp"
-
android:paddingTop="10dp"
-
android:paddingBottom="10dp"
-
android:paddingLeft="15dp"
-
android:paddingRight="15dp"
-
android:textColor="@color/actionsheet_gray"
-
android:textSize="13sp"
-
android:visibility="gone" />
-
-
<ScrollView
-
android:id="@+id/sLayout_content"
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:fadingEdge="none"
-
>
-
-
<LinearLayout
-
android:id="@+id/lLayout_content"
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:orientation="vertical" >
-
</LinearLayout>
-
</ScrollView>
-
-
<TextView
-
android:id="@+id/txt_cancel"
-
android:layout_width="match_parent"
-
android:layout_height="45dp"
-
android:layout_marginTop="8dp"
-
android:background="@drawable/actionsheet_single_selector"
-
android:gravity="center"
-
android:text="取消"
-
android:textColor="@color/actionsheet_blue"
-
android:textSize="18sp"
-
android:textStyle="bold" />
-
-
</LinearLayout>
anim弹出框和弹入框动画:首先是弹入in,后面是弹出out
-
<?xml version="1.0" encoding="utf-8"?>
-
<translate xmlns:android="http://schemas.android.com/apk/res/android"
-
android:duration="300"
-
android:fromYDelta="100%"
-
android:toYDelta="0" />
-
<?xml version="1.0" encoding="utf-8"?>
-
<translate xmlns:android="http://schemas.android.com/apk/res/android"
-
android:duration="300"
-
android:fromYDelta="0"
-
android:toYDelta="100%" />
接下去就是需要使用到的drawable了,主要是对一些背景样式的设计,可以根据公司UI要求自定义设计,不清楚的小伙伴可以看完整的demo,此处就不贴代码了
最后就是最重要的使用了:
new ActionSheetDialog(MainActivity.this)
.builder()
.setCancelable(true)
.setCanceledOnTouchOutside(true)
.addSheetItem("用相机更换头像", SheetItemColor.Blue,
new OnSheetItemClickListener() {
@Override
public void onClick(int which) {
Toast.makeText(MainActivity.this, "用相机更换头像", Toast.LENGTH_SHORT).show();
}
})
.addSheetItem("去相册选择头像", SheetItemColor.Blue,
new OnSheetItemClickListener() {
@Override
public void onClick(int which) {
Toast.makeText(MainActivity.this, "去相册选择头像", Toast.LENGTH_SHORT).show();
}