我们在常用的电商或者旅游APP中,例如美团,手机淘宝等等,都能够看的到有那种下拉式的二级列表菜单。具体如图所示:
上面两张图就是美团的一个二级列表菜单的一个展示。我相信很多人都想开发一个跟它一样的功能放到自己的APP中。好,接下来我们就开始动手,解决它。
<喎�"http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPGgyPjGjrL3hubm31s72PC9oMj4KPHA+ytfPyKOsztLDx7j4s/bV4rj2z8LAtLLLtaXQ6NKqtcTX6b2ooaPO0sPH08PP37/yzbzAtLfWzvahozwvcD4KPHA+PGltZyBzcmM9"http://www.2cto.com/uploadfile/Collfiles/20140923/2014092309051719.jpg" width="600" alt="\">
1)如上图所示,最外围的是一个Activity,顶部包含了一个View的容器,这个容器主要是装载ToggleButton来实现诸如美团里面的“美食,全城,理我最近,刷选”这一行。这一行一点就会弹出对应的下来菜单。
2)下拉菜单是如何实现的呢?,这里我们利用了PopupWindow来实现这一弹出式窗口。然后我们在弹出式窗口里面再定义我们的下来列表项,是单列还是二级菜单,都是由里面来定。
3)不同的菜单,需要一级或者需要二级,在这里根据我的需求而变动。我们在PopupWindow上面加一个自定义的LeftView,或者是MiddleView,RightView。主要是一个ToggleButton,你弹出一个窗口,你就定制一个窗口。
3)视图里面嵌入ListView,就形成了列表项。
好分析就到上面为止,接下来我们一步步的说明实现。
2,项目结构
本项目的项目结构如图所示:
1) Adapter。适配器,主要是为ListView提供数据适配的。
2)MainActivity。主活动页面。
3)ExpandTabView。本项目的核心类,它包含ToggleButton容器和PopupWindow,是控制弹出窗口的核心类。
4)ViewLeft,ViewMiddle,ViewRight。是弹出里面嵌套的类,实现不同的列表菜单。
3,MainActivity
承载所有元素。看代码比看文字实在。
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
package
com.example.expandtabview;
import
java.util.ArrayList;
import
android.app.Activity;
import
android.os.Bundle;
import
android.util.Log;
import
android.view.View;
import
android.widget.Toast;
import
com.example.view.ExpandTabView;
import
com.example.view.ViewLeft;
import
com.example.view.ViewMiddle;
import
com.example.view.ViewRight;
public
class
MainActivity
extends
Activity {
private
static
final
String TAG =
"MainActivity"
;
private
ExpandTabView expandTabView;
private
ArrayList<view> mViewArray =
new
ArrayList<view>();
private
ViewLeft viewLeft;
private
ViewMiddle viewMiddle;
private
ViewRight viewRight;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initVaule();
initListener();
}
private
void
initView() {
Log.d(TAG,
"initView"
);
expandTabView = (ExpandTabView) findViewById(R.id.expandtab_view);
viewLeft =
new
ViewLeft(
this
);
viewMiddle =
new
ViewMiddle(
this
);
viewRight =
new
ViewRight(
this
);
}
private
void
initVaule() {
Log.d(TAG,
"initValue"
);
mViewArray.add(viewLeft);
mViewArray.add(viewMiddle);
mViewArray.add(viewRight);
ArrayList<string> mTextArray =
new
ArrayList<string>();
mTextArray.add(
"距离"
);
mTextArray.add(
"区域"
);
mTextArray.add(
"距离"
);
expandTabView.setValue(mTextArray, mViewArray);
//将三个下拉列表设置进去
expandTabView.setTitle(viewLeft.getShowText(),
0
);
expandTabView.setTitle(viewMiddle.getShowText(),
1
);
expandTabView.setTitle(viewRight.getShowText(),
2
);
}
private
void
initListener() {
Log.d(TAG,
"initListener"
);
viewLeft.setOnSelectListener(
new
ViewLeft.OnSelectListener() {
@Override
public
void
getValue(String distance, String showText) {
Log.d(
"ViewLeft"
,
"OnSelectListener, getValue"
);
onRefresh(viewLeft, showText);
}
});
viewMiddle.setOnSelectListener(
new
ViewMiddle.OnSelectListener() {
@Override
public
void
getValue(String showText) {
Log.d(
"ViewMiddle"
,
"OnSelectListener, getValue"
);
onRefresh(viewMiddle,showText);
}
});
viewRight.setOnSelectListener(
new
ViewRight.OnSelectListener() {
@Override
public
void
getValue(String distance, String showText) {
Log.d(
"ViewRight"
,
"OnSelectListener, getValue"
);
onRefresh(viewRight, showText);
}
});
}
private
void
onRefresh(View view, String showText) {
Log.d(TAG,
"onRefresh,view:"
+view+
",showText:"
+showText);
expandTabView.onPressBack();
int
position = getPositon(view);
if
(position >=
0
&& !expandTabView.getTitle(position).equals(showText)) {
expandTabView.setTitle(showText, position);
}
Toast.makeText(MainActivity.
this
, showText, Toast.LENGTH_SHORT).show();
}
private
int
getPositon(View tView) {
Log.d(TAG,
"getPosition"
);
for
(
int
i =
0
; i < mViewArray.size(); i++) {
if
(mViewArray.get(i) == tView) {
return
i;
}
}
return
-
1
;
}
@Override
public
void
onBackPressed() {
if
(!expandTabView.onPressBack()) {
finish();
}
}
}</string></string></view></view>
|
4 ,ExpandTabView
最主要就是如何处理当我们点击这些ToggleButton的时候要弹出或者收起这些PopupWindow。
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
|
package
com.example.view;
import
java.util.ArrayList;
import
com.example.expandtabview.R;
import
android.app.Activity;
import
android.content.Context;
import
android.util.AttributeSet;
import
android.util.Log;
import
android.view.LayoutInflater;
import
android.view.View;
import
android.widget.LinearLayout;
import
android.widget.PopupWindow;
import
android.widget.PopupWindow.OnDismissListener;
import
android.widget.RelativeLayout;
import
android.widget.TextView;
import
android.widget.ToggleButton;
/**
* 菜单控件头部,封装了下拉动画,动态生成头部按钮个数
*
* @author zengjinlong
*/
public
class
ExpandTabView
extends
LinearLayout
implements
OnDismissListener {
private
static
final
String TAG =
"ExpandTabView"
;
private
ToggleButton selectedButton;
private
ArrayList<string> mTextArray =
new
ArrayList<string>();
private
ArrayList<relativelayout> mViewArray =
new
ArrayList<relativelayout>();
private
ArrayList<togglebutton> mToggleButton =
new
ArrayList<togglebutton>();
private
Context mContext;
private
final
int
SMALL =
0
;
private
int
displayWidth;
private
int
displayHeight;
private
PopupWindow popupWindow;
private
int
selectPosition;
public
ExpandTabView(Context context) {
super
(context);
init(context);
}
public
ExpandTabView(Context context, AttributeSet attrs) {
super
(context, attrs);
init(context);
}
/**
* 根据选择的位置设置tabitem显示的值
*/
public
void
setTitle(String valueText,
int
position) {
if
(position < mToggleButton.size()) {
mToggleButton.get(position).setText(valueText);
}
}
public
void
setTitle(String title){
}
/**
* 根据选择的位置获取tabitem显示的值
*/
public
String getTitle(
int
position) {
if
(position < mToggleButton.size() && mToggleButton.get(position).getText() !=
null
) {
return
mToggleButton.get(position).getText().toString();
}
return
""
;
}
/**
* 设置tabitem的个数和初始值
* @param textArray 标题数组
* @param viewArray 控件数组
*/
public
void
setValue(ArrayList<string> textArray, ArrayList<view> viewArray) {
if
(mContext ==
null
) {
return
;
}
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Log.d(TAG,
"setValue"
);
mTextArray = textArray;
for
(
int
i =
0
; i < viewArray.size(); i++) {
final
RelativeLayout r =
new
RelativeLayout(mContext);
int
maxHeight = (
int
) (displayHeight *
0.7
);
RelativeLayout.LayoutParams rl =
new
RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, maxHeight);
rl.leftMargin =
10
;
rl.rightMargin =
10
;
r.addView(viewArray.get(i), rl);
mViewArray.add(r);
r.setTag(SMALL);
ToggleButton tButton = (ToggleButton) inflater.inflate(R.layout.toggle_button,
this
,
false
);
addView(tButton);
View line =
new
TextView(mContext);
line.setBackgroundResource(R.drawable.choosebar_line);
if
(i < viewArray.size() -
1
) {
LinearLayout.LayoutParams lp =
new
LinearLayout.LayoutParams(
2
, LinearLayout.LayoutParams.MATCH_PARENT);
addView(line, lp);
}
mToggleButton.add(tButton);
tButton.setTag(i);
tButton.setText(mTextArray.get(i));
r.setOnClickListener(
new
OnClickListener() {
@Override
public
void
onClick(View v) {
Log.d(
"RelativeLayout"
,
"view:"
+v);
onPressBack();
}
});
r.setBackgroundColor(mContext.getResources().getColor(R.color.popup_main_background));
tButton.setOnClickListener(
new
OnClickListener() {
@Override
public
void
onClick(View view) {
Log.d(
"tButton"
,
"setOnClickListener(l)"
);
// initPopupWindow();
ToggleButton tButton = (ToggleButton) view;
if
(selectedButton !=
null
&& selectedButton != tButton) {
selectedButton.setChecked(
false
);
}
selectedButton = tButton;
selectPosition = (Integer) selectedButton.getTag();
startAnimation();
if
(mOnButtonClickListener !=
null
&& tButton.isChecked()) {
mOnButtonClickListener.onClick(selectPosition);
}
}
});
}
// for..
}
private
void
startAnimation() {
Log.d(TAG,
"startAnimation"
);
if
(popupWindow ==
null
) {
Log.d(TAG,
"startAnimation(),new popupWindow now"
);
popupWindow =
new
PopupWindow(mViewArray.get(selectPosition), displayWidth, displayHeight);
popupWindow.setAnimationStyle(R.style.PopupWindowAnimation);
popupWindow.setFocusable(
false
);
popupWindow.setOutsideTouchable(
true
);
}
Log.d(TAG,
"startAnimation(),selectedButton:"
+selectedButton+
",isChecked:"
+selectedButton.isChecked()+
",popupWindow.isShowing:"
+popupWindow.isShowing());
if
(selectedButton.isChecked()) {
if
(!popupWindow.isShowing()) {
showPopup(selectPosition);
}
else
{
popupWindow.setOnDismissListener(
this
);
popupWindow.dismiss();
hideView();
}
}
else
{
if
(popupWindow.isShowing()) {
popupWindow.dismiss();
hideView();
}
}
}
private
void
showPopup(
int
position) {
View tView = mViewArray.get(selectPosition).getChildAt(
0
);
if
(tView
instanceof
ViewBaseAction) {
ViewBaseAction f = (ViewBaseAction) tView;
f.show();
}
if
(popupWindow.getContentView() != mViewArray.get(position)) {
popupWindow.setContentView(mViewArray.get(position));
}
popupWindow.showAsDropDown(
this
,
0
,
0
);
}
/**
* 如果菜单成展开状态,则让菜单收回去
*/
public
boolean
onPressBack() {
Log.d(TAG,
"onPressBack"
);
if
(popupWindow !=
null
&& popupWindow.isShowing()) {
popupWindow.dismiss();
hideView();
if
(selectedButton !=
null
) {
selectedButton.setChecked(
false
);
}
return
true
;
}
else
{
return
false
;
}
}
private
void
hideView() {
Log.d(TAG,
"hide()"
);
View tView = mViewArray.get(selectPosition).getChildAt(
0
);
if
(tView
instanceof
ViewBaseAction) {
ViewBaseAction f = (ViewBaseAction) tView;
f.hide();
}
}
private
void
init(Context context) {
mContext = context;
displayWidth = ((Activity) mContext).getWindowManager().getDefaultDisplay().getWidth();
displayHeight = ((Activity) mContext).getWindowManager().getDefaultDisplay().getHeight();
setOrientation(LinearLayout.HORIZONTAL);
}
@Override
public
void
onDismiss() {
Log.d(TAG,
"onDismiss,selectPosition:"
+selectPosition);
showPopup(selectPosition);
popupWindow.setOnDismissListener(
null
);
}
private
OnButtonClickListener mOnButtonClickListener;
/**
* 设置tabitem的点击监听事件
*/
public
void
setOnButtonClickListener(OnButtonClickListener l) {
mOnButtonClickListener = l;
}
/**
* 自定义tabitem点击回调接口
*/
public
interface
OnButtonClickListener {
public
void
onClick(
int
selectPosition);
}
}
</view></string></togglebutton></togglebutton></relativelayout></relativelayout></string></string>
|
5,ViewLeft
其中的一个示例,其他两个就不列举了
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
110
|
package
com.example.view;
import
com.example.adapter.TextAdapter;
import
com.example.expandtabview.R;
import
android.content.Context;
import
android.util.AttributeSet;
import
android.view.LayoutInflater;
import
android.view.View;
import
android.widget.ListView;
import
android.widget.RelativeLayout;
import
android.widget.Toast;
public
class
ViewLeft
extends
RelativeLayout
implements
ViewBaseAction{
private
static
final
String TAG =
"ViewLeft"
;
private
ListView mListView;
private
final
String[] items =
new
String[] {
"item1"
,
"item2"
,
"item3"
,
"item4"
,
"item5"
,
"item6"
};
//显示字段
private
final
String[] itemsVaule =
new
String[] {
"1"
,
"2"
,
"3"
,
"4"
,
"5"
,
"6"
};
//隐藏id
private
OnSelectListener mOnSelectListener;
private
TextAdapter adapter;
private
String mDistance;
private
String showText =
"item1"
;
private
Context mContext;
public
String getShowText() {
return
showText;
}
public
ViewLeft(Context context) {
super
(context);
init(context);
}
public
ViewLeft(Context context, AttributeSet attrs,
int
defStyle) {
super
(context, attrs, defStyle);
init(context);
}
public
ViewLeft(Context context, AttributeSet attrs) {
super
(context, attrs);
init(context);
}
private
void
init(Context context) {
mContext = context;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.view_distance,
this
,
true
);
setBackgroundDrawable(getResources().getDrawable(R.drawable.choosearea_bg_mid));
mListView = (ListView) findViewById(R.id.listView);
adapter =
new
TextAdapter(context, items, R.drawable.choose_item_right, R.drawable.choose_eara_item_selector);
adapter.setTextSize(
17
);
if
(mDistance !=
null
) {
for
(
int
i =
0
; i < itemsVaule.length; i++) {
if
(itemsVaule[i].equals(mDistance)) {
adapter.setSelectedPositionNoNotify(i);
showText = items[i];
break
;
}
}
}
mListView.setAdapter(adapter);
adapter.setOnItemClickListener(
new
TextAdapter.OnItemClickListener() {
@Override
public
void
onItemClick(View view,
int
position) {
if
(mOnSelectListener !=
null
) {
showText = items[position];
mOnSelectListener.getValue(itemsVaule[position], items[position]);
}
}
});
}
public
void
setOnSelectListener(OnSelectListener onSelectListener) {
mOnSelectListener = onSelectListener;
}
public
interface
OnSelectListener {
public
void
getValue(String distance, String showText);
}
@Override
public
void
hide() {
}
@Override
public
void
show() {
}
}
|
6,效果图
好,今天就到这里。。希望有用。