場景描述:
ScrollView 的布局超過一個屏幕大小,其中有一個 EditText 在靠近底部的位置,這樣,我們在這個 EditText 上輸入內容時,向上滑動 ScrollView,由于焦點還在這個 EditText 上,所以,會出現我們向上滑動結束后,會自動下滑到這個 EditText 情況。
解決方案:
- API 23 以上有 setOnScrollChangeListener() 可以調用,但是不兼容低版本,我們可以重寫 ScrollView 的 computeScroll()方法,
或者重寫 View 的 onScrollChanged()方法, 設置滑動監聽,來實現對滑動距離的監聽。
- 重寫 computeScroll()
public class MyScrollView extends ScrollView {
private OnScrollListener listener;
/**
* 設置滑動距離監聽器
*/
public void setOnScrollListener(OnScrollListener listener) {
this.listener = listener;
}
public MyScrollView(Context context) {
super(context);
}
public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
// 滑動距離監聽器
public interface OnScrollListener{
/**
* 在滑動的時候調用,scrollY為已滑動的距離
*/
void onScroll(int scrollY);
}
@Override
public void computeScroll() {
super.computeScroll();
if(listener!=null){
listener.onScroll(getScrollY());
}
}
}
- 重寫 onScrollChanged()
public class MyScrollView extends ScrollView {
private OnScrollListener listener;
public void setOnScrollListener(OnScrollListener listener) {
this.listener = listener;
}
public MyScrollView(Context context) {
super(context);
}
public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public interface OnScrollListener{
void onScroll(int scrollY);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if(listener != null){
listener.onScroll(t);
}
}
}
2.有了滑動監聽后,需要知道什么時候清除 EditText 的焦點,我們可以在 這個 EditText 處在屏幕不可見位置時候,去清除焦點。
Point p = new Point();
getWindowManager().getDefaultDisplay().getSize(p);
int screenWidth = p.x;
int screenHeight = p.y;
final Rect rect = new Rect(0, 0, screenWidth, screenHeight);
int[] location = new int[2];
edt_validate_code.getLocationInWindow(location);
scroll_view.setOnScrollListener(new MyScrollView.OnScrollListener() {
@Override
public void onScroll(int scrollY) {
if (edt_validate_code.getLocalVisibleRect(rect)) {
// 控件在屏幕可見區域
} else {
// 控件已不在屏幕可見區域,清除焦點
edt_validate_code.clearFocus();
}
}
});