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


    转载此文章请注明出处:点击打开链接   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分钟,阅读一篇有趣的安卓小文哦。


  • 相关阅读:
    Hive on Spark
    Mongodb添加副本及修改优先级
    RabbitMQ与Spring集成
    最简单的图文教程,几步完成Git的公私钥配置
    Idea Ant 打开发包
    Spring Web 项目Junit测试报错问题
    阿里云maven仓库地址,速度提升100倍
    Spring boot 学习
    JAVA开发常用工具包
    从无到有搭建SSM框架
  • 原文地址:https://www.cnblogs.com/wanghang/p/6299607.html
Copyright © 2020-2023  润新知