Setting different orientations for Phone and Tablet on Android - android

I would like to do the following in my app:
Portrait mode only for the phone
Portrait mode and landscape mode for tablets.
I know i can easily change the orientation in the manifest file but that will affect the entire application.
I have also thought of creating separate activities, to handle the different versions but i don't know how to detect the type of device using the application.
Does anyone know how to tackle this?

You can use the following piece of code to differentiate between normal/large screen and block the orientation change accordingly.
public static boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}

In activity's onCreate method check whether app is running on phone or on tablet. If app is running on phone set activity screen orientation to portrait only.
Add these files to your res folder.
res/values/vars.xml:
<?xml version="1.0" encoding="utf-8"?><resources><bool name="is_tablet">false</bool></resources>
res/values-sw600dp/vars.xml:
<?xml version="1.0" encoding="utf-8"?><resources><bool name="is_tablet">true</bool></resources>
In onCreate method off all your activites add this code:
if (!getResources().getBoolean(R.bool.is_tablet)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

You have to identify the tablet with Android screen qualifiers:
Then you put in the right layout folder the settings you want. For example you can add the attribute orientation:portrait|landscape only in the layout xml file for large screens, and orientation:portrait for all the others. See the folder structures here:
res/layout/my_layout.xml // layout for normal screen size ("default")
res/layout-small/my_layout.xml // layout for small screen size
res/layout-large/my_layout.xml // layout for large screen size
res/layout-xlarge/my_layout.xml // layout for extra large screen size
res/layout-xlarge-land/my_layout.xml // layout for extra large in landscape orientation
Take a look to the google guide: http://developer.android.com/guide/practices/screens_support.html

i suppose you can do small trick for it, try use Configuration.screenLayout :
switch (this.getResources().getConfiguration().screenLayout) {
case Configuration.SCREENLAYOUT_SIZE_SMALL:
return "small";
case Configuration.SCREENLAYOUT_SIZE_NORMAL:
return "normal";
case Configuration.SCREENLAYOUT_SIZE_LARGE:
return "large";
case 4: // screen xlarge
return "xlarge";
default:
return "undefined";
}
}
thanks

The problem that you are coming across unfortunately becomes a grey area. We can decipher what density a phone is and the physical size of a device. But there is nothing that really decides to us, what a phone is and what a tablet it. With phones being sometimes 7 inches tall and some tablets dedicated as just e-readers and such, they really could be any density or size.
However, the table suggested by Santacrab above could be used along with using the appropriate layout attributes that will resize accordingly regardless of the size of the screen. There will be circumstances of course where it makes sense to use fragments to split screens and on a smaller screen to avoid overcrowding the screen, but the links that spin off of the link from Santacrab should provide some good guidance on that as well.

Related

Different layouts for portrait and landscape modes based on screen width, not orientation per se

I have two versions of my layout, for smaller screens and for larger screens. Incidentally, I have a device where different layouts are required in different orientations. On other device that may not be so. I want to base it on screen width, not the orientation as such.
I've read this article and noticed that the "Available screen width" (w<N>dp modifier) can be used for specifying the proper layouts. It also says:
The system's corresponding value for the width changes when the screen's orientation switches between landscape and portrait to reflect the current actual width that's available for your UI.
Sounds perfect. So I put the smaller layout in the base layout folder, and the larger one into layout-w750dp. And the larger layout is picked. The problem is that it doesn't switch to the base layout when I rotate the device into portrait mode.
I have used the code from this answer to check the screen width in dp. It's 960 in landscape and 600 in portrait. Then I made sure android:configChanges="orientation" is not specified for this activity. I have also put Log into this activity's onCreate() - it is indeed called when I rotate the device, so it should have received the correct layout?.. Why doesn't it work and how to make it work?
Update: launching the activity (and even the whole application) in portrait mode right from the start still picks the w750dp layout.
Update 2: layout-land didn't work either. This layout is still picked in the portrait mode. Odd. It's becoming clear that the issue has little to do with width but with general functioning of the resource selectors.
Comments are getting long so to answer.
I just tested on tablet (768x1024 dp) two layouts first in layout, second in layout-w900dp and everything works just fine.
Second layout is shown in landscape mode which is correct because 900 < 1024.
Note: I used getResources().getConfiguration().screenWidthDp for screen width!
So it's definitely problem on your side :)
Ether you messed up your layouts or android studio messing with you :D.
Sorry for lack of more definitive answer :/

