首先上图看效果:
点击下拉图标后出现下面的界面
个人感觉还是可以的,只是感觉不怎么美观,这个没办法,本人还是缺少了艺术细菌的。
现在来讲下技术吧!整个是通过listview+PopupWindow来完成的,感觉listView的功能还是很强大的。开始打算用spinner的但是感觉问题有点大,而且也达不到相应的效果,首先说下难点吧。第一个是数据的加载和存储方面,我们可以用set将用户的账号存储起来,头像就用用账号主键存储。所有的记录都用SharedPreferences来存储,但是有一点。就是在删除数据时,每次删除一个数据时,最好将已经存储的set整个删除掉,再重新存储。因为如果没有删除的话项目退出后再进去的时候会出现没有删掉的情况,而且烦死人,只能插入不能删除。
第二个还有就是当出现下拉列表时,我们会发现下拉按钮也改变了的,当列表消失时,就是不管点击那里消失时按钮都会改变。这个其实就是popuwindow的一个函数就搞定了,开始没有找到所以纠结死了,看了说明文档之后感觉头上光芒万丈,胜利女神都在对我微笑呀!
其他的都没什么难处,感觉都蛮容易的,只是看能不能想到这种用法,还有就是想要做出好的效果就得有这大量的艺术细菌呀!
下面是代码送上
用户类
package com.example.gettest;
public class LoginBean {
private String number;
private String user_image;
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getUser_image() {
return user_image;
}
public void setUser_image(String user_image) {
this.user_image = user_image;
}
}
列表的适配器类
package com.example.gettest;
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
//自定义适配器Adapter
public class LoginUserAdapter extends BaseAdapter {
private ArrayList<LoginBean> list = new ArrayList<LoginBean>();
private Activity activity = null;
private Handler handler;
/**
* 自定义构造方法
*
* @param activity
* @param handler
* @param list
*/
public LoginUserAdapter(Activity activity, Handler handler,
ArrayList<LoginBean> list) {
this.activity = activity;
this.handler = handler;
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
// 下拉项布局
convertView = LayoutInflater.from(activity).inflate(
R.layout.login_user_item, null);
holder.textView = (TextView) convertView
.findViewById(R.id.item_text);
holder.logLayout = (LinearLayout) convertView
.findViewById(R.id.log_layout);
holder.delLayout = (LinearLayout) convertView
.findViewById(R.id.del_layout);
holder.imageView = (ImageView) convertView
.findViewById(R.id.item_imag);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(list.get(position).getNumber());
holder.imageView.setImageResource(R.drawable.default_icon);
// 为下拉框选项文字部分设置事件,最终效果是点击将其文字填充到文本框
holder.logLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message msg = new Message();
Bundle data = new Bundle();
// 设置选中索引
data.putInt("selIndex", position);
msg.setData(data);
msg.what = 1;
// 发出消息
handler.sendMessage(msg);
}
});
// 为下拉框选项删除图标部分设置事件,最终效果是点击将该选项删除
holder.delLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message msg = new Message();
Bundle data = new Bundle();
// 设置删除索引
data.putInt("delIndex", position);
msg.setData(data);
msg.what = 2;
// 发出消息
handler.sendMessage(msg);
}
});
return convertView;
}
}
class ViewHolder {
ImageView imageView;
TextView textView;
LinearLayout logLayout;
LinearLayout delLayout;
}
最后是界面类
package com.example.gettest;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.PopupWindow.OnDismissListener;
import android.widget.Toast;
import android.widget.LinearLayout.LayoutParams;
public class CheckLoginActivity extends Activity implements Callback {
private CheckLoginActivity myself = this;
private LinearLayout login, btn_regedit, forget, iv_left;
private EditText username, pswd;
private String usernames, pswds;
private ImageView iv_openlist;
private ImageView iv_closelist;
private LinearLayout loadingPb;
// PopupWindow对象
private PopupWindow selectPopupWindow = null;
// 自定义Adapter
private LoginUserAdapter optionsAdapter = null;
// 下拉框选项数据源
private ArrayList<LoginBean> datas = new ArrayList<LoginBean>();
private Set<String> set = new HashSet<String>();
// 下拉框依附组件
private LinearLayout parent;
// 下拉框依附组件宽度,也将作为下拉框的宽度
private int pwidth;
// 下拉箭头图片组件
private LinearLayout ll_image;
// 恢复数据源按钮
private Button button;
// 展示所有下拉选项的ListView
private ListView listView = null;
// 用来处理选中或者删除下拉项消息
private Handler handler;
// 是否初始化完成标志
private boolean flag = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.check_login);
}
/**
* 没有在onCreate方法中调用initWedget(),而是在onWindowFocusChanged方法中调用,
* 是因为initWedget()中需要获取PopupWindow浮动下拉框依附的组件宽度,在onCreate方法中是无法获取到该宽度的
*/
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
while (!flag) {
initWedget();
flag = true;
}
}
/**
* 初始化界面控件
*/
private void initWedget() {
loadingPb = (LinearLayout) findViewById(R.id.list_view_pb);
username = (EditText) findViewById(R.id.username);
pswd = (EditText) findViewById(R.id.pswd);
iv_openlist = (ImageView) findViewById(R.id.ib_imagbtn);
iv_closelist = (ImageView) findViewById(R.id.ib_imagbtn_close);
// 初始化Handler,用来处理消息
handler = new Handler(CheckLoginActivity.this);
// 初始化界面组件
parent = (LinearLayout) findViewById(R.id.ll_login_list);
ll_image = (LinearLayout) findViewById(R.id.ll_imagbtn);
// 获取下拉框依附的组件宽度
int width = parent.getWidth();
pwidth = width;
iv_left = (LinearLayout) findViewById(R.id.iv_left);
iv_left.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
Toast.makeText(myself, "返回按钮", Toast.LENGTH_SHORT).show();
}
});
// 登录
login = (LinearLayout) findViewById(R.id.login);
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
usernames = username.getText().toString();
if (usernames.equals("")) {
Toast.makeText(myself, "请输入用户名", Toast.LENGTH_SHORT).show();
return;
}
pswds = pswd.getText().toString();
if (pswds.equals("")) {
Toast.makeText(myself, "请输入密码", Toast.LENGTH_SHORT).show();
return;
}
loadingPb.setVisibility(View.VISIBLE);
}
});
// 快速注册
btn_regedit = (LinearLayout) findViewById(R.id.btn_regedit);
btn_regedit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(myself, "注册按钮", Toast.LENGTH_SHORT).show();
}
});
// 忘记密码
forget = (LinearLayout) findViewById(R.id.forget);
forget.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
Toast.makeText(myself, "忘记密码", Toast.LENGTH_SHORT).show();
}
});
// 设置点击下拉箭头图片事件,点击弹出PopupWindow浮动下拉框
ll_image.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (flag) {
// 显示PopupWindow窗口
popupWindwShowing();
}
}
});
// 初始化PopupWindow
initPopuWindow();
}
/**
* 初始化填充Adapter所用List数据
*/
@SuppressLint("NewApi")
public void initDatas() {
datas.clear();
initDatasSet();
LoginBean loginBean;
// 通过set来存储登陆过的所有用户
// SharedPreferences sp = getSharedPreferences("user", 0);
// set = sp.getStringSet("login", set);
for (String login : set) {
loginBean = new LoginBean();
loginBean.setUser_image(login);
loginBean.setNumber(login);
datas.add(loginBean);
}
}
/**
* 初始化填充Adapter所用List数据
*/
private void initDatasSet() {
set.clear();
set.add("北京");
set.add("上海");
set.add("广州");
set.add("深圳");
set.add("重庆");
set.add("青岛");
set.add("石家庄");
}
/**
* 初始化PopupWindow
*/
private void initPopuWindow() {
initDatas();
// PopupWindow浮动下拉框布局
View loginwindow = (View) this.getLayoutInflater().inflate(
R.layout.login_user_list, null);
listView = (ListView) loginwindow.findViewById(R.id.list);
// 设置自定义Adapter
optionsAdapter = new LoginUserAdapter(this, handler, datas);
listView.setAdapter(optionsAdapter);
selectPopupWindow = new PopupWindow(loginwindow, pwidth,
LayoutParams.WRAP_CONTENT, true);
selectPopupWindow.setOutsideTouchable(true);
selectPopupWindow.setFocusable(false);
// 这一句是为了实现弹出PopupWindow后,当点击屏幕其他部分及Back键时PopupWindow会消失,
// 没有这一句则效果不能出来,但并不会影响背景
// 本人能力极其有限,不明白其原因,还望高手、知情者指点一下
selectPopupWindow.setBackgroundDrawable(new BitmapDrawable());
selectPopupWindow.setOnDismissListener(new OnDismissListener() {
public void onDismiss() {
iv_openlist.setVisibility(View.VISIBLE);
iv_closelist.setVisibility(View.GONE);
}
});
}
/**
* 显示PopupWindow窗口
*
* @param popupwindow
*/
public void popupWindwShowing() {
iv_closelist.setVisibility(View.VISIBLE);
iv_openlist.setVisibility(View.GONE);
// iv_openlist.setBackgroundResource(R.drawable.close_login_user);
// 将selectPopupWindow作为parent的下拉框显示,并指定selectPopupWindow在Y方向上向上偏移3pix,
// 这是为了防止下拉框与文本框之间产生缝隙,影响界面美化
// (是否会产生缝隙,及产生缝隙的大小,可能会根据机型、Android系统版本不同而异吧,不太清楚)
selectPopupWindow.showAsDropDown(parent, 0, 0);
}
/**
* PopupWindow消失
*/
public void dismiss() {
iv_openlist.setVisibility(View.VISIBLE);
iv_closelist.setVisibility(View.GONE);
selectPopupWindow.dismiss();
}
/**
* 处理Hander消息
*/
@SuppressLint("NewApi")
@Override
public boolean handleMessage(Message message) {
Bundle data = message.getData();
switch (message.what) {
case 1:
// 选中下拉项,下拉框消失
int selIndex = data.getInt("selIndex");
username.setText(datas.get(selIndex).getNumber());
dismiss();
break;
case 2:
// 移除下拉项数据
int delIndex = data.getInt("delIndex");
set.remove(datas.get(delIndex));
datas.remove(delIndex);
SharedPreferences preferences = getSharedPreferences("user",
Context.MODE_PRIVATE);
Editor editor = preferences.edit();
editor.remove("login");
editor.commit();
editor.putStringSet("login", set);
editor.commit();
// 刷新下拉列表
optionsAdapter.notifyDataSetChanged();
break;
}
return false;
}
}