登录界面可以通过自定义Dialog来实现。
一、登录界面基本Dialog
继承Dialog后有三个构造函数,不一定要都实现,但必须实现一个构造函数。这三个构造函数的作用如下:
BaseView(Context context) :
单纯的传入Context,最常用。在代码中通过new来获得Dialog实例,然后使用show()展示。
BaseView(Context context, int themeResId) :
themeResId为主题值,可以传入一个主题值,比如:R.style.XXX,让Dialog使用所设置的主题。
BaseView(Context context, boolean cancelable, OnCancelListener cancelListener) :
cancelable 点击Dialog以外的地方是否取消Dialog,为false是点击Dialog以外的地方不消失。其实这个就等同于平常使用的setCanceledOnTouchOutside(false)。
cancelListener:当cancelable为true时才起作用。点击Dialog以外的地方时会调用cancelListener,可以在cancelListener里面做相应的监听事件。
先写一个最基本的登录界面的框架Dialog。
示例代码:
public class LoginBaseView extends Dialog {
private Context mContext ;
public LoginBaseView(@NonNull Context context) {
super(context);
mContext = context;
}
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);//隐藏标题栏
setCanceledOnTouchOutside(false);//按空白处不取消Dialog
//设置横竖屏对应的大小
int screenOrientation = mContext.getResources().getConfiguration().orientation;
if(screenOrientation == Configuration.ORIENTATION_LANDSCAPE){
dialog_width = FRAME_WIDTH_LANDSCAPE ;
dialog_height= FRAME_HEIGHT_LANDSCAPE ;
}else {
dialog_width = FRAME_WIDTH_PORTRAIL;
dialog_height= FRAME_HEIGHT_PORTRAIL;
}
LinearLayout linearLayout = new LinearLayout(mContext);
linearLayout.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(Config.dpiToPx(dialog_width), Config.dpiToPx(dialog_height));//设置大小
layoutParams.gravity = Gravity.CENTER; //设置居中
linearLayout.setBackgroundColor(dialog_background);//设置颜色
linearLayout.setLayoutParams(layoutParams);
// 顶部线
View lineView = new View(mContext);
int lineLand = Config.dpiToPx(10);
LinearLayout.LayoutParams lineParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, lineLand);
lineView.setBackgroundColor(dialog_tone);
linearLayout.addView(lineView, lineParams);
//登录框的主要内容
LoginContentView(linearLayout);
//把UI添加进来
setContentView(linearLayout,layoutParams);
}
//登录框的主要内容
protected void LoginContentView(LinearLayout linearLayout){
}
//点击返回键
protected void LoginonBackPressed(){
}
//展示登录界面
@Override
public void show() {
super.show();
}
/**
* 点击返回键*/
@Override
public void onBackPressed(){
LocalLogUtils.d("onBackPressed");
LoginonBackPressed();
};
}
基本效果:
为了美观些,还可以使用GradientDrawable做圆角处理,渐变色处理等等。
登陆界面或者注册界面都继承这个Dialog,并新增或者完善 LoginContentView 和LoginonBackPressed 这两个方法。
二、账号输入框、密码输入框、验证码输入框等控件
惯例先写一个基本的InputBar,让 InputBarUser(账号输入框)、InputBarPsw(密码输入框)等继承。
InputBar示例代码:
public class InputBar {
final LinearLayout layoutTop; //layout
public final ImageView ivIcon; //icon图片
public final EditText edtInput; //Edit输入框
final ImageButton btnClear; //Edit输入字符串清除按钮
protected InputBar(Context context) {
LinearLayout.LayoutParams params;
LinearLayout layoutTop = new LinearLayout(context);
params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
params.height = Config.dpiToPx(BAR_HEIGHT);
layoutTop.setLayoutParams(params);
layoutTop.setOrientation(LinearLayout.HORIZONTAL);
layoutTop.setGravity(Gravity.CENTER);
layoutTop.setPadding(Config.dpiToPx(10), 0, Config.dpiToPx(10), 0);
this.layoutTop = layoutTop;
//icon图片
ImageView iv = new ImageView(context);
params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
params.height = Config.dpiToPx(ICON_HEIGHT);
params.width = Config.dpiToPx(ICON_HEIGHT);
iv.setLayoutParams(params);
ivIcon = iv;
layoutTop.addView(ivIcon);
// 竖线
View v = new View(context);
params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
params.width = Config.dpiToPx(LINE_WIDTH);
params.height = Config.dpiToPx(ICON_HEIGHT + 5);
params.leftMargin = Config.dpiToPx(8);
v.setLayoutParams(params);
v.setBackgroundColor(InputBar.COLOR_LINE);
layoutTop.addView(v);
//Edit输入框
EditText edt = new EditText(context);
params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
params.weight = 1;
params.height = Config.dpiToPx(ICON_HEIGHT);
edt.setLayoutParams(params);
edt.setPadding(Config.dpiToPx(10), 0, Config.dpiToPx(10), 0);
edt.setBackgroundDrawable(null);
edt.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
edt.setTextColor(0xff000000);
edt.setHintTextColor(0xffa9a9a9);
edt.setTextSize(TypedValue.DENSITY_DEFAULT, Config.dpiToPx(16));
edt.setSingleLine(true);
edt.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); //输入时,键盘不全屏显示
edtInput = edt;
layoutTop.addView(edtInput);
//Edit输入字符串清除按钮
ImageButton btn = new ImageButton(context);
int paddingDp = 10;
int padding = Config.dpiToPx(paddingDp);
params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
params.width = Config.dpiToPx(15 + paddingDp * 2);
params.height = Config.dpiToPx(15 + paddingDp * 2);
btn.setLayoutParams(params);
btn.setPadding(padding, padding, padding, padding);
btn.setImageResource(Res.getDrawable("base_login_btn_clear"));//设置清除按钮的图片
btn.setBackgroundDrawable(null);
btn.setScaleType(ScaleType.FIT_XY);
btnClear = btn;
layoutTop.addView(btnClear);
btnClear.setVisibility(View.GONE);//默认是隐藏的,Edit有输入时才显示
btnClear.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
edtInput.setText("");//点击时清空Edit的内容
}
});
edtInput.addTextChangedListener(new BarTextWatcher());//监听Edit的输入
}
//是否需要ClearBtn
private boolean isEnableClearBtn = true;
protected void enableClearBtn(boolean isEnable) {
isEnableClearBtn = isEnable;
if (!isEnable) {
btnClear.setVisibility(View.GONE);
}
}
//设置过滤字符函数(过滤掉我们不需要的字符)
protected String onFliterInput(String str) {
return str;
}
//监听Edit的输入
protected boolean hasChangeText = true;
class BarTextWatcher implements 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) {
if(mOnTextChangeListener != null) {
if(mOnTextChangeListener.onTextChange(InputBar.this, s)) {
return;
}
}
hasChangeText = true;
if (isEnableClearBtn) {
//Edit有输入时,显示清除按钮。反之隐藏
if (s == null || s.length() == 0) {
btnClear.setVisibility(View.GONE);
} else {
btnClear.setVisibility(View.VISIBLE);
}
}
String rawStr = edtInput.getText().toString();
String fliterStr = onFliterInput(rawStr);//按规则清除我们不需要的字符
if (!rawStr.equals(fliterStr)) {
edtInput.setText(fliterStr);
}
}
@Override
public void afterTextChanged(Editable s) {
}
}
private OnTextChangeListener mOnTextChangeListener = null;
protected void setOnTextChangeListener(OnTextChangeListener listener) {
mOnTextChangeListener = listener;
}
protected interface OnTextChangeListener {
boolean onTextChange(InputBar bar, CharSequence s);
}
}
InputBarUser示例代码:
public class InputBarUser extends InputBar{
final ImageButton btnDrop;//点击查看以前登陆过用户的按钮
protected InputBarUser(Context context) {
super(context);
LinearLayout.LayoutParams params;
ivIcon.setImageResource(Res.getDrawable("base_login_icon_user"));//设置用户图标
ImageButton ib = new ImageButton(context);
params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
int paddingDp = 10;
int paddingAdd = 0;
int padding = Config.dpiToPx(paddingDp);
int paddingRL = Config.dpiToPx(paddingDp + paddingAdd/2);
params.width = Config.dpiToPx(20 + paddingAdd + paddingDp * 2);
params.height = Config.dpiToPx(20 + paddingDp * 2);
ib.setLayoutParams(params);
ib.setPadding(paddingRL, padding, paddingRL, padding);
ib.setImageResource(Res.getDrawable("base_login_arrow_down_gray"));//设置按钮图标
ib.setBackgroundDrawable(null);
ib.setScaleType(ScaleType.FIT_XY);
btnDrop = ib;
layoutTop.addView(btnDrop);
edtInput.setFilters(new InputFilter[] { new InputFilter.LengthFilter(20) });
}
}
调用示例代码:
......(省略)
inputBarUser = new InputBarUser(context);
inputBarUser.edtInput.setHint("用户名"); //设置输入框的提示
inputBarUser.btnDrop.setOnClickListener(onClickDrop);//按钮监听
inputBarUser.setOnTextChangeListener(mOnTextChangeListener);//Edit输入监听
layoutInput.addView(inputBarUser.layoutTop);
......(省略)
登陆Dialog调用示例:
LoginNormalView LoginDialog =new LoginNormalView(mActivity);
LoginDialog.show();
基本效果:(这只是个Demo)
上述代码只是个简单的Demo 还缺少很多代码,如果要使用还要自己完善
这InputBarUser是不是好像少了边缘框,因为这个需要在登录框界面中把边缘框加到InputBarUser和InputBarPaw,或者其他组合当中。所以就没必要写到InputBarUser当中了。
在上述代码中查找图片ID使用的是Res.getDrawable(“base_login_arrow_down_gray”),而不是常用的R.XX.XXX。因为SDK是一个module ,需要其他APP来调用,所以需要使用“resources.getIdentifier(name, “drawable”, packageName);”来寻找指定的资源。
onBackPressed 返回按键,一般快速连续点击两次时,执行Dialog.dismiss()。
onClickDrop监听到点击后,应该展示一个list layout。list的简单使用,可以点击这里。
mOnTextChangeListener 有输入后应该显示清除按钮,点击清除按钮后,清除账号和密码输入框的字符串。
InputBarPsw 基本同理。
InputBarPsw 需要 显示或者隐藏(设置成**)的功能。这个通过edtInput.setInputType()设置InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD(显示)或者InputType.TYPE_TEXT_VARIATION_PASSWORD(隐藏)
InputBarPhone
InputBarPhone 需要获取验证码倒计时的功能,即点击获取验证码之后,获取验证码按钮进入倒计时。可以使用Timer和TimerTask,定时对验证码按钮进行setText。简单使用,可以点击这里。