Drawable issue with theme - android

When building my app, I started just using the Theme.Light.NoTitleBar.Fullscreen theme. I built all my layouts for the whole app like this, and got things to look how I want them. Some drawables used in the layouts have their size specifically set, and others are set to wrap_content.
I then decided to switch to the Holo light theme. When I do this, all the drawables used in layouts that are set to wrap_content end up larger. Almost as if they are pulling from a larger bucket. In fact, some look like they've been stretched.
I know the background is black in the older theme one, but that's not an issue (this is actually a layout file that is included in another layout). Obviously there's quite a difference in size between the two.

Here is just my guess based on what I read in this thread.
It can be because you use those images as background property of Button views. This is not safe because depending on default margin values - which are defined in the Theme - Buttons can stretch background images as they need to. If this is the case, then you need to use ImageButton views instead and use setImage*() method to assign images. There you can use scaleType property as it was mentioned by Carlos Robeles.

The only thing that comes to my mind, is that the different themes has different values for the defaultandroid:scaleType attribute of the image views.
Please, try specifying the attribute as some that is good for you, and see what happens using the 2 different themes. For example you can use android:scaleType="center", so your ImageViews would be something like
<ImageView
android:scaleType="center"
android:width="wrap_content"
android:height="wrap_content"
android:src="...
Yo can take a look at the different scale types in the ImageView reference:
http://developer.android.com/reference/android/widget/ImageView.html#attr_android:scaleType
It is not easy to understand what's the meaning of every type, so the best is to take a minute to play with them

My guess is that for some reason, the Holo theme is rendering your images in a lower resolution than Light. I mean that for instance you have your drawables in the drawable-xhdpi and Holo is treating them as drawable-hdpi. In fact, I don't have any evidence of that, but recently I've been messing around with resolutions and the difference seems very familiar to me.
If you don't have your drawables in the drawable-xxhdpi (the biggest resolution) folder, you could try putting them into a higher lever resolution folder, to see what happens.

From android's source code, see https://github.com/android/platform_frameworks_base/blob/master/core/res/res/values/styles.xml
The style which your button will be used in Holo.Light is
<style name="Widget.Holo.Light.Button" parent="Widget.Button">
<item name="android:background">#android:drawable/btn_default_holo_light</item>
<item name="android:textAppearance">?android:attr/textAppearanceMediumInverse</item>
<item name="android:textColor">#android:color/primary_text_holo_light</item>
<item name="android:minHeight">48dip</item>
<item name="android:minWidth">64dip</item>
</style>
See the last two lines. It has default minHeight and minWeight. That's why your button is stretched.
Solutions
1. Set minHeight and minWidth of your Button to 0.
2. Use a custom style like this.
<style name="MyHoloLightButtonStyle">
<item name="android:background">#android:drawable/btn_default_holo_light</item>
<item name="android:textAppearance">?android:attr/textAppearanceMediumInverse</item>
<item name="android:textColor">#android:color/primary_text_holo_light</item>
</style>
3. Use a ImageButton, and set your images by setImage*(not setBackround*) method.

Related

Android Nougat has different dp calculation? Button sizes changed after update

My Samsung Galaxy s7 just updated to Android Nougat 7.0 and I noticed some of the buttons are displayed differently. I happen to have another Galaxy s7 around which hasn't gone through the update yet (Marshmallow 6.0.1). I can see the difference in sizes very clearly:
Marshmallow:
Nougat:
The layout_height of that SHARE button is hard set to 44dp. Using Layout Inspector in Android Studio I can read that it resolves to 176px for Marshmallow and 132px for Nougat (same values for mMeasuredHeight). You can also see that the other part of the layout on the left remained the same (ignore the little thumb up icon).
Another example:
Marshmallow:
Nougat:
I'm using following styling for the buttons:
<style name="AppTheme.Button" parent="Widget.AppCompat.Button">
<item name="android:textSize">14sp</item>
<item name="android:textColor">#color/colorPrimaryDark</item>
<item name="android:backgroundTint" tools:targetApi="lollipop">#color/colorTextBrightPrimary</item>
<item name="backgroundTint" >#FFFFFF</item>
<item name="colorButtonNormal">#color/colorTextBrightPrimary</item>
</style>
<style name="AppTheme.Button.Accent" parent="AppTheme.Button">
<item name="android:textColor">#color/colorTextBrightPrimary</item>
<item name="android:backgroundTint" tools:targetApi="lollipop">#color/colorAccent</item>
<item name="backgroundTint" >#color/colorAccent</item>
<item name="colorButtonNormal">#color/colorAccent</item>
</style>
While the SHARE button is a custom view, extending AppCompatButton, the Google and Facebook auth buttons are just AppCompatButtons. In either way, they all looked different just before the update and nothing else was changed in code, nor on the device (text size and zoom are the same).
Any idea what's going on? How to ensure these layouts stay the same on various devices/OS'?
A drawable can have its own padding. In the case of a nine-patch PNG file, that's simply having transparent pixels outside of the actual non-transparent/resizing portion of the image. In the case of ShapeDrawable, you can directly declare padding in the XML. And so on. This may or may not show up as "padding" in tools like the Layout Inspector, as they focus on padding declared on widgets.
Since the previous background you were using had the problem, and the replacement background does not, my guess is that this sort of implicit padding is the problem.
You have two approaches for trying to deal with this:
The risky-but-simple approach is to try using negative padding on the button itself, in a res/values-v24/ variant of your style resources (or, optionally, use a consistent dimension resource in the style and vary the dimension values based on -v25 or not). You would have to tinker a bit to try to get values that "undo" the change. I call this "risky" as I haven't the foggiest notion how well Android respects negative padding.
The aggravating approach is to try to find the actual button background that you were using before, and see what changed about it. The drawables would be declared either in appcompat-v7's themes or the platform's themes, and the actual drawables themselves would then be defined either in appcompat-v7 or in the platform.

