转载请注明出处: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;
}
}
这就是实现这一功能的所有代码,是不是很简单呢?我们来看看运行的效果:
源码地址:点击打开链接