replace layout on orientation change
Asked Answered
H

7

16

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

Howze answered 12/12, 2012 at 20:57 Comment(0)
H
16

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.

Howze answered 18/12, 2012 at 17:7 Comment(1)
It's not working properly. it restarts the oncreate methodMucro
I
13

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.

Insatiable answered 11/1, 2016 at 5:27 Comment(1)
what needs to be used when we have layout-land in the project?Shivaree
K
7

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.

Katherinkatherina answered 12/12, 2012 at 20:59 Comment(3)
I said, that doesn't work. It recreates the view and refresh the webview. android:configChanges="orientation" prevents this behavior.Howze
I read about fragments, but have no idea how it really works! does it work in android 2.2?Howze
Using supportv4 library, yes. In many real life applications fragments are used. Its up to you when to learn about it. The other solution will help you and it doesn't need fragments. But if you want to learn about fragments, you can see the template in NewProject>MasterDetailedFlow OR Viewpager templates.Katherinkatherina
I
3

Try to use this code:

@Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setContentView(R.layout.activity_splash);
    }
Inveterate answered 31/3, 2014 at 16:49 Comment(1)
this will remove all the listeners that are set to the activity , is there any way to recover them ?Stoichiometric
A
1

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)

Arabist answered 12/12, 2012 at 21:12 Comment(0)
C
0

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

Caves answered 24/8, 2021 at 13:7 Comment(0)
S
-1

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

Stauder answered 11/9, 2014 at 5:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.