1、需求:点击下拉按钮显示一个手机号码的选择列表;
2、思路:使用PopupWindow和ListView来实现这个功能
PopupWindow可以显示在固定布局的某个位置的功能,正好满足这个需求。
3、代码
在自定义PopupWindow类添加一个列表:
布局代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/phone_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@null"
android:dividerHeight="0dp"
android:background="@drawable/ahdi_phone_popup_bg"/>
</LinearLayout>
自定义PopupWindow类:
public class PhoneListPopUpWindow extends PopupWindow {
private static final String TAG = "PhoneListPopUpWindow";
private View contentView;
private ListView phoneListView;
private ArrayList<String> list = new ArrayList<>();
private PhoneNumberListAdapter phoneNumberListAdapter;
private Context context;
private AdapterView.OnItemClickListener onItemClickListener = null;
public PhoneListPopUpWindow(Context context) {
this.context = context;
contentView = LayoutInflater.from(context).inflate(R.layout.ahdi_layout_phone_popup, null, false);
setContentView(contentView);
setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
setOutsideTouchable(false);
setTouchable(true);
initView();
}
private void initView(){
phoneListView = contentView.findViewById(R.id.phone_list);
phoneNumberListAdapter = new PhoneNumberListAdapter(context, list);
phoneListView.setAdapter(phoneNumberListAdapter);
phoneListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (onItemClickListener != null){
onItemClickListener.onItemClick(parent, view, position, id);
}
}
});
}
/**
* 监听列表的item点击
* @param onItemClickListener
*/
public void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
/**
* 更新数据
* @param data
*/
public void setData(List<String> data){
list.clear();
for (int i = 0; i <data.size(); i++) {
list.add(data.get(i));
}
phoneNumberListAdapter.notifyDataSetChanged();
}
/**
* 显示在特定布局的底部
* @param parent
*/
public void showAtLocation(View parent){
int[] location = new int[2];
parent.getLocationOnScreen(location);
setWidth(parent.getWidth());
setHeight(getPopupWindowHeight(parent, location));
showAtLocation(parent, Gravity.NO_GRAVITY, location[0], location[1] + parent.getHeight());
}
/**
* 计算popup的显示高度
* @param parent
* @param location
* @return
*/
public int getPopupWindowHeight(View parent, int[] location) {
try{
//屏幕高度减去控件的位置,剩下的就是popup可以展示的最大高度
int deviceHeight = context.getResources().getDisplayMetrics().heightPixels;
int availableHeight = deviceHeight - location[1] - parent.getHeight();
//计算listview item的高度(UI说最大展示5个item)
View listItem = phoneNumberListAdapter.getView(0, null, phoneListView);
listItem.measure(0, 0);
int measuredHeight = listItem.getMeasuredHeight();
Log.d(TAG, "可用高度 = " + availableHeight + " , itemHeight = " + measuredHeight);
//判断列表的代销是否大于5(UI说最大展示5个item)
int size = Math.min(list.size(), 5);
return Math.min(availableHeight, measuredHeight * size);
}catch (Exception e){
e.printStackTrace();
Log.d(TAG, "计算popup的显示高度时报错误:" + e.getMessage());
}
return 0;
}
}
showAtLocation(View parent) 传入一个要定锚点的view确定popupWindow要显示的位置。
setData(List<String> data)传入要显示的手机号码列表
setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener)传入一个监听器,监听点击的列表item.
getPopupWindowHeight(View parent, int[] location)根据锚点view的位置距离手机屏幕底部的距离和实际需求要显示的条目的高度判断popupWindow要显示的高度。
OK,要的功能就这些,更多详情看github上的代码