类似QQ登录账号下拉选择框的一种实现

转载请注明出处:http://blog.csdn.net/coder_jone/article/details/39031677

  在很多需要用户登录的应用中为了减少切换账号登录成本,往往会在本地客户端记住用户最近登录的账号信息,当用户需要切换账号时用下拉列表的方式展示最近的登录的一定数量的账户信息供用户选择,典型的例子有QQ、微信等等。那么要如何实现这一功能呢?



      这里我们主要来介绍一种下拉列表的实现,显然Android提供的API的下拉控件不能满足我们的需求。在这里我们通过一个PopupWindow加ListView来实现。

      首先我们来编写一个简单的供用户输入的界面布局:

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

    <RelativeLayout
        android:id="@+id/input_layout"
        android:layout_width="match_parent"
        android:layout_height="41dip"
        android:layout_marginLeft="13dip"
        android:layout_marginRight="13dip"
        android:layout_marginTop="13dp"
        android:background="@drawable/bg_input_middle_normal" >

        <TextView
            android:id="@+id/input_tip"
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:layout_marginLeft="10dip"
            android:layout_marginRight="10dip"
            android:gravity="center_vertical"
            android:text="账号"
            android:textColor="#7c7f89"
            android:textSize="14sp" />

        <EditText
            android:id="@+id/input_et"
            android:layout_width="match_parent"
            android:layout_height="fill_parent"
            android:layout_toLeftOf="@+id/input_arrow"
            android:layout_toRightOf="@+id/input_tip"
            android:background="@null"
            android:gravity="center_vertical"
            android:hint=""
            android:imeOptions="actionNext"
            android:maxLength="50"
            android:singleLine="true"
            android:textColor="#7c7f89"
            android:textColorHint="#bdbfc4"
            android:textSize="14sp" />

        <ImageButton
            android:id="@+id/input_arrow"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:background="@drawable/arrow_down"
            android:contentDescription="@string/app_name"
            android:onClick="onDownArrowClicked" />
    </RelativeLayout>

</RelativeLayout>

接下来我们编写用于放置选择条目的列表布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/input_select_listlayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <ListView
        android:id="@+id/input_select_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</RelativeLayout>

有了列表,我们还要编写每个条目的布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/input_selectitem_item"
    android:layout_width="match_parent"
    android:layout_height="46.7dip" >

    <ImageView
        android:id="@+id/input_selectitem_avatar"
        android:layout_width="40dip"
        android:layout_height="40dip"
        android:layout_centerVertical="true"
        android:layout_marginLeft="10dip"
        android:contentDescription="@string/app_name" />

    <TextView
        android:id="@+id/input_selectitem_account"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dip"
        android:layout_toLeftOf="@+id/input_selectitem_delete"
        android:layout_toRightOf="@+id/input_selectitem_avatar"
        android:ellipsize="end"
        android:singleLine="true"
        android:textColor="#7c7f89"
        android:layout_centerVertical="true"
        android:textSize="14sp" />

    <ImageButton
        android:id="@+id/input_selectitem_delete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:background="@drawable/icon_del"
        android:contentDescription="@string/app_name" />

</RelativeLayout>

编写好布局文件后我们需要一个测试界面:

package com.jone.example.spanner;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.PopupWindow.OnDismissListener;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.jone.example.spanner.SelectListAdapter.OnDelBtnClickListener;
import com.jone.example.spanner.SelectListAdapter.OnItemClickListener;

/**
 * 下拉列表测试界面
 * 
 * @author Jone
 */
public class MainActivity extends Activity implements OnItemClickListener, OnDelBtnClickListener, OnDismissListener
{
	private RelativeLayout mInputLayout;
	private ImageButton mArrow;
	private TextView mInput;
	private PopupWindow mSelectWindow;
	private LayoutInflater mInflater;
	private ArrayList<Integer> mAccounts;

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

	private void initView()
	{
		mInputLayout = (RelativeLayout) findViewById(R.id.input_layout);
		mArrow = (ImageButton) findViewById(R.id.input_arrow);
		mInput = (TextView) findViewById(R.id.input_et);
	}

	private void initData()
	{
		mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		mAccounts = new ArrayList<Integer>();
		for (int i = 0; i < 5; i++)
		{
			mAccounts.add(10086 + i);
		}
		mInput.setText(mAccounts.get(0) + "");
	}

	public void onDownArrowClicked(View view)
	{
		if (mAccounts.size() != 0)
		{
			mArrow.setBackgroundResource(R.drawable.arrow_up);
			showAccountChoiceWindow();
		}
	}

