Android自定义组件之ListPopWindow

最近在学习IOS开发,感触颇深,看到了iOS里面封装了好多组件,很多组件都是iOS自带的,相信一般的小公司的产品经理都是按照iOS的交互来设计UI,而且还要求Android要和iOS统一风格,这让Android开发人员很头痛,iOS自带组件很容易实现,而Android可能需要重写控件去配合iOS的效果。其实这样必然会导致性能的小将,或有些许的卡顿。个人认为,按照各自系统的风格和规范进行设计才能把自己的优点发挥到最大化。
下面就引出了今天的主题,自定义组件ListPopWindow,iOS中,这个效果是自带的。PopWindow可以说在项目里用的比较多的了,可能有n处要用到PopWindow,那么自定义一个PopWindow,到处来用更方便一些。
先看一下效果:

这里写图片描述

效果就是这样,看一下实现,其实也没多难,就是想开源出来供小伙伴们使用,如有不合理地方,希望大家多多指正。

1.自定义PopWindow

首先我们分析一下,这样的效果肯定是一个PopWindow嵌套着listview,而上面的title、和下面的cancel是两个文本框,实现起来也比较简单。
然后我们在PopWindow中声明两个接口,用来回调cancel和item的点击事件

1
2
3
4
5
6
7
public interface OnPopItemClickListener{
void onPopItemClick(View view,int position);
}
public interface OnBottomTextviewClickListener{
void onBottomClick();
}

然后再设置一些PopWindow的一些属性

1
2
3
4
5
6
7
8
9
10
11
12
parentView = LayoutInflater.from(context).inflate(R.layout.list_popwindow,null);
setContentView(parentView);
lv = (ListView) parentView.findViewById(R.id.lv_popwindow);
//设置弹出窗体的高
this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
this.setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
//设置弹出窗体可点击
this.setFocusable(true);
//实例化一个ColorDrawable颜色为半透明
ColorDrawable dw = new ColorDrawable(0xb0000000);
//设置SelectPicPopupWindow弹出窗体的背景
this.setBackgroundDrawable(dw);

看一下整体的代码吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/**
* Created by Hankkin on 16/1/25.
*/
public class ListPopWindow extends PopupWindow{
private Context context; //上下文
private View parentView; //父视图
private List<PopBean> dataList; //item数据源
private OnPopItemClickListener listener; //item点击接口
private ListView lv; //item列表视图
private View viewTop; //title视图
private String topText,bottomText; //title文字,bottom文字
private TextView tvTop,tvBottom; //title文本,bottom文本
private PopWindowAdapter adapter; //适配器
private OnBottomTextviewClickListener bottomListener;//底部点击接口
public interface OnPopItemClickListener{
void onPopItemClick(View view,int position);
}
public interface OnBottomTextviewClickListener{
void onBottomClick();
}
public ListPopWindow(Context context,OnPopItemClickListener listener,OnBottomTextviewClickListener bottomListener,
View parentView,List<PopBean> dataList,String bottomText,String topText){
this.context = context;
this.listener = listener;
this.parentView = parentView;
this.dataList = dataList;
this.bottomListener = bottomListener;
this.topText = topText;
this.bottomText = bottomText;
initViews();
}
private void initViews(){
parentView = LayoutInflater.from(context).inflate(R.layout.list_popwindow,null);
setContentView(parentView);
lv = (ListView) parentView.findViewById(R.id.lv_popwindow);
//设置弹出窗体的高
this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
this.setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
//设置弹出窗体可点击
this.setFocusable(true);
//实例化一个ColorDrawable颜色为半透明
ColorDrawable dw = new ColorDrawable(0xb0000000);
//设置SelectPicPopupWindow弹出窗体的背景
this.setBackgroundDrawable(dw);
//view添加OnTouchListener监听判断获取触屏位置如果在布局外面则销毁弹出框
parentView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
int height = parentView.findViewById(R.id.ll_bottom).getTop();
int y = (int) event.getY();
if (event.getAction() == MotionEvent.ACTION_UP) {
if (y > height) {
dismiss();
}
}
return true;
}
});
update();
viewTop = parentView.findViewById(R.id.view_line1);
tvBottom = (TextView) parentView.findViewById(R.id.tv_popwindow_bottom);
tvTop = (TextView) parentView.findViewById(R.id.tv_popwindow_first);
adapter = new PopWindowAdapter(context,dataList,false);
lv.setAdapter(adapter);
if (!TextUtils.isEmpty(topText)){
tvTop.setVisibility(View.VISIBLE);
tvTop.setText(topText);
viewTop.setVisibility(View.VISIBLE);
}
else {
tvTop.setVisibility(View.GONE);
viewTop.setVisibility(View.GONE);
}
if (!TextUtils.isEmpty(bottomText)){
tvBottom.setVisibility(View.VISIBLE);
tvBottom.setText(bottomText);
}
else {
tvBottom.setVisibility(View.GONE);
}
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
listener.onPopItemClick(view, i);
}
});
tvBottom.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
bottomListener.onBottomClick();
}
});
}
}

2.看一些item的bean

这里我就声明了title和图片的id

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.hankkin.library;
/**
* Created by Hankkin on 16/1/25.
*/
public class PopBean {
private String title;
private int icon_res;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getIcon_res() {
return icon_res;
}
public void setIcon_res(int icon_res) {
this.icon_res = icon_res;
}
public PopBean(String title, int icon_res) {
this.title = title;
this.icon_res = icon_res;
}
}

3.自定义adapter适配器

这里面可能要注意的就是item的背景设置,有的是上半部分圆角、有的是下半部分圆角,特殊处理一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder;
if (view == null) {
view = inflater.inflate(R.layout.listview_popwindow_item, null);
holder = new ViewHolder();
holder.tv_name = (TextView) view.findViewById(R.id.tv_title);
holder.v_line = (View) view.findViewById(R.id.v_line);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.tv_name.setText(dataList.get(i).getTitle());
if (dataList.size() - 1 == i) {
holder.v_line.setVisibility(View.INVISIBLE);
holder.tv_name.setBackground(context.getResources().getDrawable(R.drawable.selector_bottom_half));
} else {
holder.v_line.setVisibility(View.VISIBLE);
holder.tv_name.setBackground(context.getResources().getDrawable(R.drawable.list_gray_item));
}
return view;
}

最后看一下调用

Activity需要实现item接口(OnPopItemClickListener)和底部按钮接口(OnBottomTextviewClickListener)

1
2
3
4
5
6
7
8
9
public void show(View view){
List<PopBean> pops = new ArrayList<>();
for (int i=0;i<5;i++){
PopBean pop = new PopBean("item"+i,0);
pops.add(pop);
}
popWindow = new ListPopWindow(MainActivity.this,this,this,rl,pops,"cancel","title");
popWindow.showAtLocation(rl, Gravity.CENTER| Gravity.BOTTOM,0,0);
}

最后小编附上github源码地址,小伙伴们可以直接用哦。

https://github.com/Hankkin/ListPopwidowDemo