您的位置:首页 > Web前端 > CSS

安卓下拉列表样式筛选组件(仿美团,popwindow实现方式)

2018-02-11 11:23 1276 查看
需求:做一个查询页面,要求点击item的时候能对底下数据进行筛选





先看效果图:(顺便送大家一个视频转gif的在线网站https://cloudconvert.com/)



这节先不说关于toolbar的处理,只说下拉菜单popwindow的封装。

1、首先需要一个包含listview的页面pup_selectlist.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="fill_parent"
android:orientation="vertical"
android:id="@+id/popupwindow"
>

<FrameLayout
android:background="#ffffff"
android:id="@+id/employeesquery_popupwindow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>

<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#efefef"
android:dividerHeight="0.5dp"
>
</ListView>
</FrameLayout>

<!--遮罩,必须有!-->
<LinearLayout
android:id="@+id/dissmiss"
android:layout_width="match_parent"
android:layout_height="1200dp"
android:background="#50000000"
android:orientation="horizontal"></LinearLayout>

</LinearLayout>还需要一个ListView的item页面,item_listview.xml,由于我做的只是一个很简单的列表,所以就包含name和code(code不要也行,可以用tag替代)两部分,name是list展示时所用,code的用来当作前后台交互的查询条件。注:在本例子中,id='code'的TextView并没有用到。
<?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:orientation="vertical"
android:id="@+id/employeesquery"
android:background="#ffffff">

<TextView
android:gravity="center_vertical"
android:layout_marginLeft="20dp"
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="40dp"
></TextView>

<TextView
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/code"
/>

</LinearLayout>

2、定义一个listview的适配器抽象类(后面会用到)

abstract class Madapter extends BaseAdapter {
public abstract List<?> getItems(); //返回ListView的数据集
public abstract void setSelectColor(int color); //修改选中后item的颜色
public abstract void setSelectedPosition(int selectedPosition); //设置选中项
public abstract String getShowKey(int position , String key);//获取选中值,必须有这个方法。
}在建立自己的适配器时要实现这个接口,当然,这个接口除了本人写的这几个以外,还可以继续添加其他方法。
下面贴上例子中我所写的适配器类
package com.imp.dropdownmenu;

import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.List;

/**
* Created by import 2017/12/28.
*/

public class SearchAdapter extends Madapter {

private Context context;
private int selectColor = Color.GRAY; //被选中后item的颜色,为了方便,所以在添加set方法
private LayoutInflater inflater;
private List<Dic> items;
private int selectedPosition = -1;

public List<Dic> getItems() {
return items;
}

@Override
public String getShowKey(int position , String key){
if (key.equals("name")){
return items.get(position).getName();
}else {
return items.get(position).getCode();
}

}

public void setSelectedPosition(int selectedPosition) {
this.selectedPosition = selectedPosition;
}

public SearchAdapter(Context context){
this.context = context;
inflater = LayoutInflater.from(context);
}

public void setItems(List<Dic> items) {
this.items = items;
}

@Override
public int getCount() {
// TODO Auto-generated method stub
return items.size();
}

@Override
public Object getItem(int i) {
return null;
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub

SearchAdapter.ViewHolder holder;
if(convertView == null){

holder = new SearchAdapter.ViewHolder();
convertView = (View)inflater.inflate(R.layout.item_listview, parent , false);
holder.name =(TextView) convertView.findViewById(R.id.name);
holder.code = (TextView)convertView.findViewById(R.id.code);
holder.employeesquery = (LinearLayout)convertView.findViewById(R.id.employeesquery);
convertView.setTag(holder);
}else{
holder = (SearchAdapter.ViewHolder)convertView.getTag();
}

/**
* 该项被选中时改变背景色
*/
if(selectedPosition == position){
holder.employeesquery.setBackgroundColor(selectColor);
}else{
holder.employeesquery.setBackgroundColor(Color.TRANSPARENT);
}
holder.name.setText(items.get(position).getName());
holder.code.setText(items.get(position).getCode()); //也可在ITTM里去掉这一项,写在Tag里

return convertView;
}

class ViewHolder{
TextView name;
TextView code;
LinearLayout employeesquery;
}

@Override
public void setSelectColor(int selectColor) {
this.selectColor = selectColor;
}
}

3、开始编写通用下拉选择列表(DropDownMenu.java)

先上源码
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;

/**
* Created by import on 2018/1/31.
*/

fd88
public class DropDownMenu {

private final OnListCkickListence mListener; //item单击事件接口
private static DropDownMenu instance;
private static Context sContext;
private PopupWindow popupWindow;
private View dissmiss; //点击展开后的半透明挡板
private Boolean showShadow = true; //是否需要半透明挡板
private String showName; //适配器中所需要显示内容的名字,仅在modifyText中有值时使用
private String selectName; //搜索用的key
private int itemNum = 6;
private int indexColor; //设置外部所点击的View的颜色
private static int viewColor; //外部所点击的View本来的颜色

public static DropDownMenu getInstance(Context context, OnListCkickListence mListener) {
instance = new DropDownMenu(context,mListener);
return instance;
}

private DropDownMenu(Context context,OnListCkickListence mListener) {
sContext = context;
this.mListener = mListener;
}

/***
*
* @param screenWidth 屏幕宽度
* @param screenHeight 屏幕高度
* @param searchAdapter 设配器
* @param item listView的item
* @param layout 含有ListView的布局文件
* @param dropview 菜单弹出后在哪个View下
* @param modifyText 点击后需要修改的TextView
* @param type 点击了哪一个标签
* @param menuSize 是否需要限制弹出菜单大小,若需要,则传true,默认为6个item高,通过setItemNum方法进行设定
*/
public void showSelectList(int screenWidth, final int screenHeight, final Madapter searchAdapter, View layout,View item, final View dropview, final TextView modifyText, final String type, final boolean menuSize) {

ListView listview = (ListView) layout.findViewById(R.id.listview);

viewColor = dropview.getDrawingCacheBackgroundColor();

if (menuSize && searchAdapter!=null && searchAdapter.getCount()!=0) {
ViewGroup.LayoutParams para = listview.getLayoutParams();
int width = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
int height = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
item.measure(width, height);
item.getMeasuredWidth(); // 获取宽度
item.getMeasuredHeight(); // 获取高度
para.height = itemNum * (item.getMeasuredHeight()) + 14;
listview.setLayoutParams(para);
}else {
listview.setLayoutParams( new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT));
}

if (showShadow) {
dissmiss = (View) layout.findViewById(R.id.dissmiss);
if (dissmiss != null) {
dissmiss.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
popupWindow.dismiss();
dropview.setBackgroundColor(viewColor);
}
});
}
} else {
dissmiss = (View) layout.findViewById(R.id.dissmiss);
dissmiss.setVisibility(View.GONE);
}

