一,基于上一章我们今天来封装完整版的IOS风格的弹窗
http://blog.csdn.net/m0_37667770/article/details/78040724
二,封装之前了解:
首先对于Builder设计模式不知道大家有没有研究过,我们可以看android源码例如:
AlertDialog原生弹窗等,Builder设计模式如果没有接触过的希望有时间多学习学习。
今天的分装采用Buider设计模式,即使你没研究过也可以看懂。
三,封装之前的所需素材分析:
如下图,有底部的,有中间弹出的,而且底部的弹出不一定是一个item有可能是好多个:
如上图我们可以看到最下面的弹窗不一定是一个,有可能是好多个,所以我们需要准备一个布局保证可以融拉无数条Item,虽然有点夸张。布局代码中我们可以找一个ScrollView作为容器:所以代码如下:
<?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/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/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"
/>
<!--作为容器来展示更多的Item-->
<ScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fadingEdge="none"
>
<LinearLayout
android:id="@+id/Layout_content_message"
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/sheet_one_selector"
android:gravity="center"
android:text="取消"
android:textColor="@color/actionsheet_blue"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
四,开始封装分析
1)我们首先理清思路:整个封装过程如何呢?
1.我们需要整个屏幕的宽度和高度来设置Item的宽度和限制弹窗高度,所以第一步
我们来获取屏幕窗口管理对象。getSystemService(Context.WINDOW_S);
2.我们可以看到我们的布局里面是一个标题TextView,然后用一个ScrollView
为了可以添加好多条目。里面有一个LinearLayout用来作为容器添加多个
item。第二部我们来进行Dialog布局的初始化,和设置弹出框口的位置样式等。
3.我们可能需要好多个Item条。所以需要定义一个集合用来储存item的条目,每
个条目都为一个TextView,我们同时需要传过来这个TextView的字体颜色,
回调的监听事件,字体内容。所以这里我们需要定义一个内部类用来储存这个
Item的这三条内容。换需要定义一个监听时间用来回调触发我们的点击事件。
4.我们需要一个静态内部类或者枚举来储存颜色。这里我用静态内部类。
五,开始撸代码:
1.首先我们来定义一个类名叫做SheetDialogIOS,定义构造方法并且获取屏幕管理
器获得显示器,为后面的弹窗宽度做准备。代码如下:
public class SheetDialogIOS {
private Context context;
private Display display;
/*
* 这里我们初始化context获取屏幕管理,得到屏幕显示器。
* */
public SheetDialogIOS(Context context) {
this.context = context;
WindowManager windowManager = (WindowManager)
context.getSystemService(Context.WINDOW_SERVICE);
display = windowManager.getDefaultDisplay();
}
}
2.我们采用构造者模式,来初始化Dialog或者AlerDialog的view以及设置属性等,都一样的。我这里就用上一章的AlertDialog吧。代码如下:
public class SheetDialogIOS {
private Context context;
private Display display;
private AlertDialog alertDialog;
private TextView tv_title, tv_cancal;
private ScrollView scrollView;
private LinearLayout linearLayout;
private boolean isShowTitle = false;
private ArrayList<SheetItem> sheetArrayList;
/*
* 这里我们初始化context获取屏幕管理,得到屏幕显示器。
* */
public SheetDialogIOS(Context context) {
this.context = context;
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
display = windowManager.getDefaultDisplay();
}
/**
* 实例化弹窗并且设置弹出位置和属性等
*/
public SheetDialogIOS builder() {
//为弹窗设置布局
View sheetDialgView = LayoutInflater.from(context).inflate(R.layout.sheet_dialog_bottom, null);
//这里需要设置宽度最小玩屏幕的宽度。不然显示宽度很小。你可以自己试试
Point point = new Point();
display.getSize(point);
//这里的display.getWidth过时了好像还可以用。你们自己试试吧。
sheetDialgView.setMinimumWidth(point.x);
scrollView = sheetDialgView.findViewById(R.id.scroll_view);
linearLayout = sheetDialgView.findViewById(R.id.Layout_content_message);
tv_title = sheetDialgView.findViewById(R.id.txt_title);
tv_cancal = sheetDialgView.findViewById(R.id.txt_cancel);
tv_cancal.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
//实例化弹窗设置view和弹窗的样式
alertDialog = new AlertDialog.Builder(context, R.style.ActionBootoomDialogStyle).create();
alertDialog.setView(sheetDialgView);
//我们知道弹窗默认弹出式在屏幕中间的。这里需要进行窗口设置为底部不然。弹窗最后会在中间
//获取弹窗的窗口对象
Window window = alertDialog.getWindow();
//设置最终显示的位置为最下边
window.setGravity(Gravity.BOTTOM);
//如果需要考虑你的弹窗坐标位置那么下面可以通过改变layoutParams.y的值来设置出现距离底部的位置。
WindowManager.LayoutParams layoutParams = window.getAttributes();
layoutParams.x = 0;
layoutParams.y = 0;
window.setAttributes(layoutParams);
return this;
}
/*
*dialog弹出后会点击屏幕或物理返回键,dialog不消失
*/
public SheetDialogIOS setCancelable(boolean cancal) {
alertDialog.setCancelable(cancal);
return this;
}
/*
* dialog.setCanceledOnTouchOutside(false);
* dialog弹出后会点击屏幕,dialog不消失;点击物理返回键dialog消失
* */
public SheetDialogIOS touchOutSideIfCancal(boolean cancal) {
alertDialog.setCanceledOnTouchOutside(cancal);
return this;
}
/*
* 显示title是否显示:这里可以设置boolean也可以不设置以为如果你需要就显示不需要就不用调这个方法.只要调用那么就设为true
* */
public SheetDialogIOS setTitle(String title/*, boolean isShowTitle*/) {
this.isShowTitle = true;
tv_title.setVisibility(View.VISIBLE);
tv_title.setText(title);
return this;
}
/*
* 这里需要定义一个静态类用来存储字体颜色的。
* */
public static class ColorClass {
public static int COLOR_RED = Color.RED;
public static int COLOR_BLUE = Color.BLUE;
}
/*
* 定义一个接口用来进行点击事件的回掉。
* */
public interface SheetOnclickListenner {
void sheetOnclickListenner(int index);
}
//添加需要的每个item要显示的内容到这个item里面。
public SheetDialogIOS addSheetItem(String strItem, int color, SheetOnclickListenner sheetOnclickListenner) {
if (sheetArrayList == null) {
sheetArrayList = new ArrayList<>();
}
sheetArrayList.add(new SheetItem(strItem, color, sheetOnclickListenner));
return this;
}
private class SheetItem {
private int Color;
private String strItem;
private SheetOnclickListenner sheetOnclickListenner;
public SheetItem(String strItem, int color, SheetOnclickListenner sheetOnclickListenner) {
this.Color = color;
this.sheetOnclickListenner = sheetOnclickListenner;
this.strItem = strItem;
}
}
/*
*用来显示弹窗弹窗
* */
public SheetDialogIOS Show() {
//在显示之前首先将所有的条目都初始化并且显示到我们设置的布局上面。
setSheetItems();
alertDialog.show();
return this;
}
// 关键一步。这里讲所有添加到集合里面的条目都初始化显示到我们设置的布局alertDialgView上面。
private void setSheetItems() {
}
}
3.这里到最后一步了。这里将所有添加到集合里面的条目都初始化显示到我们设置的布局alertDialgView
的linearLayout上面。代码如下。每一行需要注释的地方都解释了。看懂没问题。
/** 设置条目布局 */
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);
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);
}
}
六,大功告成:
我们可以在Activity里面进行调用:代码如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void OnclickTx(View view) {
showDialogss();
}
private void showDialogss() {
new SheetDialogIOS(MainActivity.this)
.builder()
.setCancelable(true)
.setTouchOutSideIfCancal(true)
.addSheetItem("打开相册",
SheetDialogIOS.ColorClass.COLOR_BLUE,
new SheetDialogIOS.SheetOnclickListenner() {
@Override
public void sheetOnclickListenner(int index) {
}
})
.addSheetItem("打开照相机",
SheetDialogIOS.ColorClass.COLOR_RED,
new SheetDialogIOS.SheetOnclickListenner() {
@Override
public void sheetOnclickListenner(int index) {
}
})
.addSheetItem("打开镜子",
SheetDialogIOS.ColorClass.COLOR_RED,
new SheetDialogIOS.SheetOnclickListenner() {
@Override
public void sheetOnclickListenner(int index) {
}
}).Show();
}
}
运行结果如下:
Demon的 github地址:https://github.com/luhenchang/MyISODilalog.git
快下班了。哈赛该!900场亚索胜率51%今晚继续!