Adjusting to different screen sizes not working?

I thought I was successful in adjusting for different screen sizes(I was using the eclipse emulators and creating different screen sizes to test my app) but when I test my app on actual devices the result of my app varies. for example for a large screen size I set my emulator to a Nexus S and it will work and look fine, but then I try on an Alcatel One Touch Fierce(real device) which is still considered a large screen size the app play is just a little bit off, then I play it on another device which is also considered a large screen size the app will play just like the emulator. So i guess mt question is why? a samble of how I'm checking for different screen sizes is below:
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
switch(displayMetrics.densityDpi)
{
case DisplayMetrics.DENSITY_LOW:
// layout for small sized devices.
break;
case DisplayMetrics.DENSITY_MEDIUM:
// layout for medium-sized devices.
break;
case DisplayMetrics.DENSITY_HIGH:
// layout for large devices.
break;
case DisplayMetrics.DENSITY_XHIGH:
// layout for really large devices.
break;
Before your case statement, try to print the density value like this:
Log.i("Sushil", "displaymetrics.densityDpi : " + displaymetrics.densityDpi);
And check if it matches with any of your defined case statement. Else add new case statements, it should work. Few more defined cases are :
DisplayMetrics.DENSITY_TV
DisplayMetrics.DENSITY_XXHIGH
Hope this helps.
i don't see any thing wrong with the outcomes. if you run an app designed on a phone emulator-----on a tablet, the layouts will not match.
you have to decide if you wanna support different screen sizes or not if you do, then you'd have to create diffrent layouts for different screen sizes and set the corresponding layout in the OnCreate method of your Activity.
here is how to check if the device is a tablet or a phone:
if(isTablet==true){
setContentView(R.Layout.my_tablet_layout);
}else{
setContentView(R.Layout.my_phone_layout);
}
public boolean IsTablet() {
return (getApplicationContext().getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE;
}

How to make responsive Android application which is used in mobile and also in tablet?

I have created one Android application.
When I run my application in Mobile Phone it works very well, but when I run in Tablet the layout of application is changed.
So, how to make responsive Android application which is used in Mobile and also in Tablet?
On Android we can use screen size selector, introduced from Android 3.2, to define which layout to use.
More details available at http://android-developers.blogspot.in/2011/07/new-tools-for-managing-screen-sizes.html. Following code snippet has been extracted from the same link :
public class MyActivity extends Activity
{
#Override protected void onCreate(Bundle savedInstanceState)
{
super.onCreate();
Configuration config = getResources().getConfiguration();
if (config.smallestScreenWidthDp >= 600)
{
setContentView(R.layout.main_activity_tablet);
}
else
{
setContentView(R.layout.main_activity);
}
}
}
Another good reference for size configuration is keeping separator. This is explain in details at : http://www.vanteon.com/downloads/Scaling_Android_Apps_White_Paper.pdf
I am only talkin about Mobile Responsive Design.
With layouts, I believe you can only current differentiate by the following:
res/layout/my_layout.xml // layout for normal screen size
res/layout-small/my_layout.xml // layout for small screen size
res/layout-large/my_layout.xml // layout for large screen size
res/layout-large-land/my_layout.xml // layout for large screen size in landscape mode
You can find more info on what you can add to the folder structure to differentiate between different settings Documentation and android-developers.blogspot
In order to accommodate other types of tablets and screen sizes android introduces a new way to specify resources for more discrete screen sizes. The new technique is based on the amount of space your layout needs (such as 600dp of width), rather than trying to make your layout fit the generalized size groups (such as large or xlarge).
Update: There are essentially two ways you can give your audience a good experience utilizing responsive design:
Optimize the layout of your content.
Adapt the content that’s shown.
Update2: Write this code in your activity
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
setContentView(R.layout.landscapeView);
} else {
setContentView(R.layout.portraitView);
}
And also add this line in your Manifest file
android:configChanges="orientation|keyboardHidden|screenSize"
So this will handle both things, it will not restart your activity and will load the layout as per your orientation changes. For more information go to http://www.codeproject.com/Articles/422431/Handling-screen-layout-changes-in-Android
#Sagar Zala
Try to use constraint layout as parent view for your layout which will help to make your application responsive for phone and device.
Constraint Layout
You have to create layout for different screen sizes as creating a single design layout and hoping that it would work and look good on all screen size is next to impossible
As defined in android docs for supporting multiple screen sizes we need to focus on using 3 things.
using more Constraint Layout as it provide us with using more relative styling as compared to other layout component
Create alternate layout using qualifiers in android studio
use bitmaps or svg component that could stretch without being blurred.
ConstraintLayout
It supports things like percentage values,now combine those with guidelines it becomes a powerful tool for designing layout
Alternate Layout
In the layout design tab of android studio click orientation change icon then select create other... options from the dropdown list . Now you need to select qualifier from the provided list and create layout relative to different screen sizes without the need of extra code to write for showing those layout. Those layout would appear when a provided qualifier layout design matches.
You could follow the link provided above to see how they used smallest width qualifier with values
320dp: a typical phone screen (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc).
480dp: a large phone screen ~5" (480x800 mdpi).
600dp: a 7” tablet (600x1024 mdpi).
720dp: a 10” tablet (720x1280 mdpi, 800x1280 mdpi, etc).
These are the commonly used custom values that covers nearly all device sizes, you could add more refined sizes according to your need and then you could also add different orientation qualifiers too with addition to smallest width qualifiers.
Combination of all those would make your application completely responsive
I know i am answering to an old question but may be my answers helps other in search of similar query with a recent available solution.

Android: Automatically run different Code for different screen size

In the Android document: "Supporting Multiple Screens" Google describes how to employ different layout schemes for different screen sizes:
res/layout/my_layout.xml
res/layout-small/my_layout.xml
res/layout-large/my_layout.xml
res/layout-large-land/my_layout.xml
res/layout-xlarge/my_layout.xml
...
The problem is that for every layout the same code is reached: in 'onCreate' I'm using:
setContentView(R.layout.my_layout); and of course the right layout (xml) will be called according to the screen size.
What I want is that the xlarge and small screens will have very different layouts, in that case the Java code will be very different. My question is how do I differentiate these cases in the code? do I have to use some if/else or can android do it automatically?
My question is how do I differentiate these cases in the code? do I have to use some if/else or can android do it automatically?
You will have to "use some if/else", something like this:
if (getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_LARGE)==Configuration.SCREENLAYOUT_SIZE_LARGE) {
// yes, we are large
}
else {
// no, we are not
}
I wanted a navigation drawer to open on launch on the smaller screen sizes and stay closed on launch on tablets.
This is the code I ended up with:
if(getResources().getConfiguration().smallestScreenWidthDp < 600){
//Open the navigation drawer automatically
((DrawerLayout) findViewById(R.id.drawer_layout)).openDrawer(GravityCompat.START);
}else{
//Don't do anything
}

