Code Bye

自定义控件滑动被意外中断

 

我自定义了一个WebView,可随着手势往下滑动,完后这个WebView后面还有一个布局,后面的布局很简单,就一个TextView,WebView下滑的时候就能看到这个布局,现在这些功能都实现了,但有一个问题是,我想在WebView下滑到后面的TextView完全出现时改变TextView的文字,结果发现只要一改变这个TextView,我的WebView就自己又滑上去了(手指始终没有离开屏幕),原因未知,代码如下:

布局很简单activity_main.xml(注意这里com.example.testlayout.MyWebView要改成自己的包名)

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" 
        android:gravity="center_horizontal">

        <TextView
            android:id="@+id/hint"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingTop="20dp"
            android:text="下拉刷新"
            />
    </LinearLayout>

    <com.example.testlayout.MyWebView
        android:id="@+id/web_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

主类MainActivity.java

public class MainActivity extends Activity {
	MyWebView web;
	TextView hint;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		hint = (TextView) findViewById(R.id.hint);
		web = (MyWebView) findViewById(R.id.web_view);

		initView();
	}

	private void initView() {
		ViewTreeObserver vto = hint.getViewTreeObserver();
		vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
			@Override
			public void onGlobalLayout() {
				hint.getViewTreeObserver().removeGlobalOnLayoutListener(this);
				web.setLayoutBottom(hint.getBottom());
			}
		});

		WebSettings webSettings = web.getSettings();
		webSettings.setJavaScriptEnabled(true);
		web.setWebViewClient(new WebViewClient() {
			public boolean shouldOverrideUrlLoading(WebView view, String url) { // 重写此方法表明点击网页里面的链接还是在当前的webview里跳转,不跳到浏览器那边
				view.loadUrl(url);
				return true;
			}
		});
		web.loadUrl("https://www.baidu.com");

		web.setScrollListener(new ScrollListener() {

			@Override
			public void pullDownRefresh() {
				hint.setText("下拉刷新");
			}

			@Override
			public void looseRefresh() {
				hint.setText("松开刷新");
			}
		});
	}

}

自定义WebView,MyWebView.java

public class MyWebView extends WebView {
	private float preY; // 之前的Y坐标
	private float nowY; // 现在的Y坐标
	private float distance; // 手势滑动距离
	private int right; // WebView右边坐标
	private int bottom; // WebView底部坐标
	private int backBottom; // 隐藏在WebView后面的布局的bottom
	private ScrollListener scrollListener; // 自定义监听接口
	private int PULL_DOWN_STATUS = 0; // 下拉状态
	private int LOOSE_REFRESH_STATUS = 1; // 松手刷新状态
	private int status = PULL_DOWN_STATUS; // 当前状态

	public MyWebView(Context context, AttributeSet attrs) {
		super(context, attrs);

		ViewTreeObserver vto = getViewTreeObserver();
		vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
			@Override
			public void onGlobalLayout() {
				getViewTreeObserver().removeGlobalOnLayoutListener(this);

				right = getRight();
				bottom = getBottom();
			}
		});
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			preY = event.getY();
			break;

		case MotionEvent.ACTION_MOVE:
			nowY = event.getY() + getTop(); 
			distance = (nowY - preY) / 2; // 这里只滑动手势滑动距离的1/2,给用户一种下拉困难的感觉,不允许用户全部拉下去
			preY = nowY;

			if (getScrollY() == 0) { // WebView内部的内容在顶部的时候(注:不是WebView控件本身)才需要响应手势的下滑
				if (getTop() != 0 || distance >= 0) { // WebView控件本身不在顶部或者是手势向下滑动时,响应手势

					if (scrollListener != null && backBottom != 0) {
						if (status == PULL_DOWN_STATUS && getTop() > backBottom) { // 下滑到文字完全出现,改变文字和状态
							status = LOOSE_REFRESH_STATUS;
							scrollListener.looseRefresh();
						} else if (status == LOOSE_REFRESH_STATUS && getTop() < backBottom){  // 上滑到文字慢慢消失,改变文字和状态
							status = PULL_DOWN_STATUS;
							scrollListener.pullDownRefresh();
						}
					}

					layout(0, getTop() + (int) distance, right, getBottom()
							+ (int) distance);

					return true;
				}
			}

			break;

		case MotionEvent.ACTION_UP:
			TranslateAnimation ta = new TranslateAnimation(0, 0, getTop()
					+ (int) distance, 0);
			ta.setDuration(200);
			startAnimation(ta);
			layout(0, 0, right, bottom);

			break;
		}
		// TODO Auto-generated method stub
		return super.onTouchEvent(event);
	}

	public void setLayoutBottom(int backBottom) {
		this.backBottom = backBottom;
	}

	public void setScrollListener(ScrollListener scrollListener) {
		this.scrollListener = scrollListener;
	}

	public interface ScrollListener {
		public void pullDownRefresh(); // 下拉刷新
		public void looseRefresh(); // 松开刷新
	}
}

最后再AndroidManifest.xml里面加上权限<uses-permission android:name=”android.permission.INTERNET” />就OK了

PS:我尝试过很多方法,将改变文字放到handler里面,或者实现onLayout方法等等,均不行,忘高手指点

100分
更新textview时整个页面失效了?
引用 1 楼 u013280307 的回复:

更新textview时整个页面失效了?

是的,我解决了,将布局中的WebView再包一层LinearLayout就行了,但具体原因我不知道

。。。因为更新TextView时整个页面失效的。。。。。。invalidate();方法。。。。
你加上linerlayout就不会那样了。。。。。这是更新UI的问题
没人回答,就给你吧

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明自定义控件滑动被意外中断