How can I use layout_width using resource file?
There are a activity what I want to fill the screen in a phone and pop up(dialog) for a tablet.
I thought I make a layout file like this,开发者_开发知识库
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="@dimen/main_layout_width"
android:layout_height="match_parent">
and externalize the value of width as
in values/dimens.xml
<dimen name="tutorial_width">match_parent</dimen>
in values-xlarge/dimens.xml
<dimen name="tutorial_width">320dp</dimen>
But I can't representation 'match_parent' as dimen element. Any help? Thanks!
The best way I found: - instead of "match_parent" and "fill_parent" write "-1dp" - instead of "wrap_content" write "-2dp"
dp
depends on the device display metrics and won't work on all devices without a set of density-specific overlays, however, px
can be used instead.
Unfortunately, the simple rounding technique used by TypedValue#complexToDimensionPixelSize()
only considers non-negative values:
final int res = (int)(f+0.5f);
if (res != 0) return res;
if (value == 0) return 0;
if (value > 0) return 1;
return -1;
When f (the px value) is negative, the result is usually rounded incorrectly because it always uses addition. The following pixel sizes are observed for negative px
dimensions:
0px = 0.0
-1px = -1.0
-2px = -1.0
-3px = -2.0
-4px = -3.0
-5px = -4.0
...
I opened an AOSP issue for this method:
TypedValue#complexToDimensionPixelSize() rounds negative dimensions incorrectly
Considering this behavior, the following values will work on all devices:
<dimen name="match_parent">-2px</dimen>
<dimen name="wrap_content">-3px</dimen>
You can use -1px or -2px for match_parent, but wrap_content must be -3px. Either combination works on devices and emulators.
In practice, I've found that IntelliJ's Preview feature fails to render layouts when -1px is used for match_parent, and incorrectly renders -2px as if it were "wrap_content" when referenced by another dimension e.g. <dimen name="my_width">@dimen/match_parent</dimen>
. I have opened an issue for IntelliJ IDEA:
Android Preview cannot render layout_width="-1px"
I used a style to fix this problem. Having separate xml style elements with android:layout_width items for different screen sizes solved the problem without using the undocumented -1dp
I am not able to comment yet so i'm writing new answer. I used answer provided by @pjanecze in my project. All was fine till few days ago when suddenly some devices started to report strange widget positioning. Devices with very high density, instead of getting match_parent as -1 from my dimenstions (which was equivalent to android constant match_parent = -1 in layout parameters), it was getting -2, which means that width was set to wrap_content (-2 in layout_parameters). Obviously because -1dp is converted to pixels in runtime, and -1dp was in some cases -2px.
So ... instead of using constant -1dp and -2dp, you should use -1px and -2px for match_parent and wrap_content.
Whats works for me and probably features academic correctness is something like this:
<!-- In values/dimens.xml -->
<item name="width_match_unless_huge" type="dimen" format="integer">-1</item>
<!-- In values-sw600dp/dimens.xml -->
<item name="width_match_unless_huge" type="dimen" format="dimension">600dp</item>
This allows you to mix sizing behavior constants like MATCH_PARENT
and concrete sizes in dp depending on the current configuration.
You would use it as a regular <dimen/>
:
<LinearLayout
android:layout_width="@dimen/width_match_unless_huge"
.../>
According this great contribution: http://blog.danlew.net/2015/01/06/handling-android-resources-with-non-standard-formats/
Let's try defining both match_parent and wrap_content without a format:
<item name="match_parent" type="dimen">-1</item> <item name="wrap_content" type="dimen">-2</item>
We can reference those in any other dimension value:
<!-- Inside /res/values/dimens.xml --> <dimen name="responsive_width">@dimen/match_parent</dimen> <!-- Inside /res/values-sw800dp/dimens.xml --> <dimen name="responsive_width">800dp</dimen>
For more info visit the web page I mentioned earlier!
You can create two layouts - default with android:layout_height="match_parent" in "layout" dir, and for tablet android:layout_height="320dp" in "layout-xlarge" dir
As mentioned earlier in https://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html#MATCH_PARENT MATCH_PARENT = -1 and WRAP_CONTENT = -2. Instead of declaring the values as Dimension resources I have successfully declared and used them as Integer resources. So for the example to work you can use two Integer resource files:
values/integers.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="tutorial_width">-1</integer>
</resources>
values-sw600dp/integers.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="tutorial_width">-2</integer>
</resources>
And the layout file will be:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="@integer/tutorial_width"
android:layout_height="match_parent">
Value -1 was not working for me on android api 30 emulator of Pixel 4.
Clean solution is to define sw600dp/styles.xml
and create base style for your component in styles f.e. DialogControllerTypeGridBase
then create other that ha its as parent DialogControllerTypeGrid
and also other in sw600dp.
Example:
styles.xml
<style name="DialogControllerTypeGridBase" parent="CSGridMatch">
<item name="android:layout_height">wrap_content</item>
<item name="android:background">@drawable/background_bordered_section</item>
<item name="android:horizontalSpacing">8dp</item>
<item name="android:padding">4dp</item>
<item name="android:verticalSpacing">8dp</item>
</style>
<style name="DialogControllerTypeGrid" parent="DialogControllerTypeGridBase">
<item name="android:layout_width">wrap_content</item>
<item name="android:numColumns">6</item>
</style>
sw600dp/styles.xml
<style name="DialogControllerTypeGrid" parent="DialogControllerTypeGridBase">
<item name="android:layout_width">450dp</item>
<item name="android:numColumns">3</item>
</style>
This way nothing gets duplicated and you dont use meaningles values like -1, -2 that dont work reliably across device based not just by me but also comments from others.
精彩评论