Is it possible to support both orientations on some screen sizes but not others?

In my apps I currently only support the portrait orientation for some activities, because I assume that most phone users will be using portrait orientation (and holding the device with one hand) most of the time.
On the new Honeycomb tablets, however, it seems likely that users will be using the landscape orientation much more often, so I'd like to support both orientations for more of my activities.
I'd rather not have to go back and add landscape layouts for the smaller screen sizes (all the way down to QVGA), though, so I'm wondering if there's a way of supporting landscape only for the xlarge screen type but not for the others.
You can combine the orientation and size attributes on the resource objects like:
res/layout/ -- default
res/layout-port/ -- portrait for any screen size
res/layout-xlarge/ -- any orientation on xlarge screens
res/layout-xlarge-land/ -- landscape on xlarge screens
Use the layout-port directory for your portrait-only layouts for smaller screen sizes, and then add your xlarge layouts to the layout-xlarge directory if you want to use the same layout file for portrait and landscape on xlarge, or to layout-xlarge-land and layout-xlarge-port if you want different layout files depending on the orientation.
Then, when you rotate to landscape on a smaller-screened device the OS will try to load a landscape layout but fail because there isn't one that matches and throw a Resources.NotFoundException. You can catch that exception, though, and force the activity to portrait mode in those cases using Activity.setRequestedOrientation():
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.titlescreen);
} catch (Resources.NotFoundException e) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
return;
}
[...]
}
That will then cause the activity to be recreated in portrait mode and it won't try to change again because using setRequestedOrientation() overrides the orientation sensor.

Categories

Resources