listview.setAdapter(searchAdapter);

popupWindow = new PopupWindow(layout, screenWidth,
FrameLayout.LayoutParams.WRAP_CONTENT, true);
/**
* 有了mPopupWindow.setBackgroundDrawable(new BitmapDrawable());
* 这句可以使点击popupwindow以外的区域时popupwindow自动消失 但这句必须放在showAsDropDown之前
*/
popupWindow.setBackgroundDrawable(new BitmapDrawable());
/**
* popupwindow的位置,第一个参数表示位于哪个控件之下 第二个参数表示向左右方向的偏移量,正数表示向左偏移,负数表示向右偏移
* 第三个参数表示向上下方向的偏移量,正数表示向下偏移,负数表示向上偏移
*
*/

if (indexColor != 0){
dropview.setBackgroundColor(indexColor);
}else {
dropview.setBackgroundColor(viewColor);
}
popupWindow.showAsDropDown(dropview, -5, 3);// 在控件下方显示popwindow
popupWindow.setFocusable(true);
popupWindow.setOutsideTouchable(true);
popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
dropview.setBackgroundColor(viewColor);
}
});
popupWindow.update();

listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> listView, View view, int position, long id) {
searchAdapter.setSelectedPosition(position);
searchAdapter.notifyDataSetInvalidated();
if(modifyText != null){
modifyText.setText(searchAdapter.getShowKey(position,showName));
}
mListener.search(searchAdapter.getShowKey(position,selectName), type);
mListener.changeSelectPanel(searchAdapter,dropview);
popupWindow.dismiss();
dropview.setBackgroundColor(viewColor);
}
}
);
}

