【问题标题】:Surfaceview get squeeze after resuming applicationSurfaceview 恢复应用后被挤压
【发布时间】:2019-08-14 14:24:47
【问题描述】:

一开始,一切都运行良好且流畅,但一旦我将应用程序置于后台并再次恢复它,我的表面视图就会被挤压。我正在使用表面视图在后台播放视频,然后使用框架布局绘制一些点来实现一些逻辑。我调试并发现每次我恢复应用程序时,我的表面视图类的 lp.width 都会改变。

那里的任何人都可以对此有所了解吗?将不胜感激!!!

我什至尝试在 LinearLayout 中动态添加表面视图,但这也不能解决我的问题。

我尝试的第二件事是创建一个接口并调用我的 customSurfaceView 类的 init 函数,但一点运气都没有。

下面是我的 XML、MainActivity 和 CustomSurfaceView 类代码:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/home_container"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <com.example.myapplication.CustomSurfaceView
        android:id="@+id/surface"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
    />
</FrameLayout>

MainActivity 类

public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
private MyDrawingView drawingView;
private DisplayMetrics metrics;
//private LinearLayout mlLinearLayout;
//private CustomSurfaceView mCustomSurfaceView;
private ImageView mImageView;
FrameLayout frameLayout;
    Singleton singleton;
    private int j;
private ArrayList<String> list ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         singleton = new Singleton();
        list = new ArrayList<String>();
    }

    @Override
    protected void onResume() {
        super.onResume();
        singleton.getmPlayAgain().playvideo();
    } 
}

CustomSurfaceView 类:

public class CustomSurfaceView extends SurfaceView implements SurfaceHolder.Callback,PlayAgain {

    private static final String TAG = "INTRO_SF_VIDEO_CALLBACK";
    private MediaPlayer mp;
    private  Context mContext;

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public CustomSurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context);
    }

    public CustomSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }
    public CustomSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public CustomSurfaceView(Context context) {
        super(context);
        init(context);
    }

    private void init (Context context){
        mContext = context;
        Singleton singleton = new Singleton();
        singleton.setmPlayAgain(this);

        mp = new MediaPlayer();
        getHolder().addCallback(this);
    }
    public static String getDeviceDensity(Context context){
        String deviceDensity = "";
        switch (context.getResources().getDisplayMetrics().densityDpi) {
            case DisplayMetrics.DENSITY_LOW:
                deviceDensity =  0.75 + " ldpi";
                Toast.makeText(context,deviceDensity,Toast.LENGTH_LONG).show();
                break;
            case DisplayMetrics.DENSITY_MEDIUM:
                deviceDensity =  1.0 + " mdpi";
                Toast.makeText(context,deviceDensity,Toast.LENGTH_LONG).show();
                break;
            case DisplayMetrics.DENSITY_HIGH:
                deviceDensity =  1.5 + " hdpi";
                Toast.makeText(context,deviceDensity,Toast.LENGTH_LONG).show();
                break;
            case DisplayMetrics.DENSITY_XHIGH:
                deviceDensity =  2.0 + " xhdpi";
                Toast.makeText(context,deviceDensity,Toast.LENGTH_LONG).show();
                break;
            case DisplayMetrics.DENSITY_XXHIGH:
                deviceDensity =  3.0 + " xxhdpi";
                Toast.makeText(context,deviceDensity,Toast.LENGTH_LONG).show();
                break;
            case DisplayMetrics.DENSITY_XXXHIGH:
                deviceDensity =  4.0 + " xxxhdpi";
                Toast.makeText(context,deviceDensity,Toast.LENGTH_LONG).show();
                break;
            default:
                deviceDensity = "Not found";
        }
        return deviceDensity;
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.sq);
        try {
            mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
            mp.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
        int videoWidth = mp.getVideoWidth();
        int videoHeight = mp.getVideoHeight();
        android.view.ViewGroup.LayoutParams lp = getLayoutParams();
        if(getDeviceDensity(mContext).equalsIgnoreCase(3.0 + " xxhdpi")){
            lp.height = videoHeight;
            lp.width = videoWidth;
        }else if(getDeviceDensity(mContext).equalsIgnoreCase(2.0 + " xhdpi")){
            lp.height = (int)(videoHeight * .72);
            lp.width = (int) (((float)videoWidth / (float)videoHeight) * (float)getHeight() * 0.58);
        }else if(getDeviceDensity(mContext).equalsIgnoreCase("Not found")){

            lp.height = (int)(videoHeight * .7);
            lp.width = (int) (((float)videoWidth / (float)videoHeight) * (float)getHeight() * 0.52);
//            Toast.makeText(mContext, "inside"+lp.height + " "+lp.width, Toast.LENGTH_LONG).show();
        }else if(getDeviceDensity(mContext).equalsIgnoreCase(1.5 + " hdpi")){
            lp.height = (int)(videoHeight * .48);
            lp.width = (int) (((float)videoWidth / (float)videoHeight) * (float)getHeight() * 0.8);
        }




        setLayoutParams(lp);
        mp.setDisplay(getHolder());
        mp.setLooping(true);
        mp.start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mp.stop();
    }

    @Override
    public void playvideo() {
        if(!mp.isPlaying()){
            Toast.makeText(mContext, "inside", Toast.LENGTH_LONG).show();
            init(mContext);
        }

    }
}

应用程序从后台恢复到前台后,预期的 Surfaceview 不应受到挤压。

请让我知道我做错了什么

【问题讨论】:

    标签: android surfaceview android-framelayout


    【解决方案1】:

    “我调试并发现每次我恢复应用程序时,我的表面视图类的 lp.width 都会改变”

    这一定会发生,因为您在 surfaceCreated 回调中计算 lp.width。当您的应用程序的新实例被创建时,“surfaceCreated”被调用,然后您的应用程序进入后台(但仍在内存中,未销毁),然后您的应用程序再次进入前台。此时,您的表面不会获得 surfaceCreated 调用。

    你需要在surfaceChanged中计算维度,每次你的surface改变大小时都会调用它

     @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        // compute dimensions here
    }
    

    【讨论】:

    • 建议你再过一遍activity生命周期
    • surfaceChanged 方法甚至在我每次从后台恢复应用程序时都会被调用
    • 问题是 git getHeight 函数,所以我用 displayMetrics.heightPixels 替换了它,一切都开始正常了
    • displayMetrics.heightPixels 为您提供以像素为单位的绝对显示高度。目前您在布局文件中使用“match_parent”,所以一切正常,现在如果您需要更改自定义高度,那么您的代码将再次中断。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-23
    • 2015-08-19
    • 2012-07-08
    • 2018-02-06
    • 2020-10-15
    • 1970-01-01
    相关资源
    最近更新 更多