Android 使用PopupWindow实现下拉列表

来看效果图:

这里写图片描述

在实现这个效果前,先来了解下PopupWindow的常用方法

构造方法

在实例化PopupWindow窗口时,需要我们自己传入窗口的界面视图和窗口的尺寸
实例化PopupWindow的方法常用以下几种

public PopupWindow(View contentView)
public PopupWindow(int width, int height)
public PopupWindow(View contentView, int width, int height)
public PopupWindow(View contentView, int width, int height, boolean focusable)

在PopupWindow中,并没有像AlertDialog一样是有个默认的布局,所以实例化PopupWindow时我们就必须给它设置一个布局,和指定他的宽高,这三个少一个都不能正常弹出PopupWindow

显示方法

常用的显示方法:

// 相对view控件的位置,位于view控件正下方
public void showAsDropDown(View anchor)
// 相对view控件的位置,可设置偏移值
public void showAsDropDown(View anchor, int xoff, int yoff)
// 相对于整个窗口的位置
public void showAtLocation(View parent, int gravity, int x, int y)

第一个方法showAsDropDown:
指定需要在哪个View控件下显示窗口就好,默认popupWindow窗口的左上角对齐view控件的左下角。
第二个方法showAsDropDown:
xoff和yoff两个值分别设置popup窗口的横向和竖直方向上的偏移值
xoff为负数时窗口向左偏移,为正数时窗口向右偏移
同理yoff为负数时窗口向上偏移,为正数时向下偏移
第三个方法showAtLocation:
parent参数只要传进当前窗口上有的任意一个View控件就好,不要被parent这个单词的字面意思给搞混了,并不是需要传ViewGroup对象。
gravity参数需要我们传递一个Gravity值,可以指定一个或者多个属性,如:Gravity.RIGHT|Gravity.BOTTOM
最后两个参数x、y为两个偏移值,和showAsDropDown偏移值的处理方式一致

常用方法

// popup窗口显示状态,显示则返回true
public boolean isShowing()

// 设置popup窗口是否具有获取焦点的能力
public void setFocusable(boolean focusable)

// 设置是否响应touch点击事件
public void setTouchable(boolean touchable)

// 设置点击窗口外边是否可让popup窗口消失
public void setOutsideTouchable(boolean touchable)

// 设置popup窗口背景图片,这个方法挺重要的,查看源码可以发现
// 加上它后,setOutsideTouchable()方法才能生效
// 加上它后,按手机返回键关闭popup窗口的功能才会生效
public void setBackgroundDrawable(Drawable background)

// 设置popup窗口关闭事件的监听
public void setOnDismissListener(OnDismissListener onDismissListener)

// 关闭popup窗口
public void dismiss()

实现上图中的效果
这里用的是一个TextView控件,也可以换成EditText控件,一样的效果

布局文件

<?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:padding="10dp"
    android:background="#737373"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_select_input"
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:background="@drawable/bg_filter_down"
        android:drawableRight="@drawable/ic_arrows_down"
        android:gravity="center"
        android:padding="10dp"
        android:textSize="12sp" />

</LinearLayout>

TextView控件的背景图片bg_filter_down.xml,和popupWindw窗口的布局文件bg_corner.xml是一样的

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <!--设置背景颜色-->
    <solid android:color="#ffffff" />
    <!-- 设置圆角角度 -->
    <corners android:radius="5dp" />
</shape>

那个小箭头图片ic_arrows_down可以自己找个图片设置上去,也可以不加。

主要代码

/**
 * 主界面
 * Created by zhuwentao on 2016-08-10.
 */
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    /** TextView选择框 */
    private TextView mSelectTv;

    /** popup窗口里的ListView */
    private ListView mTypeLv;

    /** popup窗口 */
    private PopupWindow typeSelectPopup;

    /** 模拟的假数据 */
    private List<String> testData;

    /** 数据适配器 */
    private ArrayAdapter<String> testDataAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initUI();
        initListener();
    }

    /**
     * 初始化UI
     */
    private void initUI() {
        mSelectTv = (TextView) findViewById(R.id.tv_select_input);
    }

    /**
     * 初始化监听
     */
    private void initListener() {
        mSelectTv.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_select_input:
                // 点击控件后显示popup窗口
                initSelectPopup();
                // 使用isShowing()检查popup窗口是否在显示状态
                if (typeSelectPopup != null && !typeSelectPopup.isShowing()) {
                    typeSelectPopup.showAsDropDown(mSelectTv, 0, 10);
                }
                break;
        }
    }

    /**
     * 初始化popup窗口
     */
    private void initSelectPopup() {
        mTypeLv = new ListView(this);
        TestData();
        // 设置适配器
        testDataAdapter = new ArrayAdapter<String>(this, R.layout.popup_text_item, testData);
        mTypeLv.setAdapter(testDataAdapter);

        // 设置ListView点击事件监听
        mTypeLv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // 在这里获取item数据
                String value = testData.get(position);
                // 把选择的数据展示对应的TextView上
                mSelectTv.setText(value);
                // 选择完后关闭popup窗口
                typeSelectPopup.dismiss();
            }
        });
        typeSelectPopup = new PopupWindow(mTypeLv, mSelectTv.getWidth(), ActionBar.LayoutParams.WRAP_CONTENT, true);
        // 取得popup窗口的背景图片
        Drawable drawable = ContextCompat.getDrawable(this, R.drawable.bg_corner);
        typeSelectPopup.setBackgroundDrawable(drawable);
        typeSelectPopup.setFocusable(true);
        typeSelectPopup.setOutsideTouchable(true);
        typeSelectPopup.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                // 关闭popup窗口
                typeSelectPopup.dismiss();
            }
        });
    }

    /**
     * 模拟假数据
     */
    private void TestData() {
        testData = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            String str = new String("数据" + i);
            testData.add(str);
        }
    }
}

ListView控件中item的布局popup_text_item.xml文件

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="35sp"
    android:gravity="center"/>
  • 10
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值