我自定义了一个继承自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(); } } }
这是因为Scroller只是移动了控件的内容(相当于视图)而已,控件的本身并没真的移动。这就好比视图动画,你可以试试使用属性动画,通过改变translationX translationY这些属性来移动。
自问自答。。。
只要在最外层放一个空的全屏的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>