android仿支付宝输入支付密码详细介绍
一、自定义六位密码框输入
效果图如下:
public class InputSixPwdView extends TextView {
private Paint borderPaint;
private Paint passwordPaint;
private int passwordLength = 6;
private int borderWidth = 8;
private int passwordWidth = 16;
private int textLength;
private OnFinishListener onFinishListener;
private Stack<String> pwdQuee = new Stack<String>();
public InputSixPwdView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public InputSixPwdView(Context context, AttributeSet attr) {
super(context, attr);
init(context, attr);
}
private void init(Context context, AttributeSet attr) {
borderPaint = new Paint();
borderPaint.setAntiAlias(true);
borderPaint.setColor(getResources().getColor(R.color.txtcolor_light));
borderPaint.setStrokeWidth(borderWidth);
borderPaint.setStyle(Paint.Style.FILL);
passwordPaint = new Paint();
passwordPaint.setAntiAlias(true);
passwordPaint.setColor(getResources().getColor(R.color.txtcolor));
passwordPaint.setStrokeWidth(passwordWidth);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
int height = getHeight();
int width = getWidth();
//画边框
RectF rect = new RectF(0, 0, width, height);
borderPaint.setColor(getResources().getColor(R.color.txtcolor_light));
canvas.drawRoundRect(rect, 12, 12, borderPaint);
//画内容区域
RectF rectContent = new RectF(rect.left + 4, rect.top + 4, rect.right - 4, rect.bottom - 4);
borderPaint.setColor(getResources().getColor(R.color.main_background));
canvas.drawRoundRect(rectContent, 10, 10, borderPaint);
//画分割线:分割线数量比密码数少1
borderPaint.setColor(getResources().getColor(R.color.bg_ed));
borderPaint.setStrokeWidth(4);
for (int i = 1; i < passwordLength; i++) {
float x = width * i / passwordLength;
canvas.drawLine(x, 17, x, height - 17, borderPaint);
}
//画密码内容
float px, py = height / 2;
float halfWidth = width / passwordLength / 2;
for (int i = 0; i < textLength; i++) {
px = width * i / passwordLength + halfWidth;
canvas.drawCircle(px, py, passwordWidth, passwordPaint);
}
}
public void addPwd(String tpwd) {
textLength = pwdQuee.size();
if (textLength < 6) {
pwdQuee.add(tpwd);
textLength = pwdQuee.size();
if (textLength == 6) {
StringBuffer sb = new StringBuffer();
for (String s : pwdQuee) {
sb.append(s);
}
onFinishListener.setOnPasswordFinished(sb.toString());
}
postInvalidate();
}
}
public void reSetView() {
if (null != pwdQuee) {
pwdQuee.clear();
}
textLength = 0;
invalidate();
}
public void deletePwd() {
if (!pwdQuee.isEmpty()) {
pwdQuee.pop();
textLength = pwdQuee.size();
if (textLength < 7) {
invalidate();
}
}
}
public void reset() {
if (!pwdQuee.isEmpty()) {
pwdQuee.clear();
}
postInvalidate();
}
public void setOnFinishListener(OnFinishListener onFinishListener) {
this.onFinishListener = onFinishListener;
}
public interface OnFinishListener {
void setOnPasswordFinished(String pwd);
}
}
二、界面布局
<?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="match_parent"
android:background="@color/main_background"
android:orientation="vertical">
<TextView
android:id="@+id/activity_setpaypassword_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/y48"
android:layout_marginTop="@dimen/y60"
android:gravity="center"
android:text="请输入新的支付密码"
android:textColor="@color/txtcolor"
android:textSize="20sp" />
<com.phsxy.footballbaby.widgets.InputSixPwdView
android:id="@+id/activity_forgetpaypassword_view"
android:layout_width="match_parent"
android:layout_height="@dimen/y86"
android:layout_marginLeft="@dimen/x48"
android:layout_marginRight="@dimen/x48" />
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<GridView
android:id="@+id/activity_forgetpaypassword_gv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#5C5C5C"
android:divider="@color/clear"
android:horizontalSpacing="@dimen/x12"
android:numColumns="3"
android:paddingBottom="@dimen/y6"
android:paddingLeft="@dimen/x12"
android:paddingRight="@dimen/x12"
android:paddingTop="@dimen/y12"
android:verticalSpacing="@dimen/y14" />
</LinearLayout>
三、activity
public class SetPayPasswordActivity extends AppBaseActivity {
@BindView(R.id.activity_setpaypassword_tv)
TextView tvSetPayPassword;
@BindView(R.id.activity_forgetpaypassword_view)
InputSixPwdView mInputSixPwdView;
@BindView(R.id.activity_forgetpaypassword_gv)
GridView mGridView;
private InputPwdViewAdapter mAdapter;
private int isType;//0设置新密码1输入原密码
public static final String SETPAYPASSWORDSTR = "SetPayPassword_str";
@Override
protected void setinitVariable() {
isType = getIntent().getIntExtra(SETPAYPASSWORDSTR, 0);
}
@Override
protected void setTitleViews() {
setTitle(getString(R.string.paypassword_titlestr));
dismissTopLine();
}
@Override
protected Object getLayout() {
return R.layout.activity_setpaypassword_layout;
}
@Override
protected void setupDataForPage() {
if (isType == 1) {//输入原密码
tvSetPayPassword.setText("请输入原支付密码");
} else {//设置新密码
tvSetPayPassword.setText("请输入新的支付密码");
}
mInputSixPwdView.reSetView();
mAdapter = new InputPwdViewAdapter(mContext);
mGridView.setAdapter(mAdapter);
mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position == 11) {//点击删除键
mInputSixPwdView.deletePwd();
} else if (position == 10) {
mInputSixPwdView.addPwd("0");
} else if (position == 9) {
} else {
mInputSixPwdView.addPwd(String.valueOf(++position));
}
}
});
mInputSixPwdView.setOnFinishListener(new InputSixPwdView.OnFinishListener() {
@Override
public void setOnPasswordFinished(String pwd) {
mInputSixPwdView.reSetView();
if (isType == 1) {//输入原密码
checkPayPassword(pwd);//进行原密码校验
} else {//设置新密码
Intent mIntent = new Intent(SetPayPasswordActivity.this, SureSetPayPasswordActivity.class);
mIntent.putExtra(SureSetPayPasswordActivity.FIRSTPAYPASSWORD, pwd);
startActivityForResult(mIntent, 0);
}
}
});
}
/**
* 支付密码校验
*/
private void checkPayPassword(final String password) {
//校验逻辑
}
四、键盘Adapter
public class InputPwdViewAdapter extends BaseAdapter {
private Context mContext;
public InputPwdViewAdapter(Context context) {
this.mContext = context;
}
@Override
public int getCount() {
return 12;
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final Holder holder;
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.adapter_inputpwdview_item_layout, null);
holder = new Holder(convertView);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
convertView.setBackgroundResource(R.drawable.bg_black_selector);
holder.tvNum.setVisibility(View.VISIBLE);
holder.tvNum.setText((position + 1) + "");
holder.tvABC.setVisibility(View.VISIBLE);
holder.tvDelete.setVisibility(View.GONE);
switch (position) {
case 0:
holder.tvABC.setVisibility(View.INVISIBLE);
break;
case 1:
holder.tvABC.setText("ABC");
break;
case 2:
holder.tvABC.setText("DEF");
break;
case 3:
holder.tvABC.setText("GHI");
break;
case 4:
holder.tvABC.setText("JKL");
break;
case 5:
holder.tvABC.setText("MNO");
break;
case 6:
holder.tvABC.setText("PQRS");
break;
case 7:
holder.tvABC.setText("TUV");
break;
case 8:
holder.tvABC.setText("WXYZ");
break;
case 9:
holder.tvNum.setVisibility(View.GONE);
holder.tvABC.setVisibility(View.GONE);
holder.tvDelete.setVisibility(View.GONE);
break;
case 10:
holder.tvNum.setVisibility(View.VISIBLE);
holder.tvNum.setText("0");
holder.tvABC.setText("");
holder.tvDelete.setVisibility(View.GONE);
break;
case 11:
holder.tvNum.setText("");
holder.tvABC.setText("");
holder.tvDelete.setVisibility(View.VISIBLE);
convertView.setBackgroundColor(mContext.getResources().getColor(R.color.clear));
break;
default:
break;
}
return convertView;
}
class Holder {
TextView tvNum, tvABC, tvDelete;
Holder(View view) {
tvNum = (TextView) view.findViewById(R.id.adapter_inputpwd_tv);
tvABC = (TextView) view.findViewById(R.id.adapter_inputpwd_abc);
tvDelete = (TextView) view.findViewById(R.id.adapter_inputpwd_delete);
}
}
}
五、键盘adapter布局
<?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="@dimen/y100"
android:elevation="2dp"
android:background="@drawable/bg_black_selector">
<TextView
android:id="@+id/adapter_inputpwd_delete"
android:layout_width="@dimen/x46"
android:layout_height="@dimen/y36"
android:layout_centerInParent="true"
android:background="@mipmap/icon_delete_inputpwd"
android:visibility="gone" />
<TextView
android:id="@+id/adapter_inputpwd_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="1"
android:textColor="@color/white"
android:textSize="25sp" />
<TextView
android:id="@+id/adapter_inputpwd_abc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/y56"
android:gravity="center_horizontal"
android:text="ABC"
android:textColor="@color/white"
android:textSize="10sp" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bg_shape_black_normal" android:state_enabled="false" />
<item android:drawable="@drawable/bg_shape_black_press" android:state_pressed="true" />
<item android:drawable="@drawable/bg_shape_black_normal" />
</selector>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="5dp" />
<solid android:color="#8D8D8D" />
</shape>
<color name="txtcolor_light">#9B9797</color>
<color name="txtcolor">#272121</color>
<color name="main_background">#FCFCFC</color>