输入框输入日期校验
String birthdayPattern = "^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|" +
"([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|" +
"([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?(" +
"(0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?(" +
"(0?[1-9])|(1[0-9])|(2[0-8]))))))";
private void initView(){
birthdayEdit = findViewById(R.id.birthday);
birthdayEdit.addTextChangedListener(birthdayWatcher);
}
String additionalContent = "11111111"; //用以填充时间 比如输入 201时因为用正则匹配不能部分匹配 所以填充成 20111111 此时再判断是否满足正则表达式
Matcher m;
Pattern p;
String temp; // 保存填充后的时间
int textLength = 0;
private TextWatcher birthdayWatcher = 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) {
//全部删除按钮
if (TextUtils.isEmpty(s.toString())) {
findViewById(R.id.clear_birthday).setVisibility(View.INVISIBLE);
return;
} else {
findViewById(R.id.clear_birthday).setVisibility(View.VISIBLE);
}
//当删除的过程中再次输入 自动添加"-"
if ((s.length() == 5 || s.length() == 8) && !s.toString().substring(s.length() - 1, s.length()).equals("-")) {
String temp = s.toString().substring(0, s.length() - 1) + "-" + s.toString().substring(s.length() - 1, s.length());
birthdayEdit.setText(temp);
birthdayEdit.setSelection(temp.length());
return;
}
temp = s + additionalContent.substring(0, s.toString().replace("-", "").length() < 8 ? 8 - s.toString().replace
("-", "").length() : 0);
p = Pattern.compile(birthdayPattern);
m = p.matcher(temp.replace("-", ""));
boolean b = m.matches();
if (!b) {
// birthdayEdit.setText(s.subSequence(0, s.length() - 1));
// birthdayEdit.setSelection(s.length() - 1);
ToastMaster.shortToast("输入格式有误");
}
//自动填充“-”
if (textLength < s.length()) {
//在输入过程中自动填充“-” 例如输入2019自动填写成2019-
if (s.length() == 4 || s.length() == 7) {
String temp1 = s + "-";
birthdayEdit.setText(temp1);
birthdayEdit.setSelection(temp1.length());
}
} else {
//在删除过程中自动删除“-” 例如2019-2 此时删除2 "-"应该自动删除
if (s.charAt(s.length() - 1) == '-') {
s = s.subSequence(0, s.length() - 1);
birthdayEdit.setText(s);
birthdayEdit.setSelection(s.length());
}
}
//记录输入的内容是在增加还是减少
textLength = s.length();
}
@Override
public void afterTextChanged(Editable s) {
}
};
更新2019/1/25
把生日输入框抽取成独立的组件
public class BirthdayEditText extends LinearLayout {
EditText birthday;
View clear;
String birthdayPattern = "^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|" +
"([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|" +
"([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?(" +
"(0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?(" +
"(0?[1-9])|(1[0-9])|(2[0-8]))))))";
String additionalContent = "11111111";
Matcher m;
Pattern p;
String temp;
int textLength = 0;
public BirthdayEditText(Context context) {
super(context);
init(context);
}
public BirthdayEditText(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
public BirthdayEditText(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
View view = LayoutInflater.from(context).inflate(R.layout.birthday_edittext, null);
birthday = view.findViewById(R.id.birthday_edit);
birthday.addTextChangedListener(watcher);
clear = view.findViewById(R.id.clear_birthday);
addView(view);
}
public void setText(String text) {
birthday.setText(text);
birthday.setSelection(text.length());
}
public String getText() {
return birthday.getText().toString().trim();
}
/**
*自动获取焦点
*/
public void setFocus() {
birthday.setFocusable(true);
birthday.setFocusableInTouchMode(true);
birthday.requestFocus();
birthday.setSelection(birthday.getText().toString().length());
birthday.postDelayed(new Runnable() {
@Override
public void run() {
InputMethodManager imm = (InputMethodManager) birthday.getContext().getSystemService(Context
.INPUT_METHOD_SERVICE);
imm.showSoftInput(birthday, 0);
}
}, 200);
}
private TextWatcher watcher = 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) {
//当删除的过程中再次输入 自动添加"-"
if ((s.length() == 5 || s.length() == 8) && !s.toString().substring(s.length() - 1, s.length()).equals("-")) {
String temp = s.toString().substring(0, s.length() - 1) + "-" + s.toString().substring(s.length() - 1, s.length
());
birthday.setText(temp);
birthday.setSelection(temp.length());
return;
}
//删除按钮
if (TextUtils.isEmpty(s.toString())) {
clear.setVisibility(View.INVISIBLE);
return;
} else {
clear.setVisibility(View.VISIBLE);
}
temp = s + additionalContent.substring(0, s.toString().replace("-", "").length() < 8 ? 8 - s.toString().replace
("-", "").length() : 0);
p = Pattern.compile(birthdayPattern);
m = p.matcher(temp.replace("-", ""));
boolean b = m.matches();
if (!b) {
// birthday.setText(s.subSequence(0, s.length()-1));
// birthday.setSelection(s.length() - 1);
ToastMaster.shortToast("输入格式有误");
}
//自动填充“-”
if (textLength < s.length()) {
if (s.length() == 4 || s.length() == 7) {
String temp1 = s + "-";
birthday.setText(temp1);
birthday.setSelection(temp1.length());
}
} else {
if (s.toString().endsWith("-")) {
s = s.subSequence(0, s.length() - 1);
birthday.setText(s);
birthday.setSelection(s.length());
}
}
textLength = s.length();
}
@Override
public void afterTextChanged(Editable s) {
}
};
}
xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<EditText
android:id="@+id/birthday_edit"
android:layout_width="250dp"
android:layout_height="match_parent"
android:background="@null"
android:layout_gravity="center_vertical"
android:hint="请输入生日 例如:20190111"
android:imeOptions="actionDone"
android:inputType="number|numberDecimal"
android:maxLength="10" />
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<View
android:id="@+id/clear_birthday"
android:layout_width="24dp"
android:layout_height="24dp"
android:background="@drawable/icon_dele_gray"
android:visibility="visible" />
LinearLayout>
自动旋转显示UI
用出 :在处理拍照时头像移动方向与真实方向相反的问题
旋转的组件(把需要旋转的容器被其包裹就可以了)
public class ScaleLinearLayout extends LinearLayout {
public ScaleLinearLayout(Context context) {
super(context);
}
public ScaleLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScaleLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.scale(-1f, 1f, getWidth() * 0.5f, getHeight() * 0.5f);
super.dispatchDraw(canvas);
}
}
xml
<com.xyz.ScaleLinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:id="@+id/relative"
android:layout_width="550dp"
android:layout_height="412dp"
android:background="#999999">
<TextureView
android:id="@+id/camera_view"
android:layout_width="match_parent"
android:layout_height="412dp" />
<ImageView
android:id="@+id/tip_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
<com.xyz.widget.FaceView
android:id="@+id/face"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
</com.xyz.ScaleLinearLayout>