最近一到了下午脑袋都是懵的,可能是中午没有休息好吧。反正就是头疼,搞的我整个没有状态。已经立夏了,天气渐渐的热了起来。因为办公室位置的原因,中午以后就属于背阴了,再加上习习的微风,还是感觉有点凉。
今天记录一个比较常见的问题吧,EditText 提示文字和图标都居中显示的问题。这个问题也得需要重写EditText来实现我们的需求。废话不多说,直接上代码。
@SuppressLint("AppCompatCustomView")
public class CenterEdittext extends EditText {
private Context context;
private int drawableIcon; // icon图标
private boolean isShowCenter;//是否居中显示icon,默认为不居中
private boolean isShowLeft;//键盘打开后icon是否显示在左边,默认为不显示icon
private boolean isShowHint;//键盘打开后是否显示提示文字,默认为显示
private boolean isOpen;//是否开启使用,默认为false
private boolean isDraw = true;//是否绘制,配合居中显示使用
private String hintText;
public CenterEdittext(Context context) {
super(context);
this.context = context;
initView(null);
}
public CenterEdittext(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
initView(attrs);
}
public CenterEdittext(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
initView(attrs);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public CenterEdittext(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
this.context = context;
initView(attrs);
}
private void initView(AttributeSet attrs) {
if (attrs != null) {
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CenterEdittext);
isShowCenter = array.getBoolean(R.styleable.CenterEdittext_isCenter, false);
isShowLeft = array.getBoolean(R.styleable.CenterEdittext_isShowLeft, false);
isShowHint = array.getBoolean(R.styleable.CenterEdittext_isShowHint, true);
isOpen = array.getBoolean(R.styleable.CenterEdittext_isOpen, true);
drawableIcon = array.getResourceId(R.styleable.CenterEdittext_drawableIcon, R.drawable.search_black);
array.recycle();
}
// 通过监听软键盘显示还是隐藏来设置提示语
if (context instanceof Activity && isOpen) {
hintText = getHint().toString();
SoftKeyBoardListener.setListener((Activity) context, new SoftKeyBoardListener.OnSoftKeyBoardChangeListener() {
@Override
public void keyBoardShow(int height) {//键盘处于打开状态
setCursorVisible(true);// 显示光标
isDraw = false;//重新绘制(icon居左或者不显示)
if (isShowHint)
setHint(hintText);
else {
if (!TextUtils.isEmpty(hintText))
setHint("");
}
}
@Override
public void keyBoardHide(int height) {//键盘处于关闭状态
setCursorVisible(false);// 隐藏光标
if (TextUtils.isEmpty(getText().toString()))
isDraw = true;
else
isDraw = false;
if (!TextUtils.isEmpty(hintText))
setHint(hintText);
}
});
}
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onDraw(Canvas canvas) {
//如果不启用还使用EditText原来的,否则重新绘制
if (!isOpen) {
super.onDraw(canvas);
return;
}
if (isShowCenter && isDraw) {// 将icon绘制在中间
setCompoundDrawablesWithIntrinsicBounds(context.getResources().getDrawable(drawableIcon), null, null, null);//绘制图片
float textWidth = getPaint().measureText(getHint().toString());//得到文字宽度
int drawablePadding = getCompoundDrawablePadding();//得到drawablePadding宽度
int drawableWidth = context.getResources().getDrawable(drawableIcon).getIntrinsicWidth();//得到图片宽度
float bodyWidth = textWidth + drawableWidth + drawablePadding;//计算距离
canvas.translate((getWidth() - bodyWidth - getPaddingLeft() - getPaddingRight()) / 2, 0);//最终绘制位置
super.onDraw(canvas);
} else {
if (isShowLeft) {
setCompoundDrawablesWithIntrinsicBounds(context.getResources().getDrawable(drawableIcon), null, null, null);
} else {
setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
}
super.onDraw(canvas);
}
}
}
以上就可以实现icon和提示文字居中显示了。
软键盘的代码
public class SoftKeyBoardListener {
private View rootView;//activity的根视图
int rootViewVisibleHeight;//纪录根视图的显示高度
private OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener;
public SoftKeyBoardListener(Activity activity) {
//获取activity的根视图
rootView = activity.getWindow().getDecorView();
//监听视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//获取当前根视图在屏幕上显示的大小
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
int visibleHeight = r.height();
System.out.println("" + visibleHeight);
if (rootViewVisibleHeight == 0) {
rootViewVisibleHeight = visibleHeight;
return;
}
//根视图显示高度没有变化,可以看作软键盘显示/隐藏状态没有改变
if (rootViewVisibleHeight == visibleHeight) {
return;
}
//根视图显示高度变小超过200,可以看作软键盘显示了
if (rootViewVisibleHeight - visibleHeight > 200) {
if (onSoftKeyBoardChangeListener != null) {
onSoftKeyBoardChangeListener.keyBoardShow(rootViewVisibleHeight - visibleHeight);
}
rootViewVisibleHeight = visibleHeight;
return;
}
//根视图显示高度变大超过200,可以看作软键盘隐藏了
if (visibleHeight - rootViewVisibleHeight > 200) {
if (onSoftKeyBoardChangeListener != null) {
onSoftKeyBoardChangeListener.keyBoardHide(visibleHeight - rootViewVisibleHeight);
}
rootViewVisibleHeight = visibleHeight;
return;
}
}
});
}
private void setOnSoftKeyBoardChangeListener(OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) {
this.onSoftKeyBoardChangeListener = onSoftKeyBoardChangeListener;
}
public interface OnSoftKeyBoardChangeListener {
void keyBoardShow(int height);
void keyBoardHide(int height);
}
public static void setListener(Activity activity, OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) {
SoftKeyBoardListener softKeyBoardListener = new SoftKeyBoardListener(activity);
softKeyBoardListener.setOnSoftKeyBoardChangeListener(onSoftKeyBoardChangeListener);
}
}
自定义属性
<declare-styleable name="CenterEdittext">
<attr name="isCenter" format="boolean" />
<attr name="isShowLeft" format="boolean" />
<attr name="isShowHint" format="boolean" />
<attr name="drawableIcon" format="reference" />
<attr name="isOpen" format="boolean" />
</declare-styleable>
不想多说了,直接用就行了。