Unexpected screen gradient in ListView

I have a ListView with some rows and a custom checkbox on the right hand side. On my OS 4.4 Nexus 4 it seems like a gentle gradient is being applied to the list row backgrounds, creating an ugly artifact on the checkboxes (they disappear half way down, and then invert for the bottom half). On other devices I don't see this problem, and I also don't see it in an OS 4.4.2 emulator.
I haven't been able to find any information online about this, so I'm not sure if it's specific to the device, or the exact OS flavor.
Is this something I can disable? If not, what advice should I give my asset designer?
Here's a screenshot:
The Holo.Light theme uses a subtle grey gradient background. It might only be more apparent on one of your devices due to the screen's contrast/brightness.
You can just set the background to solid white by using the android:windowBackground tag in your Activity's theme:
<style name="SolidWhiteTheme" parent="android:Theme.Holo.Light">
<item name="android:windowBackground">#android:color/white</item>
<item name="android:colorBackground">#android:color/white</item>
</style>
And then applying the theme to your activity in your AndroidManifest.xml like so:
<activity
android:theme="#style/SolidWhiteTheme"
...
>
...
</activity>
As Denley mentioned, the reason for this is the default background specified by the Holo.Light theme.
However, since this background is specifically affecting your ListView, I would suggest setting the background of your ListView in your xml file. Code below.
<ListView
android:background="#android:color/white">
Try specifying a background color for your activity (android:background). If the background is not explicitly set, the device may be using it's own device-specific default background, which is why the gradient is only shown on your Nexus 4 and not other devices.

change style attribute at runtime

I set the application theme using the following style
<style name="Background1" parent="#android:style/Theme.NoTitleBar.Fullscreen">
<item name="android:windowBackground">#drawable/bigl_2</item>
<item name="android:windowNoTitle">true</item>
</style>
using this method :
setTheme(R.style.background1);
Here my requirement is I want to change the theme with a bitmap image, how can I do it at runtime?
Thanks
You may want to have a look at the same question: android dynamically change style at runtime
As it seems to me, the matter is that generic style attributes can force screen re-layouting, so there is no API to change styles at runtime - you need to create screen anew (the same approach is dictated for landscape/portrait screen orientation changes, where Activity is re-created and large brains of Android system architects invented savedState in onCreate() to easy (complicate?) that process, and then invented Fragments to easy that even more))
So, changing styles generally means changing layout. But you can change Theme attributes at runtime (per the link above - I haven't tried myself), and it will work since it doesn't need re-layouting.
As a workaround, since you will need to recreate views for new layout, you can simplify code by applying different Theme, see the link.

Android Where to place different icons for different themes?

In my application I have different Themes - one dark and one bright theme. Each theme requires his own icon set.
How do I apply it to the theme? Is there something like a special folder like for icons with different sizes ?
The following serves as a hint...
I suppose this may help: http://developer.android.com/reference/android/R.attr.html#icon
Lets say you have the following themes...
<style name="MyTheme.Dark">
...
</style>
<style name="MyTheme.Light">
...
</style>
You can add <item name="android:icon"></item> to each theme and supply each one with their own drawable icon. Then to get the respective drawables in your layout or what have you, you need to make use of ?android:attr/icon.
So your layout may end up looking something like...
<View
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?android:attr/icon"/>
If you're unsure about what the ?android:attr/icon part exactly means, read http://developer.android.com/guide/topics/resources/accessing-resources.html#ReferencesToThemeAttributes.
Is there something like a special folder like for icons with different sizes ? (up to my knowledge) NO
no such default folder exist which you can use for Themes.
You need to do it programmatically.
Save the theme info in your Shared Preferences.
and at time of loading the view you can set your desired themed drawable.

Best way to scale layout styles in Android?

I've run into a dilemma when working with apps that should support a large range of screen sizes. What is the best way to scale attributes like text size, width and height via styles?
Optimally, I would love a setup like this:
layout.xml:
<YourView style="#style/Footer"/>
styles.xml:
<style name="Footer">
<item name="android:layout_height">#string/FooterHeight</item>
<item name="android:layout_width">fill_parent</item>
<item name="android:background">#drawable/background_footer</item>
<item name="android:layout_gravity">bottom</item>
</style>
values/layout_vals.xml:
<string name="FooterHeight">50dp</string>
values-sw600dp/layout_vals.xml:
<string name="FooterHeight">80dp</string>
Then, in order to change the height of a View, all one would have to do is create a new folder with the target min width and edit the values of *layout_vals.xml*, and leave all the extraneous junk about width, gravity, background etc alone, leaving for a much cleaner setup and easier editing.
However, I've tried and found out that this exact setup doesn't work. For now, I just copy the entire styles.xml into the different 'layout-swXXdp' folders and swap out values. Does anyone have suggestions as to another method of project setup that is comparable to or, better yet, even better than this? Thank you for your time!
Instead of string, use the #dimen resource - I think its exactly what you're looking for (except it would go into res/values-sw600dp)

Categories

Resources