ScrollView嵌套EditText联带滑动的解决办法
Posted that-jay
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ScrollView嵌套EditText联带滑动的解决办法相关的知识,希望对你有一定的参考价值。
解决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();
以上是关于ScrollView嵌套EditText联带滑动的解决办法的主要内容,如果未能解决你的问题,请参考以下文章