Set visibility via bindings - dimens.xml - android

Is it possible to set the visibility via bindings? (dimens.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="#whatever/visibility_of_this_view"
android:orientation="horizontal">...
so that I can put something inside of the dimens.xml like:
<whatever name="visibility_of_this_view">visible</whatever>
I don't want to do it via code or different layouts, just with different dimens.xml.

How ever your different dimens are selected (layout, api, what ever) you should use the same mechanism to select another layout or even a different style which sets the visibility. Every other way seems to be a abusive way :)

Related

How to show phone's portrait layout in tablet irrespective of it's orientation WITH ViewBinding WITHOUT locking orientation?

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?

Use generic layout for top-level ar locale, but region specific locale for others

I'm developing a multilingual app and need to show a different layout for a specific region
My res structure is as follows
res/
layout/
questions.xml
layout-ar-rLY/
questions.xml
When the locale is English (en) the default layout is shown. When the locale is Libyan the Libyan (ar_LY) layout is shown. However, when the locale is Arabic (ar) the Libyan layout is still shown. I need it to show the default layout.
I know that I can simply create a layout-ar directory and copy the questions.xml layout there, however, I am wondering if there is a more elegant way to achieve the right result, so that I don't have to maintain both files.
res/
layout/
questions.xml
layout-ar/
questions.xml
layout-ar-rLY/
questions.xml
The best solution I have come up with so far is for the default and the Arabic layouts both to include a shared sub-layout. Is there a better way to achieve the same result?
Thanks to MH's comment above I had a look at the Android documentation on the official way to do this using Aliases which suggest this.
<?xml version="1.0" encoding="utf-8"?>
<merge>
<include layout="#layout/main_ltr"/>
</merge>
Unfortunately the method given in the documentation doesn't actually work (as detailed in this StackOverflow) answer. Using a merge tag as a root element gives an InflateException error.
I'm sure that the second suggested fix contained in the StackOverflow thread should work; however, the concept of placing Layouts into the resources seems to me to be just as flawed as creating multiple copies (ie from a maintenance perspective you have to remember they are there and not in the layouts folders where you'd expect them to be) so in the end I compromised on the following:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<include layout="#layout/questions_default"/>
</FrameLayout>
Which is a bit more verbose than just a merge tag, but at least it works.

Change several layouts for different densities at the same time

If I have three different layouts for a same view (lets say, one for phone, one for tablet and one for tablet in landscape) and I want to add/change a property that the three of them share (lets say, the android:background), is there a way of adding/changing it in one place and have it automatically in the other two layouts? Is there an alternative to copy-and-paste it?
Unfortunately not really. You could have separate layouts for each set of elements and use include to include them in each subsequent layout, then just updating the single layout would update all of them. But this would mean having a lot of stand alone layouts. A good example of this is using a seperate Toolbar layout like so:
Toolbar layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
style="#style/Toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
Then have this line in all layouts which you want to use Toolbar.
<include layout="#layout/toolbar" />
This technique could be applied to anything you like, and would allow you to in future only edit each separate layout once and have it applied everywhere you use it. You can also edit dimensions inside these Layouts under the include, or in code.
The only other way to achieve what you want would be to handle it all explicitly in code but I wouldn't recommend this.
You can apply style for the widget(TextView or LinearLayout for example) that uses background property and determine background property in that style.
Changing background property in style will affect all the widgets this style was previously applied to.
http://developer.android.com/guide/topics/ui/themes.html

How do I setup my fragments such that the layout I am using for phone also works well with tablets?

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.

Is it possible to save layout_weight in an xml?

I need to change the layout_weight of 3 views in a layout, according to the physical size of the screen. The views have the weight of 0-1-0, but this has to change to 0.2-0.6-0.2 when the layout is used in an xlarge screen.
I tried saving the layout_weight inside different copies of the dimensions.xml (one in values/dimensions and an other one in values-xlarge/dimensions), but it looks like I cannot give a dimension without setting dp/px or w/e (cannot save a "raw" number like 1, or 0.2).
Is it possible to do via xml somehow, or do I have to work programmatically in order to achieve that?
Try an integer resource file. It is very similar to dimensions.
http://developer.android.com/guide/topics/resources/more-resources.html
Create a file in your corresponding values folders i.e. values, values-large, values-xlarge, .... Add a resources file with content similar to this example:
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<item type="integer" name="layout_weight_xy">7</item>
</resources>
and then call
android:layout_weight="#integer/layout_weight_xy"
in your layout file.
You can create special layout in layout-xlarge folder and provide different weights there
First, define your resource e.g integer.xml and make sure you set the correct type and format. If you want to use it for layout_weight you can set type="integer" format="float".
<item name="my_weight_value" type="integer" format="float">1.2</item>
Then we can use it in layout
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="#integer/my_weight_value"
android:orientation="vertical">
</LinearLayout>

Categories

Resources