我自定义了一个继承自RelativeLayout的布局,效果是向右滑动后,内部的控件会向右移出屏幕。左划后又移回屏幕。
现在的情况是,内部控件右划移出屏幕后,把应用切换回后台,再切换到前台,然后左划把内部控件移回屏幕,这时这些内部控件会不显示,但是它们的确存在在那里,并可以接收点击效果,点击后就会显示出来。
现在想要的效果是从回台回来后,把内部控件拖动回屏幕后,直接显示。应该需要怎么实现?我试过用invalidate()刷新,可是不起作用。
package com.leu.textapplication;
import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.RelativeLayout;
import android.widget.Scroller;
/**
* Created by Leu on 2016/10/8.
*/
public class ScrollRelativeLayout extends RelativeLayout implements View.OnTouchListener {
private Scroller mScroller;
private int mScreenWitdh;
//0表示隐藏,1表示显示
private int beginX;
private int distanceX;
private GestureDetector mGestureDetector;
public ScrollRelativeLayout(Context context) {
super(context);
initView(context);
}
public ScrollRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public ScrollRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
private void initView(Context context) {
//setFocusable(true);
//requestFocus();
//this.setLongClickable(true);
this.setOnTouchListener(this);
//setFocusable(true);
setDescendantFocusability(FOCUS_BEFORE_DESCENDANTS);
mScroller = new Scroller(context);
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
mScreenWitdh = outMetrics.widthPixels;
mGestureDetector = new GestureDetector(context, new SimpleGestureListener());
mGestureDetector.setIsLongpressEnabled(true);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
beginX = (int) event.getX();
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
Log.d("ScrollRelativeLayout", "执行up");
Log.d("ScrollRelativeLayout", "distanceX:" + distanceX);
distanceX = (int) event.getX() - beginX;
//右划
if (distanceX > 0) {
//右划超过固定距离
if (distanceX > 200) {
scrollRight();
//右划未超过固定距离
} else {
scrollLeft();
}
//左划
} else if(distanceX<0){
//左划超过固定距离
if (distanceX < -200) {
scrollLeft();
//左划未超过固定距离
} else {
scrollRight();
}
}
//通知View进行重绘,从而调用computeScroll的模拟过程
invalidate();
break;
}
return true;
}
private class SimpleGestureListener extends
GestureDetector.SimpleOnGestureListener {
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
//在主屏幕时,才能进行拖动。
if (getScrollX() + distanceX <= 0 && getScrollX() + distanceX > -mScreenWitdh) {
scrollBy((int) distanceX, 0);
}
return false;
}
//当执行onFling后,onTouchEvent的up动作不会再执行。
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
Log.d("ScrollRelativeLayout", "执行fling");
if (e1.getX() - e2.getX() > 0 && getScrollX() <= 0 && getScrollX() > -mScreenWitdh) {
//左划
scrollLeft();
} else if (e2.getX() - e1.getX() > 0 && getScrollX() <= 0 && getScrollX() > -mScreenWitdh) {
//右划
scrollRight();
}
invalidate();
return true;
}
}
/**
* 左划进屏幕
*/
private void scrollLeft() {
mScroller.startScroll(
getScrollX(),
0,
-getScrollX(),
0);
}
/**
* 右划出屏幕
*/
private void scrollRight() {
mScroller.startScroll(
getScrollX(),
0,
-(mScreenWitdh + getScrollX()),
0);
}
/**
* 重写computeScroll方法,实现模拟滑动
* 系统在绘制View的时候会在draw方法中调用该方法
*/
@Override
public void computeScroll() {
super.computeScroll();
// 判断Scroller是否执行完毕,是否完成了整个滑动
//当模拟过程结束后,该方法会返回false,从而中断循环,完成整个平滑移动过程。
if (mScroller.computeScrollOffset()) {
//通过不断地瞬间移动一个小的距离来实现整体上的平滑移动效果
scrollTo(
mScroller.getCurrX(),//获得当前的滑动坐标
mScroller.getCurrY());
// 通过重绘来不断调用computeScroll,通过invalidate→draw→computeScroll来间接调用。
invalidate();
}
}
}
伊谢尔伦2017-04-17 17:49:47
自问自答。。。
只要在最外层放一个空的全屏的View就解决这个问题了。。。不知道什么原理
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fresco="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
>
<SurfaceView
android:id="@+id/id_surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<com.niurenhuiji.app.view.ScrollRelativeLayout
android:id="@+id/id_rLayout_cover"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<WebView
android:id="@+id/id_webview"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="52dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="@android:color/transparent"
android:layerType="software"
/>
<include layout="@layout/live_top"/>
<include layout="@layout/live_editlayout"/>
<include layout="@layout/live_bottom"/>
</com.niurenhuiji.app.view.ScrollRelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
迷茫2017-04-17 17:49:47
这是因为Scroller只是移动了控件的内容(相当于视图)而已,控件的本身并没真的移动。这就好比视图动画,你可以试试使用属性动画,通过改变translationX translationY这些属性来移动。