Ali
Ali

Reputation: 22317

replace layout on orientation change

My app has a webview and some buttons inside a LinerLayout.

the problem is, I want the buttons to be on bottom in portrait mode and on left in landscape mode while the webview maintains it's state.

Two different layout doesn't work as it force recreation of the activity that refresh the webview. for now I use android:configChanges="orientation" in activity tag so webview doesn't get refreshed on orientation change.

Is there anyway to replace the layout of buttons on the change of screen mode?

enter image description here

portrait mode

enter image description here

landscape mode

Upvotes: 16

Views: 50488

Answers (7)

H Gh
H Gh

Reputation: 1

Add in the manifest

<activity android:name=".MyActivity"
      android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
      android:label="@string/app_name">

and

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (Resources.getSystem().getDisplayMetrics().widthPixels>
            Resources.getSystem().getDisplayMetrics().heightPixels)
    setContentView(R.layout.activity_layout1);
    else setContentView(R.layout.activity_layout2); 

...

}

and

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);

if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
    setContentView(R.layout.activity_layout1);
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
    setContentView(R.layout.activity_layout2);
}

}

Documents here: https://developer.android.com/guide/topics/resources/runtime-changes.html

Upvotes: 0

Ali
Ali

Reputation: 22317

I tested fragments, but dealing with fragment makes things much more complex and the fragment itself needs saving and restoring which may not work in a webview which has javascript state, So I searched more and find a nice article somewhere and with some modification I came to a solution which I suggest:

First, add android:configChanges="orientation|screenSize|keyboard|keyboardHidden" so the app handles the config changes instead of android.

Make two different layout for landscape and portrait. In both layouts instead of webview place a FrameLayout which acts as a placeholder for the webview.

Define initUI method like this and put everything related to UI initialization in this method:

public void initui()
{
    setContentView(R.layout.main);
    if (wv == null) wv = new WebView(this);
    ((LinearLayout)findViewById(R.id.webviewPlace)).addView(wv);
    findViewById(R.id.home).setOnClickListener(this);
}

If the webview doesn't exist yet it will be created and after setContentView(R.layout.main) it will be added to the layout. Any other UI customization you need came after this.

and in onConfigurationChanged:

@Override
public void onConfigurationChanged(Configuration newConfig)
{
    ((LinearLayout)findViewById(R.id.webviewPlace)).removeAllViews();
    super.onConfigurationChanged(newConfig);
    initUI();
}

In onConfigChange the webview is removed from old placeholder and initui will be called which will add it back to the new layout.

In oncreate() call initui() so the ui will be initialized for the first time.

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    initUI()
}

I wish it would be helpful for someone.

Upvotes: 16

Pratibha Sarode
Pratibha Sarode

Reputation: 1849

If you are using android:configChanges="orientation|screenSize"

In manifest,it ignores the XML in "layout-land". If you create a different XML for landscape don't use the android:configChanges="orientation|screenSize" tag for that activity in manifest.

Upvotes: 13

Amritha Dilip
Amritha Dilip

Reputation: 733

You can add values-(configuration that you require - eg. land,portrait) folder under resources and mention the layout you need for this configuration.. It's as simple as that.

Please checkout the below link for further information- http://developer.android.com/training/multiscreen/screensizes.html#TaskUseAliasFilters

Upvotes: -1

villanuevaquelin
villanuevaquelin

Reputation: 944

Try to use this code:

@Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setContentView(R.layout.activity_splash);
    }

Upvotes: 3

dymmeh
dymmeh

Reputation: 22306

Make your view a relative layout. When the orientation changes just adjust the layout params for each view in code. Have your buttons be contained in a linear layout

As in..

Portrait

LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
buttonLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
buttonLinearLayout.setLayoutParams(lp);


LayoutParams webParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
lp.addRule(RelativeLayout.ABOVE, R.id.buttons);
webView.setLayoutParams(webParams);

Landscape

LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
buttonLinearLayout.setOrientation(LinearLayout.VERTICAL);
buttonLinearLayout.setLayoutParams(lp);


LayoutParams webParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
lp.addRule(RelativeLayout.TO_RIGHT_OF, R.id.buttons);
webView.setLayoutParams(webParams);

Make sure the LayoutParams you are using are the RelativeLayout params (always use the Layoutparams of the view's parent)

Upvotes: 1

wtsang02
wtsang02

Reputation: 18863

put that at layout-land for the layouts you want as landscape.

The idea is, you shouldn't really use configChange="orientation" because it has its downsides. You can find a detailed post here . You should manually handle your state if you want to change your layout. Of course you can programmaiclly do this but if you want to use xml to do this. You can maintain you webView with fragments.

Upvotes: 7

Related Questions