自定义组合控件:下拉选择框

Spinner 自定义组合控件之下拉选择框

自定义组合控件:下拉选择框_第1张图片

项目概述

下拉选择框主要是通过在EditText 下用PopupWindow 动态显示ListView 控件来实现的。下拉选择框可以方便用户的输入效率,以此提升用户体验。点击EditText 控件右侧的倒三角形弹出如下可选项,点击
可选项,那么内容将自动填充到EditText 控件中,如图1-6 所示。另外,点击下拉框中条目右边的红色叉号可以删除当前的条目,效果图如图1-7 所示。

下拉选择框UI

下拉框的布局文件为activity_main.xml,这里的布局仅仅是在EditText 的右侧添加了一个倒三角图标。具体的代码如文件【1-6】所示:【文件1-6】Res/layout/activity_main.xml


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

    <RelativeLayout
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="150dp">

        <EditText
            android:id="@+id/et_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        EditText>

        <ImageView
            android:id="@+id/iv_drop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:src="@drawable/down_arrow"/>
    RelativeLayout>
RelativeLayout>

点击倒三角弹出的ListView 条目布局文件为list_item.xml,具体代码如文件【1-7】所示:【文件1-7】res/layout/list_item


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:descendantFocusability="blocksDescendants"
              android:gravity="center_vertical"
              android:orientation="horizontal"
              android:padding="5dp">

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/user"/>

    <TextView
        android:id="@+id/tv_content"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"/>

    <ImageView
        android:id="@+id/iv_delete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/delete"/>
LinearLayout>

下拉选择框业务逻辑实现

下拉选择框MainActivity 界面,具体代码如文件【1-8】所示:【文件1-8】com/itheima/dropdown/MainActivity

package com.github.spinner;

import android.app.Activity;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;

import java.util.ArrayList;

/**
 * ============================================================
 * Copyright:${TODO}有限公司版权所有 (c) 2017
 * Author:   AllenIverson
 * Email:    [email protected]
 * GitHub:   https://github.com/JackChen1999
 * 博客:     http://blog.csdn.net/axi295309066
 * 微博:     AndroidDeveloper
 * 

* Project_Name:Spinner * Package_Name:com.github.spinner * Version:1.0 * time:2016/2/28 17:18 * des :自定义组合控件,Spinner下拉选择框控件 * gitVersion:$Rev$ * updateAuthor:$Author$ * updateDate:$Date$ * updateDes:${TODO} * ============================================================ */ public class MainActivity extends Activity { private ListView lvList; private EditText etContent; private ArrayList mList; private PopupWindow mPopup; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ImageView ivDrop = (ImageView) findViewById(R.id.iv_drop); etContent = (EditText) findViewById(R.id.et_content); ivDrop.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showDropDown(); } }); initView(); } //初始化listview 作为pw 的视图 private void initView() { lvList = new ListView(this); // 初始化listview 数据 mList = new ArrayList(); for (int i = 0; i < 200; i++) { mList.add("aaabbbccc" + i); } lvList.setAdapter(new MyAdapter()); lvList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { etContent.setText(mList.get(position)); mPopup.dismiss(); } }); } // 下拉框的显示 protected void showDropDown() { if (mPopup == null) { /** * 第一个参数lv:PopupWindow 显示的内容视图 * 第二个参数et_number.getWidth():PopupWindow 的宽度 * 第三个参数200:PopupWindow 的高度 */ mPopup = new PopupWindow(lvList, etContent.getWidth(), 200, true); mPopup.setFocusable(true); //设置pw 可以响应焦点 mPopup.setOutsideTouchable(true); //允许点击pw 以外的地方,让pw 隐藏 //要让setOutsideTouchable(true)有效,必须给PopupWindow 设置背景 mPopup.setBackgroundDrawable(new BitmapDrawable()); } //设置PopupWindow 显示的位置 mPopup.showAsDropDown(etContent); } //ListView 的适配器 class MyAdapter extends BaseAdapter { @Override public int getCount() { return mList.size(); } @Override public String getItem(int position) { return mList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = View.inflate(getApplicationContext(), R.layout.list_item, null); holder = new ViewHolder(); holder.tvContent = (TextView) convertView .findViewById(R.id.tv_content); holder.ivDelete = (ImageView) convertView .findViewById(R.id.iv_delete); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.tvContent.setText(getItem(position)); holder.ivDelete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mList.remove(position); MyAdapter.this.notifyDataSetChanged(); } }); return convertView; } } static class ViewHolder { public TextView tvContent; public ImageView ivDelete; } }

知识点总结

1.PopupWindow 获取焦点能力较差,要让它内容获得焦点,需要通过setFocusable(true)方法来获得焦点,见MainActivity.java 第47 行。

2.PopupWindow 可以通过setOutsideTouchable(true)方法来实现点击除PopupWindow 以外的地方,让PopupWindow 销毁,但必须同时设置背景才有效,见MainActivity.java 第48~50 行。

3.当listview 无法响应onItemClick 点击事件时,有可能是listview 的条目布局中存在抢占焦点能力强的button、imagebutton 等控件,可以在布局中设置android:descendantFocusability=”blocksDescendants”属性,以按
块区域的形式响应点击事件,来解决bug,见listview_item.xml 第7 行。

代码:https://github.com/JackChen1999/Spinner

你可能感兴趣的:(Android自定义控件,自定义控件)