自从Android进入7.0之后,使用PoppupWindow是越来越不顺手了,各种问题出现,而且对于很多个性化定义不是很完美,下面是我做了一些小封装的demo,有问题大家提出来一起学习。
废话不多说,直接上代码:
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/ll_container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"></LinearLayout>
custom_poppup_window.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="match_parent" android:background="#fff" android:orientation="vertical"> <FrameLayout android:id="@+id/ll_tab" android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal" ></FrameLayout> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/colorPrimary" /> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="#fff"> <!--内容区--> <FrameLayout android:id="@+id/fl_content" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#fff" /> <!--遮罩区--> <View android:id="@+id/mask" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#99000000" android:visibility="gone" /> <!--弹出框--> <FrameLayout android:id="@+id/fl_pop" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="left" android:background="#fff" android:orientation="horizontal" android:visibility="gone"></FrameLayout> </FrameLayout> </LinearLayout>
item_pop_view.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:background="#fff" android:orientation="horizontal"> <ListView android:id="@+id/lv_city" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:scrollbars="none" /> <ListView android:id="@+id/lv_age" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:scrollbars="none" /> </LinearLayout>
item_tab_view.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"> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal"> <TextView android:id="@+id/tv_city" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:drawableRight="@mipmap/icon_to_down" android:gravity="center" android:paddingLeft="20dp" android:paddingRight="20dp" android:text="城市" /> <View android:layout_width="1dp" android:layout_height="match_parent" android:background="@color/colorPrimary" /> <TextView android:id="@+id/tv_age" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:drawableRight="@mipmap/icon_to_down" android:gravity="center" android:paddingLeft="20dp" android:paddingRight="20dp" android:text="年龄" /> </LinearLayout> </LinearLayout>
MainActivity.java:
public class MainActivity extends AppCompatActivity { private String content[]; private String citys[] = {"北京", "上海", "广州", "深圳"}; private String ages[] = {"1-5", "6-10", "11-15", "16-20"};
//父布局容器,即Activity中最外层容器
private LinearLayout ll_container;
//封装的popupWindow布局 private CustomPopupWindow popupWindow;
//对话框的内容容器
private FrameLayout popView;
//正文内容容器
private FrameLayout contentView;
//顶部条件筛选栏容器
private FrameLayout tabView;
//对话框的详细布局
private View viewPop;
//条件筛选详细布局
private View viewTab;
private TextView tvCity;
private TextView tvAge;
private ListView lvCity;
private ListView lvAge;
//内容列表
private ListView lvContent;
/**
* 当前展开位置下标
*/
private int currentPos = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initEvent();
}
private void initView() {
ll_container = this.findViewById(R.id.ll_container);
popupWindow = new CustomPopupWindow(this, ll_container);
popView = popupWindow.getPopupView();
contentView = popupWindow.getContentView();
tabView = popupWindow.getTabView();
viewPop = LayoutInflater.from(this).inflate(R.layout.item_pop_view, null);
viewTab = LayoutInflater.from(this).inflate(R.layout.item_tab_view, null);
popView.addView(viewPop);
tabView.addView(viewTab);
lvContent = new ListView(this);
contentView.addView(lvContent);
tvCity = viewTab.findViewById(R.id.tv_city);
tvAge = viewTab.findViewById(R.id.tv_age);
lvCity = viewPop.findViewById(R.id.lv_city);
lvAge = viewPop.findViewById(R.id.lv_age);
content = new String[20];
for (int i = 0; i < 20; i++) {
content[i] = "第" + (1 + i) + "项";
}
ArrayAdapter contentAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, content);
lvContent.setAdapter(contentAdapter);
//创建数组适配器对象,并且通过参数设置类item项的布局样式和数据源
ArrayAdapter cityAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, citys);
//把数组适配器加载到ListView控件中
lvCity.setAdapter(cityAdapter);
ArrayAdapter ageAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, ages);
//把数组适配器加载到ListView控件中
lvAge.setAdapter(ageAdapter);
}
private void initEvent() {
tvCity.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (popupWindow != null) {
if (!popupWindow.isShow()) {
currentPos = 1;
switchPop();
popupWindow.show();
} else {
if (currentPos == 2) {
currentPos = 1;
switchPop();
} else {
currentPos = -1;
popupWindow.dismiss();
}
}
}
}
});
tvAge.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (popupWindow != null) {
if (!popupWindow.isShow()) {
currentPos = 2;
switchPop();
popupWindow.show();
} else {
if (currentPos == 1) {
currentPos = 2;
switchPop();
} else {
currentPos = -1;
popupWindow.dismiss();
}
}
}
}
});
}
/**
* 切换帅选条件
*/
private void switchPop() {
if (currentPos == 1) {
lvCity.setVisibility(View.VISIBLE);
lvAge.setVisibility(View.GONE);
} else {
lvCity.setVisibility(View.GONE);
lvAge.setVisibility(View.VISIBLE);
}
}
}
CustomPopupWindow.java:
public class CustomPopupWindow { private View pop; private Context context; /** * 标题栏 */ private FrameLayout ll_tab; /** * 内容区域 */ private FrameLayout fl_content; /** * 弹出框区域 */ private FrameLayout fl_pop; /** * 遮罩层区域 */ private View mask; /** * 是否已打开对话框 */ private boolean hasOpen = false; /** * @param context * @param parentContainer 最外层父容器 */ public CustomPopupWindow(Context context, LinearLayout parentContainer) { this.context = context; pop = LayoutInflater.from(context).inflate(R.layout.custom_poppup_window, null); parentContainer.addView(pop); initView(); initEvent(); } private void initView() { ll_tab = pop.findViewById(R.id.ll_tab); fl_content = pop.findViewById(R.id.fl_content); fl_pop = pop.findViewById(R.id.fl_pop); mask = pop.findViewById(R.id.mask); } private void initEvent() { mask.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dismiss(); } }); } /** * 打开对话框 */ public void show() { if (!hasOpen) { fl_pop.setVisibility(View.VISIBLE); fl_pop.setAnimation(AnimationUtils.loadAnimation(context, R.anim.add_menu_in)); mask.setVisibility(View.VISIBLE); mask.setAnimation(AnimationUtils.loadAnimation(context, R.anim.add_mask_in)); hasOpen = true; } } /** * 关闭对话框 */ public void dismiss() { fl_pop.setVisibility(View.GONE); fl_pop.setAnimation(AnimationUtils.loadAnimation(context, R.anim.add_menu_out)); mask.setVisibility(View.GONE); mask.setAnimation(AnimationUtils.loadAnimation(context, R.anim.add_mask_out)); hasOpen = false; } /** * 对话框是否已经打开 * * @return */ public boolean isShow() { return hasOpen; } /** * 获取弹出框的容器,用来自己添加View * * @return */ public FrameLayout getPopupView() { return fl_pop; } /** * 获取内容的容器,用来自己添加View * * @return */ public FrameLayout getContentView() { return fl_content; } /** * 获取tab的容器,用来自己添加View * * @return */ public FrameLayout getTabView() { return ll_tab; } }
动画文件:
add_mask_in.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="250"> <alpha android:fromAlpha="0" android:toAlpha="1" /> </set>
add_mask_out.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="250"> <alpha android:fromAlpha="1" android:toAlpha="0" /> </set>add_menu_in.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="250"> <translate android:fromYDelta="-100%p" android:toYDelta="0" /> </set>add_menu_out.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="250"> <translate android:fromYDelta="0" android:toYDelta="-100%p" /> </set>
上面的代码都是完整的,直接copy可以使用,其中布局文件中有两张图片需要自己去修改,这两个图标我就不上传了。