转载此文章请注明出处:点击打开链接   http://blog.csdn.net/qq_32059827/article/details/52313516

首先,很荣幸此专栏能被CSDN推荐到主页。荣幸的同时,也激励自己会把这个专栏一直更新下去。

进入今天的主题:

我们在qq登录的时候,会有一个下拉的按钮,来查看历史登录账号。这一篇就模拟这个效果,自定义组合框实现之。

这里面会用到popupwindow,对于popupwindow的原始用法欢迎看之前的一篇文章,对弹出窗体做过介绍:点击打开链接

今天不再使用那种方式来定义了,使用其他的api,实现方式更简单。同时,有一些”小技巧”在里面。

定义主布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:gravity="center_horizontal"
android:layout_height="match_parent"> <EditText
android:id="@+id/et_number"
android:layout_width="200dip"
android:layout_height="wrap_content" /> <ImageButton
android:id="@+id/ib_down_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/et_number"
android:layout_alignRight="@id/et_number"
android:layout_alignTop="@id/et_number"
android:layout_marginRight="5dip"
android:background="@drawable/down_arrow" /> </RelativeLayout>

小技巧:图片的点击事件ImageButton能更好的胜任这个工作,但是使用它的时候,需要把背景去掉(ImageButton默认是携带一个背景的)。设置背景无的方式有两种:1、加入两个属性: android:background="@android:color/transparent" 作用是让背景为透明状态              android:src="@drawable/icon_home"   ;  2直接设置android:background="@drawable/down_arrow" 。一般对ImageButton图片使用第二种。

弹出窗体,窗体需要一个布局。显然,要实现模拟qq下拉需要用listview显示,它的布局如下:

<?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="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:descendantFocusability="blocksDescendants"
android:padding="5dip" >
<!-- android:descendantFocusability="blocksDescendants"表示让后辈只在自己那一块位置响应事件,不要抢占父组件本身的事件 -->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/user" /> <TextView
android:id="@+id/tv_listview_item_number"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_marginRight="5dip"
android:layout_weight="1"
android:gravity="center"
android:text="默认的号码"
android:textSize="18sp" /> <ImageButton
android:id="@+id/ib_listview_item_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/delete" /> </LinearLayout>

小技巧:注意在根布局里面加入的android:descendantFocusability="blocksDescendants"。如果去掉的话,当在点击listview的item的时候,事件会被他上边的ImageButton抢占走。加入它的目的就是:让LiearLayout的子组件只在自己那一块位置响应事件,不要抢占父组件本身的事件。

接下来,就是业务逻辑,如下:

package com.itydl.popupwindowdemo;

import java.util.ArrayList;
import java.util.List; import android.app.Activity;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView; public class MainActivity extends Activity implements OnClickListener, OnItemClickListener { private List<String> numberList; // 号码集合
private ListView mListView;
private EditText etNumber;
private PopupWindow popupWindow;
private NumberAdapter mAdapter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); etNumber = (EditText) findViewById(R.id.et_number);
ImageButton ibArrow = (ImageButton) findViewById(R.id.ib_down_arrow); ibArrow.setOnClickListener(this);
} @Override
public void onClick(View v) {
showPopupWindow();
} /**
* 弹出一个下拉窗体
*/
private void showPopupWindow() {
initListView(); // 创建PopupWindow对象,指定内容为ListView,宽度为输入框的宽度,高度为200,当前窗体可以获取焦点
popupWindow = new PopupWindow(mListView, etNumber.getWidth() - 8, 200, true);   /*************************************** 这里需要添加两行代码 ***************************************************************/ /**
* View anchor, 相对父组件(这里的父组件是一个编辑框)
* int xoff, x偏移量
* int yoff,y偏移量
* 说明:弹出窗体右上角与父组件左下角作为相对位置。
*/
popupWindow.showAsDropDown(etNumber, 4, -4);//表示mListView的窗体,相对父组件左移4个像素,上移4个像素
} /**
* 初始化ListView
*/
private void initListView() {
mListView = new ListView(this);
/****/
mListView.setOnItemClickListener(this); numberList = new ArrayList<String>();
for (int i = 0; i < 30; i++) {
//数据源添加数据
numberList.add("10000060" + i);
} mAdapter = new NumberAdapter();
mListView.setAdapter(mAdapter);
} class NumberAdapter extends BaseAdapter { @Override
public int getCount() {
return numberList.size();
} @Override
public View getView(final int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = View.inflate(MainActivity.this, R.layout.listview_item, null);
} TextView tvNumber = (TextView) convertView.findViewById(R.id.tv_listview_item_number);
ImageButton ibDelete = (ImageButton) convertView.findViewById(R.id.ib_listview_item_delete);
tvNumber.setText(numberList.get(position)); ibDelete.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
numberList.remove(position);//移除数据源位置
mAdapter.notifyDataSetChanged();//通知listview刷新
}
}); return convertView;
} @Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
} @Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
} } @Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// System.out.println("onItemClick");
//获取点击那项的数据
String number = numberList.get(position);
etNumber.setText(number);
popupWindow.dismiss(); //关闭窗体
}
}

可以运行程序看看效果了:

基本实现了需求,但是最后还有几个小技巧要说一下:

1、您会发现等弹出窗体后,没办法关闭窗体,按返回键都关闭不掉,这个时候就需要设置两行代码解决这个问题。需要在哪里加入我已经在代码中标注出来了,在那个地方加入两行代码:

popupWindow.setOutsideTouchable(true);//popupWindow可以接收其它位置的点击事件触发

        popupWindow.setBackgroundDrawable(new BitmapDrawable());/

2、如果想干掉listview旁边的下拉滚动条,只需要加入下边一行代码即可:

mListView.setVerticalScrollBarEnabled(false);

