核心代码:
PasswordView.java
package com.huatec.myapplication;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class PasswordView extends RelativeLayout {
Context context;
private String strPassword; // 输入的密码
private TextView[] tvList; // 就6个输入框不会变了,用数组内存申请固定空间,比List省空间
private GridView gridView; // 用GrideView布局键盘,其实并不是真正的键盘,只是模拟键盘的功能
private ArrayList<Map<String, String>> valueList; // 要用Adapter中适配,用数组不能往adapter中填充
private ImageView tvCancel;//取消按钮
private TextView tvForget;//忘记密码按钮
private int currentIndex = -1; // 用于记录当前输入密码格位置
public PasswordView(Context context) {
this(context, null);
}
public PasswordView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
//view布局
View view = View.inflate(context, R.layout.layout_popup_bottom, null);
valueList = new ArrayList<>();
tvList = new TextView[6];
//初始化控件
tvCancel = (ImageView) view.findViewById(R.id.tvCancel);
tvForget = (TextView) view.findViewById(R.id.tv_forgetPwd);
tvList[0] = (TextView) view.findViewById(R.id.tv_pass1);
tvList[1] = (TextView) view.findViewById(R.id.tv_pass2);
tvList[2] = (TextView) view.findViewById(R.id.tv_pass3);
tvList[3] = (TextView) view.findViewById(R.id.tv_pass4);
tvList[4] = (TextView) view.findViewById(R.id.tv_pass5);
tvList[5] = (TextView) view.findViewById(R.id.tv_pass6);
//初始化键盘
gridView = (GridView) view.findViewById(R.id.gv_keybord);
//设置键盘显示按钮到集合
setView();
// 必须要,不然不显示控件
addView(view);
}
//设置按钮显示内容
private void setView() {
// 初始化按钮上应该显示的数字
for (int i = 1; i < 13; i++) {
Map<String, String> map = new HashMap<>();
if (i < 10) {
map.put("name", String.valueOf(i));
} else if (i == 10) {
map.put("name", "");
} else if (i == 12) {
map.put("name", "<<-");
} else if (i == 11) {
map.put("name", String.valueOf(0));
}
valueList.add(map);
}
//为键盘gridview设置适配器
gridView.setAdapter(adapter);
//为键盘按键添加点击事件
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// 点击0~9按钮
if (position < 11 && position != 9) {
// 判断输入位置————要小心数组越界
if (currentIndex >= -1 && currentIndex < 5) {
tvList[++currentIndex].setText(valueList.get(position).get("name"));
}
} else {
// 点击退格键
if (position == 11) {
// 判断是否删除完毕————要小心数组越界
if (currentIndex - 1 >= -1) {
tvList[currentIndex--].setText("");
}
}
}
}
});
}
// 设置监听方法,在第6位输入完成后触发
public void setOnFinishInput(final OnPasswordInputFinish pass) {
tvList[5].addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (s.toString().length() == 1) {
// 每次触发都要先将strPassword置空,再重新获取,避免由于输入删除再输入造成混乱
strPassword = "";
for (int i = 0; i < 6; i++) {
strPassword += tvList[i].getText().toString().trim();
}
// 接口中要实现的方法,完成密码输入完成后的响应逻辑
pass.inputFinish();
}
}
});
tvCancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//点击取消调用接口
pass.outfo();
}
});
tvForget.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//单击忘记密码调用接口
pass.forgetPwd();
}
});
}
//获取输入的密码
public String getStrPassword() {
return strPassword;
}
// GrideView的适配器
BaseAdapter adapter = new BaseAdapter() {
@Override
public int getCount() {
return valueList.size();
}
@Override
public Object getItem(int position) {
return valueList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
//装载数字键盘布局
convertView = View.inflate(context, R.layout.item_gride, null);
viewHolder = new ViewHolder();
//初始化键盘按钮
viewHolder.btnKey = convertView.findViewById(R.id.btn_keys);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
//设置按钮显示数字
viewHolder.btnKey.setText(valueList.get(position).get("name"));
if (position == 9) {
//设置按钮背景
viewHolder.btnKey.setBackgroundResource(R.drawable.selector_key_del);
//设置按钮不可点击
viewHolder.btnKey.setEnabled(false);
}
if (position == 11) {
//设置按钮背景
viewHolder.btnKey.setBackgroundResource(R.drawable.selector_key_del);
}
return convertView;
}
};
public final class ViewHolder {
public TextView btnKey;
}
}
layout_popup_bottom.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF">
<LinearLayout
android:id="@+id/linear_pass"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true">
<!--支付密码标题-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_margin="5dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="支付密码"
android:textColor="#898181"
android:textSize="20sp" />
<ImageView
android:id="@+id/tvCancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ic_clear_black_24dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"/>
</RelativeLayout>
<!--分割线-->
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#33000000" />
<!-- 6位密码框布局,需要一个圆角边框的shape作为layout的背景 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:layout_marginTop="20dp"
android:background="@drawable/shape_input_area"
android:orientation="horizontal" >
<!--
inputType设置隐藏密码明文
textSize设置大一点,否则“点”太小了,不美观
-->
<TextView
android:id="@+id/tv_pass1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:inputType="numberPassword"
android:textSize="30sp" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#999999" />
<TextView
android:id="@+id/tv_pass2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:inputType="numberPassword"
android:textSize="30sp" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#999999" />
<TextView
android:id="@+id/tv_pass3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:inputType="numberPassword"
android:textSize="30sp" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#999999" />
<TextView
android:id="@+id/tv_pass4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:inputType="numberPassword"
android:textSize="30sp" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#999999" />
<TextView
android:id="@+id/tv_pass5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:inputType="numberPassword"
android:textSize="30sp" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#999999" />
<TextView
android:id="@+id/tv_pass6"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:inputType="numberPassword"
android:textSize="30sp" />
</LinearLayout>
<!-- 忘记密码链接 -->
<TextView
android:id="@+id/tv_forgetPwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_margin="15dp"
android:text="忘记密码?"
android:textColor="#354EEF" />
</LinearLayout>
<!-- 输入键盘 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical">
<View
android:id="@+id/vw1"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#11000000"/>
<GridView
android:id="@+id/gv_keybord"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#11000000"
android:verticalSpacing="0.5dp"
android:horizontalSpacing="0.5dp"
android:numColumns="3"
android:layout_alignParentBottom="true"/>
</LinearLayout>
</RelativeLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化控件
final PasswordView pwdView = findViewById(R.id.pwd_view);
// 添加回调接口
pwdView.setOnFinishInput(new OnPasswordInputFinish() {
@Override
public void inputFinish() {
// 输入完成后我们简单显示一下输入的密码
// 也就是说——>实现你的交易逻辑什么的在这里写
Toast.makeText(MainActivity.this, pwdView.getStrPassword(),
Toast.LENGTH_SHORT).show();
}
//取消支付
@Override
public void outfo() {
//关闭支付页面
finish();
}
//忘记密码回调事件
@Override
public void forgetPwd() {
Toast.makeText(MainActivity.this, "忘记密码", Toast.LENGTH_SHORT).show();
}
});
}
}
效果图:
2018-05-22 12_12_15.gif
网友评论