I have an Activity in a tablet app and I want to show different Fragments depending on the orientation. I figured the easiest way to do this was just to define two different layout XML files, one for landscape and one for portrait. In other words I have /layout/home.xml which looks like this:
<LinearLayout android:orientation="horizontal">
<fragment class="com.foo.app.Frag1" android:id="frag1"/>
<fragment class="com.foo.app.Frag2" android:id="frag2"/>
</LinearLayout>
And then in /layout-port/home.xml:
<LinearLayout android:orientation="vertical">
<fragment class="com.foo.app.Frag2" android:id="frag2"/>
<fragment class="com.foo.app.Frag3" android:id="frag3"/>
</LinearLayout>
When I run it, I can start in landscape and go to portrait, and everything is fine. However, when I go from portrait to landscape, the app crashes with a android.content.res.Resources$NotFoundException with Resource ID equal to "frag3." That's right it's looking for Frag3 when going to landscape made, and there is no Frag3 in that mode. This happens during the Activity.onCreate stack, so before any of my code has any chance to make the app crash.
Are Fragments not supposed to work this way? Do I need to use a FragmentTransaction instead?
It's hard to say without seeing the code- However, Resources.NotFoundException usually means you tried to look up an asset (think R.layout.xx, R.drawable.xx, etc) incorrectly.
That said, I tried writing a small app using your layout XML, and the compiler yelled at me for hardcoding strings as the ID's when I copied in your XML code to test it out. Try switching the values of the android:id attribute to read like this:
android:id="android:id="#+id/frag1"
that might fix the issue.
Related
I have a fragment called ErrorFragment.
I have different layout files to be shown on phone for portrait (error_fragment_portrait_content.xml) and landscape(error_fragment_portrait_content.xml) mode.
But I want to use the same layout (phone's portrait layout) in tablet mode irrespective of tablet's orientation.
Please note that I don't want to lock the orientation. I want orientation to be switched, but layout to be shown should remain the same.
And I want to use the ViewBinding for my fragment.
I know a straightforward solution is to just copy the layout file error_fragment.xml from res/layout/ folder to res/layout-sw600dp. But this is adding up to the apk size. I want to avoid this.
I tried another approach as well. This is the code snippet of my error_fragment.xml:-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/error_fragment_content"
layout="#layout/error_fragment_portrait_content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
In res/layout/ folder, I am including layout="#layout/error_fragment_portrait_content"
In res/layout-land folder, I am including layout="#layout/error_fragment_landscape_content"
In res/layout-sw600dp folder, I am including layout="#layout/error_fragment_portrait_content"
But the binding file generated for ErrorFragment (ErrorFragmentBinding) gets confused whether to create and instance of ErrorFragmentPortraitContentBinding or ErrorFragmentLandscapeContentBinding? It's generating an instance of ViewDataBinding. So getting a build error with this approach.
So, I want to know how can I achieve my desired results?
I am participating in the Udacity Android Basics degree. I am struggling with the project explained below. I am yet using only basic knowledge so please do not be surprised by the code simplicity. :)) I am eager to understand how to position elements so that they appear in every phone orientation mode using RelativeLayout.
You can find the XML here.
There are two screenshots of the app displayed in portrait and auto-rotate. The portrait looks alright but in auto-rotate half of the information displayed disappears.
My second question is related to the clickable elements. Once, I made them clickable they turned into red and underlined. Is this common or I should offset this with another statement?
This is my GitHub project.
Any help is appreciated.
Thanks,
Iva
For Your First Issue of Portrait and Landscape Try to put your view contents in a scrollview so that the screen contents will be scrollable when the height of the view is more than the screen height (In Portrait and Landscape Modes)
Sample with your code
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.helloandroid.MainActivity"
android:background="#03B3E4">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
Add Your Contents Here ...
</LinearLayout>
</ScrollView>
For the Second question
Textviews with android:autoLink="" always takes the color from your colorAccent in styles.xml in your project if it has text that can be linked like website or mobile or map
you can change the text color by adding android:textColorLink="yourcolorhere"
to your textviews
Thanks
For auto-rotation, you can either lock rotation for your app locking screen rotation. You can use any of the methods suggested by other developers.
But If you want to add landscape orientation to your app, then you will have to define a separate XML layout file for it. You can do so by Creating a
layout-landdirectory by right clicking layout under res and putting the landscape version of your layout XML file in that directory. You can also refer to this answer for some help handle screen rotation without losing data in android
Coming to the second part of your question, if you make an element clickable, it is not supposed to turn red and underlined. I am not sure how you are making them clickable but to make an element perform a function on Click, just declare the element and define it. Then you can set an OnClick listener to it. You can see an example here making a button clickable. Youcan also try this code to make the button clickable:
Button btn= (Button) findViewById(R.id.button_main);
btn.setClickable(true);
I am using my app currently ,made of fragments , just on phone. I am planning to add tablet version of the same , but seems like some fragments don't work exactly as expected on the tablet and often many mess up on landscape.So I just needed some pointers how to go about the same?
Here is my code for one of the fragments layout in xml :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/altercolor2" >
<HorizontalPageView
android:id="#+id/headline_gallery"
android:layout_width="match_parent"
android:layout_height="140dp" />
<include layout="#layout/loading_no_results" />
</FrameLayout>
How do I alter it such that the height even works on tablet as expected without cutting off some data? Also, should i add another duplicate layout somewhere for this or there's way around it? Any help appreciated,thanks!
Try this. Make a new layout-xlarge folder in /res directory and place all your tablet related xml files in that folder. Android system automatically fetches layout files from this layout-xlarge folder for 7-10 inch screens.
And to support landscape mode, design your layout files specifically for landscape mode and put it in layout-land folder. But make sure that the name of the files in all the folders are same.
Android Training guide covers this best.
You should read it
http://developer.android.com/guide/practices/screens_support.html#support
Theory, logic and best practices are a bit long to be explained here. So, my suggestion is to read this tutorial from the official documentation, http://developer.android.com/training/basics/fragments/index.html, checking all the topics and the links suggested by Google.
Also check the example application provided by them as well.
Having done that, if you have a more specific issue, please ask here and we will be more than happy to help you.
Try putting your main views i.e HorizontalPageView in a linear layout and make use of the weight and orientation attributes of the linear layout.
As I understand from your code you want to align the views vertically, in this case the "weight" attribute does wonders
first you need to figure out whether you will use a different ui for tablet version besides the phone version, if you use the same ui disign, (one pane or two panes), just thinking about portrait/landscape is enough, otherwise you need use style and value-swxxx to arrange the layout files for tablet and phone.
Besides the phone/tablet issue, you also need use layout-land to define the same layout unit for the landscape mode. so there are (phone-portrait, phone-landscape, tablet-portrait, tablet-landscape) four scenarios.
I have an image in portrait mode, which is displayed correctly. When I change the configuration to landscape, the image is not displayed.
Note that the LinearLayout, enclosing the ImageView is displayed right(I checked it by changing the background). But when I changed the background for the ImageView, the background was also not shown.
<LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="10dp" android:layout_weight="3">
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_vertical" android:minHeight="48dp" android:minWidth="48dp" android:src="#drawable/xyz" android:id="#+id/img"/>
Do you have different files specified for portrait and landscape more? I.e., do you have a layout file with the same name in the layout folder as well as the layout-land folder? If so, make sure both files include the ImageView.
You are most likely specifying the file you want to display like
myImageView.setImage("myfile.jpg");
in your onCreate method.
Move this code to onResume (create onResume with the #Override if you do not already have it) This will fix your problem
OK, your layout file is unnecessarily large and complex. So let's try a couple of things-
First, try creating a simple version of your XML file that contains the barebones for displaying the image. If that works in both portrait and landscape, you know that the problem is not your activity or your image.
If the first step works, the next step would be to work on simplifying your layout file, there is a lot that could be pruned. It goes seven layers deep at points, that should almost never happen. Here is a good blog post by an Android engineer on better layout design. You can find similar resources elsewhere.
Ok, I'm officially at my wit's end here. Working on an Android app that uses AdMob. Everything is set up to the letter following their instructions, no errors, etc.
Problem is: I only see ads when the phone is in landscape orientation.
I've searched online and done every last thing I can think of to test this:
Tried it in test mode and normal mode
Removed the orientation configChanges from my main activity's manifest and their handlers in the code, in case they were causing it
Removed all functionality of the app so that onCreate looked like the one in the instructions above
Tried every possible change of main layout - placing it in different locations, removing other widgets, different layouts, etc
These are just a summary of a few hours of testing, every time the result is the same. Portrait shows no ad, landscape shows the ad (as/where expected - not stretched, but the max width issue is well known and not a problem).
Logcat shows everything to be working properly in both orientations: Requests are made, ads are returned. I can click on the ads that appear in landscape, but tapping the area they're meant to be in portrait does nothing.
It's driving me mental! Any ideas?
Edit: Okay, the problem is gone but I'm afraid I can't really call it a "fix". I remembered ads working fine in a previous but similar app. It was using a different version of the AdMob SDK - I don't know any details, but admob-sdk-android.jar is 77kb rather than 136kb.
I copied the 77kb one from the old app into the new app, along with the attrs.xml file, which necessitated changing the primaryTextColor attribute in the AdView to textColor, and that's it. Works perfectly now - and as a bonus, the ads stretch horizontally across the whole screen in landscape view as well!
I'm posting this as an edit rather than an answer since it seems more appropriate and I'd still love to know if anyone can shed some light on the issue. Was it an AdMob SDK issue?
I also encountered this issue, you should check if the parent container is padded, if it is, remove padding and all of sudden ads will appear. I don't find it very logical but it helps.
Not sure if this will help, but i had a similar issue, where in a landscape game, the ads would appear in portrait mode only. On a tab 2 i borrowed for testing from someone. Turned out there was some sort of screen lock on the device which caused it. Spent hours trying to chase the bug down.
Check this layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".AddTest"
tools:ignore="MergeRootFrame" >
<com.google.android.gms.ads.AdView
android:id="#+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
ads:adSize="BANNER"
ads:adUnitId="#string/banner_ad_unit_id"
>
</com.google.android.gms.ads.AdView>
</RelativeLayout>
I have same problem in tools:ignore = "aaaaaaaaa" and padding