google-ar / arcore-android-sdk

ARCore SDK for Android Studio
https://developers.google.com/ar
Other
4.95k stars 1.22k forks source link

Manually updating layout view objects in ARCore Android application #805

Closed soudalan closed 3 years ago

soudalan commented 5 years ago

Hi there,

I'm currently running into an issue in an ARCore Android app (this is without sceneform). I have an activity that has a fragment that holds the ARCore session object, as well as the OpenGL ES context tied to the surfaceView, and an external C++ class that uses jni to communicate with the Android app.

I am trying to preserve the state of those objects upon orientation change, but there doesn't seem to be a way to save those objects as parcelables inside the Activity's Bundle for recreation after changing to landscape mode.

Given this, I have resorted to using android:configChanges="orientation|screenSize|keyboardHidden" inside my AndroidManifest.xml file and overriding @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); } inside my Activity.

I have tried calling a method inside onConfigurationChanged() that calls a method inside a View class that updates its layout manually, but this doesn't seem to work.

Basically what I am trying to do is get my ARCore app to preserve all of its state after changing to landscape orientation, but I have several layout view objects in the app that look very different in Portrait versus Landscape mode. Because the activity is no longer recreating itself, it doesn't automatically load the layout files inside my resources/layout or resources/layout-land folders.

As a more thorough example, I have: @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig);

    if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {

fragment.handleOrientationChange(FezConstants.DEVICE_ORIENTATION_PORTRAIT); } }

which calls

public void handleOrientationChange(String orientation) { if (orientation.equals(DEVICE_ORIENTATION_PORTRAIT)) { view.updatePortraitLayout(); } }

which calls

public void updatePortraitLayout() { mPortraitView = inflate(getContext(), R.layout.onboardingPortrait, this); mBrowseView = findViewById(R.id.update_product_view); mCloseView = findViewById(R.id.product_view_close); mPortraitView.requestLayout(); mBrowseView.requestLayout(); }

but this doesn't seem to properly update from the existing landscape view to the new portrait view. Oftentimes when I rotate the phone from portrait to landscape, and I call the related updateLandscapeLayout() method, a view inflates but off the view of the screen. It inflates below the bottom of the screen where I can't see it.

How do I properly manually replace views for portrait and landscape at runtime by overriding onConfigurationChanged()?

devbridie commented 3 years ago

I don't see a problem specific to ARCore here-- perhaps the question is better suited for as a question on the android stackoverflow.