您的位置:首页 > 其它

关于Scrollview和EditText 滑动冲突的解决办法

2016-03-26 14:23 381 查看
这两天遇到这样一个问题,一个布局外层是一个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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: