Android 控件不显示?

 吴小熙1108 发布于 2022-10-28 17:19
问题描述

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

    2022-11-12 01:44 回答
  • 自问自答。。。

    只要在最外层放一个空的全屏的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>
    
    2022-11-12 01:44 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有