persian Developer persian Developer - 5 months ago 12
Android Question

defined xml layout in layout-land does not appear in android application

I am developing an application according to this example. I defined a landscape layout for header.xml in a layout-land folder, but when I change the orientation to landscape, defined layout does not appear in the screen.

Do know Why ?

Thanks

Updated :

Activity Code :

public class ACENewsFeedActivity extends ListActivity {

// Progress Dialog
private ProgressDialog pDialog;

// Array list for list view
ArrayList<HashMap<String, String>> rssItemList = new ArrayList<HashMap<String,String>>();

RSSParser rssParser = new RSSParser();

List<RSSItem> rssItems = new ArrayList<RSSItem>();

RssFeed rssFeed;

private static String TAG_TITLE = "title";
private static String TAG_LINK = "link";
private static String TAG_DESRIPTION = "description";
private static String TAG_PUB_DATE = "pubDate";
//private static String TAG_GUID = "guid"; // not used

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rss_item_list);

/**
* Calling a backgroung thread will loads recent articles of a website
* @param rss url of website
* */
new loadRSSFeedItems().execute();
}

....
}


XMl Layout in landscape mode :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layoutHeader"
android:layout_width="fill_parent"
android:layout_height="50dip"
android:layout_alignParentTop="true"
android:background="@layout/header_gradient"
android:orientation="horizontal">

<!-- Logo -->

<!-- Refresh -->


<!-- Plus Button -->

<ImageButton
android:id="@+id/btnAddSite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="5dip"
android:background="@null"
android:src="@drawable/plus"
android:layout_centerVertical="true" />

<ImageView
android:id="@+id/logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:src="@drawable/logo" />

<ImageView
android:id="@+id/refreshList"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:src="@drawable/refresh" />

</RelativeLayout>

Answer

Android allows you to provide different versions of resource files to support specific device configurations including screen size/resolution and (as you are trying to do) device orientation. When android is loading a layout file it will look first in the res/layout-port folder (if it is in portrait orientation) or in the res/layout-land folder (if it is in landscape orientation). If it doesn't find the file it will then look in the regular res/layout folder.

Additionally, as noted here, when certain device configurations change (like device orientation) during runtime android will restart whatever process is currently running by saving the state, destroying it, and then starting it with the saved state info. This allows it to load the layout files again, and it will look it the folder for the new orientation when it tries to load them.

So, if you start your application in portrait it will load the file in res/layout-port or res/layout. If you then rotate the device to landscape it will destroy your process and restart. However, this time it will be in landscape so it will check res/layout-land instead for the layout files.

If you have your files set up this way but it is not operating as you think it should, I'd first verify that it is definitely not using the correct files by putting two different header.xml files in the layout-land and layout-port folders, maybe one with a red background and one with a green background. Make sure to double-check the file references and maybe use Toast to post some debugging info on-screen to ensure that it is inflating layouts properly.

The default behavior is for android to handle the orientation change (which involves destroying your activity and creating a new instance of it which will reload all layout files). This default behavior will always occur unless your activity tag in your manifest file contains the property android:configChanges="orientation". (This tag can take arguments other than orientation - android will handle the config changes for all events except the ones you pass as arguments to this tag.)

If you include the android:configChanges="orientation" tag you are telling android NOT to destroy your activity and NOT to reload layout files when the orientation of the device changes. Instead of its default behavior it will call a method (which you define) to allow you to make any changes you wish to make to handle the orientation change yourself rather than letting android handle it automatically. It's intended so that if destroying your activity would be a major inconvenience it doesn't have to be automatically destroyed.

EDIT: added some things from the comment discussion