最近在开发中遇到在ScrollView包含EditText输入框时ScrollView数据变化引起的ScrollView自动滑动到焦点EditText出的问题,解决方法如下:
sv= (ScrollView) findViewById(R.id.sv);
sv.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
sv.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
v.requestFocusFromTouch();
return false;
}
});
解释:
ViewGroup的setDescendantFocusability(int focusability)方法入下,看注释大致意思是:
* 设置了viewgroup中字视图的可聚焦性,定义了viewgroup与子view的关系
* 方便在requestFocus方法中找到那个view有焦点,参数有三个值
* FOCUS_BEFORE_DESCENDANTS 先viewgroup获取焦点,在viewgroup没有之后子view再去获取
*FOCUS_AFTER_DESCENDANTS 子view先获取焦点,子view无焦点后再viewgroup去获取
*FOCUS_BLOCK_DESCENDANTS viewgroup拦截焦点,子view取不到焦点
/**
* Set the descendant focusability of this view group. This defines the relationship
* between this view group and its descendants when looking for a view to
* take focus in {@link #requestFocus(int, android.graphics.Rect)}.
*
* @param focusability one of {@link #FOCUS_BEFORE_DESCENDANTS}, {@link #FOCUS_AFTER_DESCENDANTS},
* {@link #FOCUS_BLOCK_DESCENDANTS}.
*/
public void setDescendantFocusability(int focusability) {
switch (focusability) {
case FOCUS_BEFORE_DESCENDANTS:
case FOCUS_AFTER_DESCENDANTS:
case FOCUS_BLOCK_DESCENDANTS:
break;
default:
throw new IllegalArgumentException("must be one of FOCUS_BEFORE_DESCENDANTS, "
+ "FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS");
}
mGroupFlags &= ~FLAG_MASK_FOCUSABILITY;
mGroupFlags |= (focusability & FLAG_MASK_FOCUSABILITY);
}
咱们看ScrollView的初始化方法,可以看到默认设置为FOCUS_AFTER_DESCENDANTS了,如下:
private void initScrollView() {
mScroller = new OverScroller(getContext());
setFocusable(true);
//这里设置为FOCUS_AFTER_DESCENDANTS
setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
setWillNotDraw(false);
final ViewConfiguration configuration = ViewConfiguration.get(mContext);
mTouchSlop = configuration.getScaledTouchSlop();
mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
mOverscrollDistance = configuration.getScaledOverscrollDistance();
mOverflingDistance = configuration.getScaledOverflingDistance();
}