解决ScrollView嵌套EditText的滑动事件,并且实现它们两者之间的联带滑动。什么是联带滑动呢,就是当EditText滑动到底部的时候,这时就应该让外部的ScrollView跟着滑动,好让它们之间完成连贯的滑动事件。先来看看效果把。
网上没找到完整实现的例子,只好自己撸demo了。
代码里有注释,全部代码如下:
package chn.fz.thatjay.scrolleditview.view; import android.content.Context; import android.content.res.TypedArray; import android.text.Layout; import android.util.AttributeSet; import android.support.v7.widget.AppCompatEditText; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.RelativeLayout; import chn.fz.thatjay.scrolleditview.R; public class ScrollMulrowsEditText extends AppCompatEditText { private final String TAG = "ScMulrowsEditText"; //滑动距离的最大边界 private int mOffsetHeight; private int mHeight; private int mVert = 0; public ScrollMulrowsEditText(Context context) { super(context); } public ScrollMulrowsEditText(Context context, AttributeSet attrs) { super(context, attrs); initAttribute(context, attrs, 0); } public ScrollMulrowsEditText(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initAttribute(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int paddingTop; int paddingBottom; int height; int mLayoutHeight; //获得内容面板 Layout mLayout = getLayout(); //获得内容面板的高度 mLayoutHeight = mLayout.getHeight(); //获取上内边距 paddingTop = getTotalPaddingTop(); //获取下内边距 paddingBottom = getTotalPaddingBottom(); //获得控件的实际高度 height = mHeight; // getHeight()第一次得到0,所以最好从外部指定设置值 //计算滑动距离的边界 mOffsetHeight 当内容少,没有滚动条时候,值为0 mOffsetHeight = mLayoutHeight + paddingTop + paddingBottom - height; setOnTouchListener(); if(getId() == R.id.edittext2) { Log.d(TAG, "ffffaaaa onMeasure == " + mOffsetHeight); } } private void initAttribute(Context context, AttributeSet attrs, int defStyleAttr) { TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ScrollMulrowsEditText, defStyleAttr, 0); int count = array.getIndexCount(); for (int i = 0; i < count; i++) { int attr = array.getIndex(i); switch (attr) { case R.styleable.ScrollMulrowsEditText_sc_mul_edit_height: mHeight = array.getDimensionPixelSize(attr, 0); break; } } array.recycle(); } @Override protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) { super.onScrollChanged(horiz, vert, oldHoriz, oldVert); mVert = vert; if(getId() == R.id.edittext2){ Log.d(TAG,"ffffaaaa mOffsetHeight == " + mOffsetHeight + " ,, vert === " + vert ); } if (vert == mOffsetHeight || vert == 0) { //这里触发父布局或祖父布局的滑动事件 getParent().requestDisallowInterceptTouchEvent(false); Log.d(TAG, "vert requestDisallowInterceptTouchEvent false "); } } //滑动到上边缘 public boolean isUpperEdge(){ return mVert == 0; } //滑动到下边缘 public boolean isLowerEdge(){ return mVert == mOffsetHeight; } private float scrollBeginY; public void setOnTouchListener(){ setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { //canScrollVertically()方法为判断指定方向上是否可以滚动,参数为正数或负数,负数检查向上是否可以滚动,正数为检查向下是否可以滚动 if(MotionEvent.ACTION_DOWN == event.getAction()){ scrollBeginY = event.getY(); v.getParent().requestDisallowInterceptTouchEvent(true);//要求父类布局不在拦截触摸事件 return false; } Log.d(TAG, "event.getY" + event.getY());//edittext 如果在最边缘,getY得到的也不是固定的值 if(canScrollVertically(1)){//可以向下滚动 if(isUpperEdge() && event.getY() >= scrollBeginY){//已经在上边缘,向下手势滑动 v.getParent().requestDisallowInterceptTouchEvent(false);//交给父布局 } else { v.getParent().requestDisallowInterceptTouchEvent(true); } } else if(canScrollVertically(-1)){//可以向上滚动 if(isLowerEdge() && event.getY() <= scrollBeginY){//已经在下边缘,向上手势滑动 v.getParent().requestDisallowInterceptTouchEvent(false);//交给父布局 } else { v.getParent().requestDisallowInterceptTouchEvent(true); } } else { v.getParent().requestDisallowInterceptTouchEvent(false);//交给父布局 } //getY 手机屏幕上边 getY 值小 //getY 手机屏幕下边 getY 值大 return false; } }); } }
activity代码,下面是ImmersionBar的第三方库,用来监听输入法键盘消失的时候,让edittext失去焦点,否则edittext光标一直在,很难看。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initStatusBar(edittext1, edittext2, edittext3, edittext4, edittext5); } public void initStatusBar(final EditText... ets){ ImmersionBar.with(this) .fitsSystemWindows(true) .statusBarColor(R.color.color1) .keyboardEnable(true) .setOnKeyboardListener(new OnKeyboardListener() { @Override public void onKeyboardChange(boolean isPopup, int keyboardHeight) { if (!isPopup) { for (EditText et:ets ) { et.clearFocus(); } } } }) .init(); }
原文地址:https://www.cnblogs.com/that-jay/p/11487535.html
时间: 2024-10-09 01:45:50