I am trying to create an app which has two different UIs for tablets and phones, and I'm using fragments to implement this. I have created two separate xml files for each tablet and phone layout and both are called activity_main.xml, with the phone layout being placed in the res/layout folder and the tablet layout being placed in the res/layout-sw600dp folder.
However when I try to run my app on a Nexus 10 emulator(Android Studio), it automatically goes to the default phone layout. The app doesn't crash or anything but it just runs in the phone UI when it's supposed to run in tablet UI. I dont know what the source of this error could be and so any help would be appreciated.
Here's an update, I tried renaming the folder to res/layout-large-mdpi but still found no change. Is it possible that it might have something to do with the emulator?
Here's my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidattack.www.sunshine" >
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.androidattack.www.sunshine.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.androidattack.www.sunshine.DetailActivity"
android:label="@string/title_activity_detail"
android:parentActivityName="com.androidattack.www.sunshine.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.androidattack.www.sunshine.MainActivity" />
</activity>
<activity
android:name="com.androidattack.www.sunshine.SettingsActivity"
android:label="@string/title_activity_settings"
android:parentActivityName="com.androidattack.www.sunshine.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.androidattack.www.sunshine.MainActivity" />
</activity>
<provider
android:authorities="com.androidattack.www.sunshine"
android:name=".data.WeatherProvider" />
</application>
</manifest>
sw600dp layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="?android:attr/dividerHorizontal"
android:baselineAligned="false"
tools:context="com.androidattack.www.sunshine.MainActivity">
<fragment
android:layout_width="0dp"
android:layout_height="fill_parent"
android:name="com.androidattack.www.sunshine.ForecastFragment"
android:id="@+id/fragment_forecast"
android:layout_gravity="center_vertical"
android:layout_weight="1" />
<FrameLayout
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="2"
android:id="@+id/weather_detail_container">
</FrameLayout>
</LinearLayout>
normal layout:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_forecast"
android:name="com.androidattack.www.sunshine.ForecastFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
tools:context="com.androidattack.www.sunshine.ForecastFragment"
tools:ignore="MergeRootFrame"
tools:layout="@android:layout/list_content" />
And finally this is my MainActivity.java class:
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.androidattack.www.sunshine;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends ActionBarActivity {
private final String LOG_TAG = MainActivity.class.getSimpleName();
private boolean mTwoPane;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (findViewById(R.id.weather_detail_container) != null) {
// Tablet view
mTwoPane = true;
// In two-pane mode, show the detail view by adding
// or replacing the detail fragment using a
// fragment transaction.
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.weather_detail_container, new DetailFragment())
.commit();
}
} else {
// Phone View
mTwoPane = false;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
startActivity(new Intent(this, SettingsActivity.class));
return true;
}
if (id == R.id.action_map) {
openPreferredLocationInMap();
return true;
}
return super.onOptionsItemSelected(item);
}
private void openPreferredLocationInMap() {
SharedPreferences sharedPrefs =
PreferenceManager.getDefaultSharedPreferences(this);
String location = sharedPrefs.getString(
getString(R.string.pref_location_key),
getString(R.string.pref_location_default));
// Using the URI scheme for showing a location found on a map. This super-handy
// intent can is detailed in the "Common Intents" page of Android's developer site:
// http://developer.android.com/guide/components/intents-common.html#Maps
Uri geoLocation = Uri.parse("geo:0,0?").buildUpon()
.appendQueryParameter("q", location)
.build();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(geoLocation);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
} else {
Log.d(LOG_TAG, "Couldn't call " + location + ", no receiving apps installed!");
}
}
}