最近一到了下午腦袋都是懵的乎赴,可能是中午沒(méi)有休息好吧忍法。反正就是頭疼潮尝,搞的我整個(gè)沒(méi)有狀態(tài)。已經(jīng)立夏了饿序,天氣漸漸的熱了起來(lái)勉失。因?yàn)檗k公室位置的原因,中午以后就屬于背陰了原探,再加上習(xí)習(xí)的微風(fēng)乱凿,還是感覺(jué)有點(diǎn)涼。
今天記錄一個(gè)比較常見(jiàn)的問(wèn)題吧咽弦,EditText 提示文字和圖標(biāo)都居中顯示的問(wèn)題告匠。這個(gè)問(wèn)題也得需要重寫(xiě)EditText來(lái)實(shí)現(xiàn)我們的需求。廢話不多說(shuō)离唬,直接上代碼。
@SuppressLint("AppCompatCustomView")
public class CenterEdittext extends EditText {
private Context context;
private int drawableIcon; // icon圖標(biāo)
private boolean isShowCenter;//是否居中顯示icon划鸽,默認(rèn)為不居中
private boolean isShowLeft;//鍵盤(pán)打開(kāi)后icon是否顯示在左邊输莺,默認(rèn)為不顯示icon
private boolean isShowHint;//鍵盤(pán)打開(kāi)后是否顯示提示文字,默認(rèn)為顯示
private boolean isOpen;//是否開(kāi)啟使用,默認(rèn)為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();
}
// 通過(guò)監(jiān)聽(tīng)軟鍵盤(pán)顯示還是隱藏來(lái)設(shè)置提示語(yǔ)
if (context instanceof Activity && isOpen) {
hintText = getHint().toString();
SoftKeyBoardListener.setListener((Activity) context, new SoftKeyBoardListener.OnSoftKeyBoardChangeListener() {
@Override
public void keyBoardShow(int height) {//鍵盤(pán)處于打開(kāi)狀態(tài)
setCursorVisible(true);// 顯示光標(biāo)
isDraw = false;//重新繪制(icon居左或者不顯示)
if (isShowHint)
setHint(hintText);
else {
if (!TextUtils.isEmpty(hintText))
setHint("");
}
}
@Override
public void keyBoardHide(int height) {//鍵盤(pán)處于關(guān)閉狀態(tài)
setCursorVisible(false);// 隱藏光標(biāo)
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原來(lái)的,否則重新繪制
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;//計(jì)算距離
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);
}
}
}
以上就可以實(shí)現(xiàn)icon和提示文字居中顯示了裸诽。
軟鍵盤(pán)的代碼
public class SoftKeyBoardListener {
private View rootView;//activity的根視圖
int rootViewVisibleHeight;//紀(jì)錄根視圖的顯示高度
private OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener;
public SoftKeyBoardListener(Activity activity) {
//獲取activity的根視圖
rootView = activity.getWindow().getDecorView();
//監(jiān)聽(tīng)視圖樹(shù)中全局布局發(fā)生改變或者視圖樹(shù)中的某個(gè)視圖的可視狀態(tài)發(fā)生改變
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//獲取當(dāng)前根視圖在屏幕上顯示的大小
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
int visibleHeight = r.height();
System.out.println("" + visibleHeight);
if (rootViewVisibleHeight == 0) {
rootViewVisibleHeight = visibleHeight;
return;
}
//根視圖顯示高度沒(méi)有變化嫂用,可以看作軟鍵盤(pán)顯示/隱藏狀態(tài)沒(méi)有改變
if (rootViewVisibleHeight == visibleHeight) {
return;
}
//根視圖顯示高度變小超過(guò)200,可以看作軟鍵盤(pán)顯示了
if (rootViewVisibleHeight - visibleHeight > 200) {
if (onSoftKeyBoardChangeListener != null) {
onSoftKeyBoardChangeListener.keyBoardShow(rootViewVisibleHeight - visibleHeight);
}
rootViewVisibleHeight = visibleHeight;
return;
}
//根視圖顯示高度變大超過(guò)200丈冬,可以看作軟鍵盤(pán)隱藏了
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>
不想多說(shuō)了嘱函,直接用就行了。