android:gravity="center_horizontal"的EditText为什么设置了adjustPan之后不能调整View的位置。
今天遇到一个问题,当这个edittext同时设置 android:gravity="center_horizontal" android:singleLine="true"这两个属性时会导致当 edittext第二次呼出输入法的时候,整个window不能adjust..
1》先附上 TestDemo的Layout如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="bottom"
android:orientation="vertical">
<EditText
android:id="@+id/folder_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="12341234"
android:gravity="center_horizontal"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"/>
</LinearLayout>
2》解答:这个问题经过分析是android4.4 TextView的一个共性的bug.
center_horizontal的TextView的宽度在计算时得到了一个超大的数,详见下述方法的最后一个else.
public float getLineRight(int line) {
int dir = getParagraphDirection(line);
Alignment align = getParagraphAlignment(line);
if (align == Alignment.ALIGN_LEFT) {
return getParagraphLeft(line) + getLineMax(line);
} else if (align == Alignment.ALIGN_NORMAL) {
if (dir == DIR_RIGHT_TO_LEFT)
return mWidth;
else
return getParagraphLeft(line) + getLineMax(line);
} else if (align == Alignment.ALIGN_RIGHT) {
return mWidth;
} else if (align == Alignment.ALIGN_OPPOSITE) {
if (dir == DIR_RIGHT_TO_LEFT)
return getLineMax(line);
else
return mWidth;
} else { /* align == Alignment.ALIGN_CENTER */
int left = getParagraphLeft(line);
int right = getParagraphRight(line);
int max = ((int) getLineMax(line)) & ~1;
return right - ((right - left) - max) / 2;
}
}
而ViewRootImpl在呼出输入法需要findFocus对应的TextView,然后TextView在计算需要偏移的Rect的时候(getFocusedRect)失败。。(详见下述方法)
@Override
public void getFocusedRect(Rect r) {
if (mLayout == null) {
super.getFocusedRect(r);
return;
}
int selEnd = getSelectionEnd();
if (selEnd < 0) {
super.getFocusedRect(r);
return;
}
int selStart = getSelectionStart();
if (selStart < 0 || selStart >= selEnd) {
int line = mLayout.getLineForOffset(selEnd);
r.top = mLayout.getLineTop(line);
r.bottom = mLayout.getLineBottom(line);
r.left = (int) mLayout.getPrimaryHorizontal(selEnd) - 2;
r.right = r.left + 4;
} else {
int lineStart = mLayout.getLineForOffset(selStart);
int lineEnd = mLayout.getLineForOffset(selEnd);
r.top = mLayout.getLineTop(lineStart);
r.bottom = mLayout.getLineBottom(lineEnd);
if (lineStart == lineEnd) {
r.left = (int) mLayout.getPrimaryHorizontal(selStart);
r.right = (int) mLayout.getPrimaryHorizontal(selEnd);
} else {
// Selection extends across multiple lines -- make the focused
// rect cover the entire width.
if (mHighlightPathBogus) {
if (mHighlightPath == null) mHighlightPath = new Path();
mHighlightPath.reset();
mLayout.getSelectionPath(selStart, selEnd, mHighlightPath);
mHighlightPathBogus = false;
}
synchronized (TEMP_RECTF) {
mHighlightPath.computeBounds(TEMP_RECTF, true);
r.left = (int)TEMP_RECTF.left-1;
r.right = (int)TEMP_RECTF.right+1;
}
}
}
// Adjust for padding and gravity.
int paddingLeft = getCompoundPaddingLeft();
int paddingTop = getExtendedPaddingTop();
if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) != Gravity.TOP) {
paddingTop += getVerticalOffset(false);
}
r.offset(paddingLeft, paddingTop);
int paddingBottom = getExtendedPaddingBottom();
r.bottom += paddingBottom;
}