简体   繁体   中英

Surfaceview get squeeze after resuming application

At the very first time, everything works fine and smooth but as soon as I take the application in the background and resume it again my surface view gets squeezed. I am playing a video in the background using surface view and then using frame layout drawing some points to implement some logic. I debugged and found that every time I resume the application my lp.width of surface view class get changed.

Can anyone out there can put some light on it? It would be greatly appreciated!!!

I even tried by adding surface view dynamically inside LinearLayout but that also does not solve my problem.

The second thing I tried I create an interface and call the init function of my customSurfaceView class but no luck at all.

Bellow is my XML, MainActivity and CustomSurfaceView class code:

<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 class

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 Class :

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);
        }

    }
}

Expected Surfaceview should not get squeeze after resuming application from background to foreground.

Please let me know what I am doing wrong in this

" I debugged and found that every time I resume the application my lp.width of surface view class get changed"

This is bound to happen because you are computing lp.width in surfaceCreated callback. When new instance of your app is created "surfaceCreated" is called, then your app goes into background(but still in memory, not destroyed) and then your app comes to foreground again. At that point your surface doesn't get surfaceCreated call.

You need to compute dimension in surfaceChanged, which gets called every time your surface changes size

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM