自从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
MainActivity.java:<?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>
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可以使用,其中布局文件中有两张图片需要自己去修改,这两个图标我就不上传了。