到此,小demo完毕了。

欢迎关注本博客点击打开链接  http://blog.csdn.net/qq_32059827,每天花上5分钟,阅读一篇有趣的安卓小文哦。

Android简易实战教程--第二十二话《自定义组合控件模拟qq登录下拉框和其中的一些”小技巧”》的更多相关文章

  1. 自定义SWT控件四之其它下拉框

    4.其它下拉框 4.1 添加联动二级多选择框(有添加按钮和删除按钮) package com.view.control.select; import java.util.ArrayList; impo ...

  2. Android简易实战教程--第二十九话《创建图片副本》

    承接第二十八话加载大图片,本篇介绍如何创建一个图片的副本. 安卓中加载的原图是无法对其修改的,因为默认权限是只读的.但是通过创建副本,就可以对其做一些修改,绘制等了. 首先创建一个简单的布局.一个放原 ...

  3. Android简易实战教程--第二十六话《网络图片查看器在本地缓存》

    本篇接第二十五话  点击打开链接   http://blog.csdn.net/qq_32059827/article/details/52389856 上一篇已经把王略中的图片获取到了.生活中有这么 ...

  4. Android简易实战教程--第二十话《通过广播接收者,对拨打电话外加ip号》

    没睡着觉,起来更篇文章吧哈哈!首先祝贺李宗伟击败我丹,虽然我是支持我丹的,但是他也不容易哈哈,值得尊敬的人!切入正题:这一篇来介绍个自定义广播接收者. 通常我们在外拨电话的时候,一般为使用网络电话.如 ...

  5. Android简易实战教程--第二十八话《加载大图片》

    Android系统以ARGB表示每个像素,所以每个像素占用4个字节,很容易内存溢出.假设手机内存比较小,而要去加载一张像素很高的图片的时候,就会因为内存不足导致崩溃.这种异常是无法捕获的 内存不足并不 ...

  6. Android简易实战教程--第二十五话《网络图片查看器》

    访问网络已经有了很成熟的框架.这一篇只是介绍一下HttpURLConnection的简单用法,以及里面的"注意点".这一篇可以复习或者学习HttpURLConnection.han ...

  7. Android简易实战教程--第二十四话《画画板》

    今天完成一个画画板. 首先来个布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android ...

  8. Android简易实战教程--第二十一话《内容观察者监听数据库变化》

    当数据库的数据发生改变,我们又想知道具体改变的情况时,就需要对数据库的变化情况做一个监控.这个任务,就由内容观察者来完成.下面这个案例,为短信数据库注册内容观察者,来监控短信的变化情况,当短信数据库发 ...

  9. Android简易实战教程--第十二话《代码获取手机总运行内存的大小》

    手机RAM存储,类似于电脑的内存.这一篇,对通过代码获取手机总内存大小做详细介绍. 首先,定义一个engine类,这个类功能就是获取进程信息,包括运行的程序个数,系统总内存,系统剩余总内存.本篇先完成 ...

随机推荐

  1. [NOI 2009]变换序列

    Description 题库链接 对于 \(N\) 个整数 \(0, 1, \cdots, N-1\) ,一个变换序列 \(T\) 可以将 \(i\) 变成 \(T_i\) ,其中 \(T_i \in ...

  2. ●BZOJ 4310 跳蚤

    ●赘述题目 给出一个字符串,要求分成k个子串,然后求出每个子串的字典序最大的子串(我称它为子子串),要使这k个子子串中的字典序最大的那个串(即魔力串)最小.输出该魔力串. (本题个人感觉很好,比较综合 ...

  3. [bzoj1558][JSOI2009]等差数列

    题目:给定n个数,m个操作,每次给一段区间加一个等差数列或者询问一段区间至少要用多少个等差数列来表示.$n,m\leqslant 10^{5}$ 题解:老套路,维护差分数组,修改操作变成了两个单点加和 ...

  4. bzoj4767两双手 容斥+组合

    4767: 两双手 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 684  Solved: 208[Submit][Status][Discuss] ...

  5. PHP 中 config.m4 的探索

    PHP 中 config.m4 的探索 最近在看php扩展相关的东西,虽然来来回回编辑了好多次config.m4,并且也在技术社区看到了 config.m4是什么?什么作用? 类的问题,但是还是觉得有 ...

  6. 如何避免 async/await 地狱

    简评:async/await 写着很爽,不过要注意这些问题. async/await 让我们摆脱了回调地狱,但是这又引入了 async/await 地狱的问题. 什么是 async/await 地狱 ...

  7. Mysql锁机制--概念、分类及基础命令

    Mysql 系列文章主页 =============== 1 概念 在 Java 程序中,当多线程并发访问某个资源的时候,如果有非线程安全的操作,那么需要通过加锁来保护之.同理,在 Mysql 中,如 ...

  8. 利用生产者消费者模型和MQ模型写一个自己的日志系统-并发设计里一定会用到的手段

    一:前言 写这个程序主要是用来理解生产者消费者模型,以及通过这个Demo来理解Redis的单线程取原子任务是怎么实现的和巩固一下并发相关的知识:这个虽然是个Demo,但是只要稍加改下Appender部 ...

  9. PyCharm 2018.1破解过程

    一.下载 首先从官网下载 官网,如果开了酸酸乳的话无法下载,官网会自动断开连接.所以下载时请关闭酸酸乳 二.安装 选择安装路径 选择64位,创建关联.py文件 安装完后运行Pycharm 选择不导入开 ...

  10. IDEA中Git的使用

    工作中多人使用版本控制软件协作开发,常见的应用场景归纳如下: 假设小组中有两个人,组长小张,组员小袁 场景一:小张创建项目并提交到远程Git仓库 场景二:小袁从远程Git仓库上获取项目源码 场景三:小 ...