	private void showAccountChoiceWindow()
	{
		View view = mInflater.inflate(R.layout.input_selectlist, null);
		RelativeLayout contentview = (RelativeLayout) view.findViewById(R.id.input_select_listlayout);
		ListView userlist = (ListView) view.findViewById(R.id.input_select_list);
		userlist.setDividerHeight(0);

		SelectListAdapter adapter = new SelectListAdapter(this, mAccounts);
		adapter.setOnItemClickListener(this);
		adapter.setOnDelBtnClickListener(this);
		userlist.setAdapter(adapter);

		mSelectWindow = new PopupWindow(contentview, mInputLayout.getMeasuredWidth(), LayoutParams.WRAP_CONTENT, true);
		mSelectWindow.setBackgroundDrawable(getResources().getDrawable(R.drawable.bg_input_bottom_normal));
		mSelectWindow.setOutsideTouchable(true);
		mSelectWindow.setFocusable(true);
		mSelectWindow.setOnDismissListener(this);
		mSelectWindow.showAsDropDown(mInputLayout, 0, 0);
		mArrow.setBackgroundResource(R.drawable.arrow_up);
	}

	@Override
	public void onDelBtnClicked(int position)
	{
		mSelectWindow.dismiss();
		int inputAccount = Integer.valueOf(mInput.getText().toString());
		if (inputAccount == mAccounts.remove(position))
		{
			String nextAccount = "";

			if (mAccounts.size() != 0)
				nextAccount = mAccounts.get(0) + "";

			mInput.setText(nextAccount);
		}
		Toast.makeText(this, "删除账号成功", Toast.LENGTH_SHORT).show();
	}

	@Override
	public void onItemClicked(int position)
	{
		mSelectWindow.dismiss();
		mInput.setText(mAccounts.get(position) + "");
	}

	@Override
	public void onDismiss()
	{
		mArrow.setBackgroundResource(R.drawable.arrow_down);
	}
}

要显示条目的数据我们需要编写一个适配器:

package com.jone.example.spanner;

import java.util.ArrayList;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
 * 下拉列表适配器
 * 
 * @author Jone
 */
public class SelectListAdapter extends BaseAdapter
{
	private ArrayList<Integer> mAccounts = new ArrayList<Integer>();
	private LayoutInflater mInflater;
	private OnItemClickListener mOnItemClickListener;
	private OnDelBtnClickListener mOnDelBtnClickListener;

	public SelectListAdapter(Context context, ArrayList<Integer> items)
	{
		mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		mAccounts = items;
	}

	@Override
	public int getCount()
	{
		return mAccounts.size();
	}

	@Override
	public Object getItem(int position)
	{
		return mAccounts.get(position);
	}

	@Override
	public long getItemId(int position)
	{
		return position;
	}

	@Override
	public View getView(final int position, View convertView, ViewGroup parent)
	{
		ViewHolder viewHolder;
		if (convertView == null)
		{
			viewHolder = new ViewHolder();
			convertView = mInflater.inflate(R.layout.input_selectitem, null);
			viewHolder.mItem = (RelativeLayout) convertView.findViewById(R.id.input_selectitem_item);
			viewHolder.mAvatar = (ImageView) convertView.findViewById(R.id.input_selectitem_avatar);
			viewHolder.mAccount = (TextView) convertView.findViewById(R.id.input_selectitem_account);
			viewHolder.mDelete = (ImageButton) convertView.findViewById(R.id.input_selectitem_delete);
			convertView.setTag(viewHolder);
		}
		else
		{
			viewHolder = (ViewHolder) convertView.getTag();
		}

		if (position == mAccounts.size() - 1)
			viewHolder.mItem.setBackgroundResource(R.drawable.input_bottom_bg);
		else
			viewHolder.mItem.setBackgroundResource(R.drawable.input_middle_bg);

		viewHolder.mAccount.setText(mAccounts.get(position) + "");
		viewHolder.mAvatar.setImageResource(R.drawable.avatar);

		viewHolder.mItem.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				mOnItemClickListener.onItemClicked(position);
			}
		});

		viewHolder.mDelete.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				mOnDelBtnClickListener.onDelBtnClicked(position);
			}
		});

		return convertView;
	}

	private static class ViewHolder
	{
		RelativeLayout mItem;
		ImageView mAvatar;
		TextView mAccount;
		ImageButton mDelete;
	}

	/**
	 * 选择条目点击监听器接口
	 * 
	 * @author Jone
	 */
	public interface OnItemClickListener
	{
		public void onItemClicked(int position);
	}

	public void setOnItemClickListener(OnItemClickListener onItemClickListener)
	{
		mOnItemClickListener = onItemClickListener;
	}

	/**
	 * 删除按钮点击监听器接口
	 * 
	 * @author Jone
	 */
	public interface OnDelBtnClickListener
	{
		public void onDelBtnClicked(int position);
	}

	public void setOnDelBtnClickListener(OnDelBtnClickListener onDeleteBtnClickListener)
	{
		mOnDelBtnClickListener = onDeleteBtnClickListener;
	}

}

这就是实现这一功能的所有代码,是不是很简单呢?我们来看看运行的效果:


源码地址:点击打开链接


  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值