public void setShowShadow(Boolean showShadow) {
this.showShadow = showShadow;
}

public void setItemNum(int itemNum) {
this.itemNum = itemNum;
}

public void setShowName(String showName) {
this.showName = showName;
}

public void setSelectName(String selectName) {
this.selectName = selectName;
}

public void setIndexColor(int color){
indexColor = sContext.getResources().getColor(color);
}

public interface OnListCkickListence {
void search(String code, String type); //根据选择的数据进行查询
void changeSelectPanel(Madapter madapter,View view); //修改选中后item的颜色,以及点击后对View进行一些修改
}
}

核心方法是showSelectList,定义接口为了方便在外部调用时根据不用的需求写不同的实现。

4、实例调用

4.1、初始化dropDownMenu
dropDownMenu = DropDownMenu.getInstance(this, new DropDownMenu.OnListCkickListence() {
@Override
public void search(String code, String type) {
System.out.println("======"+code+"========="+type);
    //写一些你自己的需求和方法,比如:点击某个item我们可以得到你点的是哪个列表和item的code,根据code查询后台并刷新页面
 }

@Override
public void changeSelectPanel(Madapter madapter, View view) {
    //提供了对适配器方法调用以及返回第一次点击的view的回调(本例中为:性别、民族、国家...)
}
});
dropDownMenu.setIndexColor(R.color.colorAccent);//用来设置点击(性别、民族、国家...)后的颜色
dropDownMenu.setShowShadow(true);//要不要在popwindow展示的时候背景变为半透明
dropDownMenu.setShowName("name");//listView适配器中返回数据的名字(比如:我在适配器中传入List<Dic> list,在这个list中有n个Dic类,我要在性别、民族...View中显示的值在Dic这个类中的名字’)
dropDownMenu.setSelectName("code");//listView适配器中返回数据的名字(返回用来查询的)
4.2、调用dropDownMenu先定义好需要调用的layout布局
@Overrid
public void onClick(View view) {
switch (view.getId()) {
case R.id.sex:
dropDownMenu.showSelectList(ScreenUtils.getScreenWidth(this),
ScreenUtils.getScreenHeight(this), sexAdapter,
listView, listItem,sex, sex_text, "cyry.xbdm", false);
break;
case R.id.nation:
dropDownMenu.showSelectList(ScreenUtils.getScreenWidth(this),
ScreenUtils.getScreenHeight(this), nationAdapter,
listView, listItem,nation,nation_text,"cyry.mzdm",true);
break;
case R.id.country:
dropDownMenu.showSelectList(ScreenUtils.getScreenWidth(this),
ScreenUtils.getScreenHeight(this), countryAdapter,
listView, listItem,country,country_text,"cyry.gjdm",true);

break;
case R.id.culture:
dropDownMenu.showSelectList(ScreenUtils.getScreenWidth(this),
ScreenUtils.getScreenHeight(this), cultureAdapter,
listView, listItem,culture,culture_text,"cyry.whcd",true);
break;
default:
break;
}
}

5、小结

由于这个例子为前期测试例子,所以命名不是很规范,各位看官有啥不明白的可以再下面留言,共同进步。

demo传送门:http://download.csdn.net/download/w1085541827/10249330

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: