这两天遇到这样一个问题,一个布局外层是一个Scrollview,里面有一个EditText,Edittext的高度是固定的,当用户输入足够多的内容后,Edittext就会展示不全,可是不管怎么滑动,都是外层的Scrollview在滑动,Edittext里面的文字却怎么都不能滑动,我也知道是抢夺焦点,事件冲突的问题,事件冲突说起来很容易,可是真正要解决的时候就不是像说的那么容易了。一直想着自己独立解决的,可是最后还是百度,Google了,然后就找到了一篇blog http://blog.csdn.net/yigelangmandeshiren/article/details/12168877 就是这一篇,基本实现了我的功能,但是我还是稍微修改了,我想要的效果是,如果输入的内容比较少的时候,在Edittext区域滑动,还是Scrollview在动,如果输入的内容比较多,那么应该是文字滑动,而不是Scrollview在动,而且blog 是用的是再定义一个Scrollview,我觉得没必要,定义一个Linearlayout就可以了,不定义Scrollview的原因很简单,如果要定义一个Scrollview,那么Edittext就需要再包裹一层,大家都知道,没嵌套一层,性能相应的就会降低一些,所以我定义了一个LinearLayout,源码如下:
public class MyLinearLayout extends LinearLayout { private ScrollView parentScrollview; private EditText editText; private int showLineMax = 0; public void setParentScrollview(ScrollView parentScrollview) { this.parentScrollview = parentScrollview; } public void setEditeText(EditText editText) { this.editText = editText; MyLinearLayout.LayoutParams lp = (MyLinearLayout.LayoutParams) editText.getLayoutParams(); showLineMax = lp.height / editText.getLineHeight(); } public MyLinearLayout(Context context) { super(context); } public MyLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (parentScrollview == null) { return super.onInterceptTouchEvent(ev); } else { if (ev.getAction() == MotionEvent.ACTION_DOWN && editText.getLineCount() >= showLineMax) { // 将父scrollview的滚动事件拦截 setParentScrollAble(false); } else if (ev.getAction() == MotionEvent.ACTION_UP) { // 把滚动事件恢复给父Scrollview setParentScrollAble(true); } } return super.onInterceptTouchEvent(ev); } /** * 是否把滚动事件交给父scrollview * * @param flag */ private void setParentScrollAble(boolean flag) { parentScrollview.requestDisallowInterceptTouchEvent(!flag); } }和那篇blog 不一样的是,我里面有一个Edittext变量,主要是为了计算Edittext能展示几行,从而进行滚动事件是自己用还是交给Scrollview,
而布局文件中,其实很简单,源码如下:
<ScrollView android:id="@+id/sv" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:fadingEdge="none" android:scrollbars="none"> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <com.hoyouly.dispathcertouchdemo.MyLinearLayout android:id="@+id/se" android:layout_width="fill_parent" android:layout_height="100dip" android:layout_gravity="center" android:layout_marginBottom="500dp" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:layout_marginTop="500dp" android:fadingEdge="none" android:scrollbars="none" android:visibility="visible"> <EditText android:id="@+id/et" android:layout_width="match_parent" android:layout_height="100dp" android:hint="输入内容" android:textColor="#FF0000" android:textSize="20sp"/> </com.hoyouly.dispathcertouchdemo.MyLinearLayout> </LinearLayout> <TextView android:layout_width="match_parent" android:layout_height="50dp" android:layout_marginBottom="50dp" android:text="这是个底部" android:textSize="30dp"/> </LinearLayout> </LinearLayout> </ScrollView>
因为我们代码中Edittext和Scrollview中间隔了好几层,所以我就试了试多嵌套几层,发现也是可以的。
至于MainActivity 中,就更加简单了
public class MainActivity extends Activity { private ScrollView sv; private EditText et; private MyLinearLayout se; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_other); sv = (ScrollView) findViewById(R.id.sv); et = (EditText) findViewById(R.id.et); se = (MyLinearLayout) findViewById(R.id.se); se.setParentScrollview(sv); se.setEditeText(et); } }就是几个初始化,然后设置Scrollview和Edittext,这样就能实现Scrollview和Edittext滑动不冲突的问题了
源码地址:https://github.com/hoyouly/DispathcerTouchDemo