I have a textview that I set its style to a style I made with a shadow. I declared the settings I want in the style.xml InfoTextstyle and set the textview style to the style but it doesn't work.
This is the style.xml:
<style name="InfoTextStyle" parent="AppBaseTheme">
<item name="android:textColor">#fff</item> <- works
<item name="android:textSize">18sp</item> <- works
<item name="android:shadowColor">#ff0000</item> <- don't works*
<item name="android:shadowRadius">5.0</item> <- *
<item name="android:shadowDx">2.0</item> <- *
<item name="android:shadowDy">2.0</item> <- *
</style>
& this is the activity_main.xml:
<TextView
android:id="#+id/brightness"
style="#style/InfoTextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginTop="15dp"
android:text="#string/brightness"
android:textAppearance="?android:attr/textAppearanceMedium" />
I'm new to android, so I'm not sure what's the problem.
A few things to try:
Look on a real device, not in Eclipse "Graphical layout" which does not support text shadow.
Decrease the shadow radius to 1. The larger the radius, the more blurred the shadow is.
Check if the style file you wrote in in the main "values" directory or under values-?dpi. Maybe your device dpi does not target your style file
Use this XML code in your TextView declaration instead of using Styles
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="A light blue shadow."
android:shadowColor="#00ccff"
android:shadowRadius="1.5"
android:shadowDx="1"
android:shadowDy="1"
/>
-android:shadowColor Shadow color in the same format as textColor.
-android:shadowRadius Radius of the shadow specified as a floating point number.
-android:shadowDx The shadow’s horizontal offset specified as a floating point number.
-android:shadowDy The shadow’s vertical offset specified as a floating point number.
Also use this link to pick your Color code
http://www.w3schools.com/tags/ref_colorpicker.asp
EDIT:
TextView textv = (TextView) findViewById(R.id.textview1);
textv.setShadowLayer(1, 0, 0, Color.BLACK);
Also take a look at this link for Style way
https://stackoverflow.com/a/2487340/1364896
Related
I have a LinearLayout with that has multiple TextViews and want to set up a default global color for that layout only without having to add a textColor field inside each TextView. Also, if it's possible, would it also be possible to override the color value by adding it inside the TextView? i.e. If I set blue as a default color and black for a single TextView, would the blue change to black?
To set the default global TextView colors, first you can create your own theme in AndroidManifest.xml file for the following items:
textColorPrimary - for Large texts
textColorSecondary - for Medium texts
textColorTertiary - for Small texts
textColorHint - for Hint texts
For example, in AndroidManifest.xml:
<style name="TextViewTheme" parent="android:Widget.TextView">
<!-- Set the default global color for TextViews to Holo Blue Dark -->
<item name="android:textColorPrimary">#android:color/holo_blue_dark</item>
<item name="android:textColorSecondary">#android:color/holo_blue_dark</item>
<item name="android:textColorTertiary">#android:color/holo_blue_dark</item>
<item name="android:textColorHint">#android:color/holo_blue_dark</item>
</style>
Next, set the theme style on your LinearLayout. You can also override the default for a single TextView to black color, like the following which set the first TextView Hint text color to black in activity_main.xml:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:theme="#style/TextViewTheme">
<TextView
android:id="#+id/phone_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="#string/phone_tv"
android:textColor="#android:color/black"
android:textColorHint="#android:color/black" />
<TextView
android:id="#+id/email_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="#string/email_tv" />
</LinearLayout>
Hope this helps!
You can override default text colors for the entire application by setting textColorPrimary and textColorSecondary in your parent in styles.xml
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="textColorPrimary">#color/black</item>
<item name="textColorSecondary">#color/grey</item>
</style>
If your TextViews are indeed very many to the extent that calling setTextColor() on each of them would be a herculean task, why not use a view that supports an adapter (i.e ListView, RecyclerView etc). Your TextViews would show up the exact same way as you intend them to appear with the LinearLayout.
While using an adapter, you can set up a model TextView layout and set a global textColor for all the TextViews. You can override this global textcolor in your adapter by using simple if and else statements.
I hope this helps.. Merry coding!
This code will work even if you add or remove TextViews from your layout. Just put it in your activity's onCreate();
LinearLayout layout = (LinearLayout)findViewById(R.id.layout);
for (int i = 0; i < layout.getChildCount(); i++) {
View v = layout.getChildAt(i);
if (v instanceof TextView) {
((TextView) v).setTextColor(Color.BLACK);
}
}
change the color to what you like.
If you want after this code you can change the color for any specific TextView.
Pretty late answer but this does the trick.
Inside style.xml lately changed to themes.xml
<style name="ErrorStyle">
<item name="android:textColor">#FF0000</item>
</style>
Then inside your xml layout
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="#style/ErrorStyle">
.. All of your TextView
</LinearLayout>
Using this approach we can use other xml variation such as night mode, etc... and we still have te possibility to override the internal TextViews.
I have included a rating bar in android, and now I need to place a text view to immediate right if the rating bar.But I failed to do the same since, there is a lot of unwanted space (rectangular blue box) around the rating bar, which prevents me from placing the textview to its immediate right side. Is there any way to reduce this space around the rating bar , so that both the textview and the rating bar comes in same line and textview is placed next to the rating bar without a gap.Please help me with a good support! Thanks in advance! Here is my xml code for it.
<RatingBar
android:id="#+id/overall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="70dp"
android:numStars="5"
android:rating="0.0"
android:scaleX="0.4"
android:scaleY="0.4"
android:stepSize="0.01" />
You can use android default styles, Like:
style="#android:style/Widget.Holo.Light.RatingBar.Small"
in you xml layout. I am using above and have no space around it.
You can check variants here
I tried to use different suggestion but i was unsuccessful with the Android Rating bar removal of extra padding. All i did downloaded ic icons from https://material.io/icons/ and use star and star bordered icon and programmed them with switch cases.
While using the base style for the RatingBar, set the minHeight to 0dp. The base minHeight in the style itself was preventing the view from scaling down. Setting it to 0 should work as you expect a normal view (we set ours to wrap_content).
Tried to use the base (#android:style/Widget.RatingBar) and small (#android:style/Widget.DeviceDefault.RatingBar.Small and #android:style/Widget.Holo.Light.RatingBar.Small) but both fixed/limited the size of the the RatingBar regardless of what icon is used. Looking at their codes, it was no surprise.
<style name="Widget.RatingBar">
<item name="indeterminateOnly">false</item>
<item name="progressDrawable">#drawable/ratingbar_full</item>
<item name="indeterminateDrawable">#drawable/ratingbar_full</item>
<item name="minHeight">57dip</item>
<item name="maxHeight">57dip</item>
<item name="thumb">#null</item>
<item name="mirrorForRtl">true</item>
</style>
<style name="Widget.Material.RatingBar.Small" parent="Widget.RatingBar.Small">
<item name="progressDrawable">#drawable/ratingbar_small_material</item>
<item name="indeterminateDrawable">#drawable/ratingbar_small_material</item>
<item name="minHeight">16dp</item>
<item name="maxHeight">16dp</item>
</style>
<style name="Widget.Holo.Light.RatingBar.Small" parent="Widget.RatingBar.Small">
<item name="progressDrawable">#drawable/ratingbar_small_holo_light</item>
<item name="indeterminateDrawable">#drawable/ratingbar_small_holo_light</item>
<item name="minHeight">16dip</item>
<item name="maxHeight">16dip</item>
</style>
Setting the scales didn't work right either.
I'm trying to theme my app in Android. However, each widget is an excrutiating pain in itself: I have to search for theming that particular widget and then create a style that hopefully derives from same style that widget uses.
Of course, answers about theming a particular widget don't always contain info about base style, just the particular colors.
So, instead of accepting fish to eat, can you teach me to fish instead?
How do I interpret those ObtainStyledAttributes() calls in widget constructors and extract styles from that? How do I recurse that?
In particular, can you walk me through AlertDialog button color? What style defines lollipop flat button + teal text color? How do I get to that style if I start from AlertDialog source and ObtainStyledAttributes call?
I find that styling is about sherlocking your way through the framework. The what (almost always) comes from the widget's implementation. The where, I find is all over the place. I will try my best to explain the process through your particular use-case - AlertDialog's button(s).
Starting off:
You already have this figured out: we start with the widget's source code. We are specifically trying to find - where AlertDialog buttons get their text-color. So, we start with looking at where these buttons come from. Are they being explicitly created at runtime? Or are they defined in an xml layout, which is being inflated?
In source code, we find that mAlert handles the button options among other things:
public void setButton(int whichButton, CharSequence text, Message msg) {
mAlert.setButton(whichButton, text, null, msg);
}
mAlert is an instance of AlertController. In its constructor, we find that the attribute alertDialogStyle defines the xml layout:
TypedArray a = context.obtainStyledAttributes(null,
com.android.internal.R.styleable.AlertDialog,
com.android.internal.R.attr.alertDialogStyle, 0);
mAlertDialogLayout =
a.getResourceId(
com.android.internal.R.styleable.AlertDialog_layout,
com.android.internal.R.layout.alert_dialog);
So, the layout we should look at is alert_dialog.xml - [sdk_folder]/platforms/android-21/data/res/layout/alert_dialog.xml:
The layout xml is quite long. This is the relevant part:
<LinearLayout>
....
....
<LinearLayout android:id="#+id/buttonPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="54dip"
android:orientation="vertical" >
<LinearLayout
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="4dip"
android:paddingStart="2dip"
android:paddingEnd="2dip"
android:measureWithLargestChild="true">
<LinearLayout android:id="#+id/leftSpacer"
android:layout_weight="0.25"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone" />
<Button android:id="#+id/button1"
android:layout_width="0dip"
android:layout_gravity="start"
android:layout_weight="1"
style="?android:attr/buttonBarButtonStyle"
android:maxLines="2"
android:layout_height="wrap_content" />
<Button android:id="#+id/button3"
android:layout_width="0dip"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
style="?android:attr/buttonBarButtonStyle"
android:maxLines="2"
android:layout_height="wrap_content" />
<Button android:id="#+id/button2"
android:layout_width="0dip"
android:layout_gravity="end"
android:layout_weight="1"
style="?android:attr/buttonBarButtonStyle"
android:maxLines="2"
android:layout_height="wrap_content" />
<LinearLayout android:id="#+id/rightSpacer"
android:layout_width="0dip"
android:layout_weight="0.25"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone" />
</LinearLayout>
We now know that the buttons get the style held by attribute buttonBarButtonStyle.
Head over to [sdk_folder]/platforms/android-21/data/res/values/themes.material.xml and search for buttonBarButtonStyle:
<!-- Defined under `<style name="Theme.Material">` -->
<item name="buttonBarButtonStyle">#style/Widget.Material.Button.ButtonBar.AlertDialog</item>
<!-- Defined under `<style name="Theme.Material.Light">` -->
<item name="buttonBarButtonStyle">#style/Widget.Material.Light.Button.ButtonBar.AlertDialog</item>
Depending on what your activity's parent theme is, buttonBarButtonStyle will refer to one of these two styles. For now, let's assume your activity's theme extends Theme.Material. We'll look at #style/Widget.Material.Button.ButtonBar.AlertDialog:
Open [sdk_folder]/platforms/android-21/data/res/values/styles_material.xml and search for Widget.Material.Button.ButtonBar.AlertDialog:
<!-- Alert dialog button bar button -->
<style name="Widget.Material.Button.ButtonBar.AlertDialog" parent="Widget.Material.Button.Borderless.Colored">
<item name="minWidth">64dp</item>
<item name="maxLines">2</item>
<item name="minHeight">#dimen/alert_dialog_button_bar_height</item>
</style>
Okay. But these values don't help us in determining the button's text color. We should look at the parent style next - Widget.Material.Button.Borderless.Colored:
<!-- Colored borderless ink button -->
<style name="Widget.Material.Button.Borderless.Colored">
<item name="textColor">?attr/colorAccent</item>
<item name="stateListAnimator">#anim/disabled_anim_material</item>
</style>
At last, we find the textColor - and its supplied by attr/colorAccent initialized in Theme.Material:
<item name="colorAccent">#color/accent_material_dark</item>
For Theme.Material.Light, colorAccent is defined as:
<item name="colorAccent">#color/accent_material_light</item>
Browse to [sdk_folder]/platforms/android-21/data/res/values/colors_material.xml and locate these colors:
<color name="accent_material_dark">#color/material_deep_teal_200</color>
<color name="accent_material_light">#color/material_deep_teal_500</color>
<color name="material_deep_teal_200">#ff80cbc4</color>
<color name="material_deep_teal_500">#ff009688</color>
Screenshot of an AlertDialog and the corresponding text-color:
Shortcut:
Sometimes, its easier to read the color value (as in the picture above) and search for it using AndroidXRef. This approach would not have been useful in your case since #80cbc4 would have only pointed out that its the accent color. You would still have to locate Widget.Material.Button.Borderless.Colored and tie it with attribute buttonBarButtonStyle.
Changing button's text-color:
Ideally, we should create a style that extends Widget.Material.Button.ButtonBar.AlertDialog, override android:textColor inside it, and assign it to attribute buttonBarButtonStyle. But, this won't work - your project won't compile. This is because Widget.Material.Button.ButtonBar.AlertDialog is a non-public style and hence cannot be extended. You can confirm this by checking Link.
We'll do the next best thing - extend the parent style of Widget.Material.Button.ButtonBar.AlertDialog - Widget.Material.Button.Borderless.Colored which is public.
<style name="CusButtonBarButtonStyle"
parent="#android:style/Widget.Material.Button.Borderless.Colored">
<!-- Yellow -->
<item name="android:textColor">#ffffff00</item>
<!-- From Widget.Material.Button.ButtonBar.AlertDialog -->
<item name="android:minWidth">64dp</item>
<item name="android:maxLines">2</item>
<item name="android:minHeight">#dimen/alert_dialog_button_bar_height</item>
</style>
Note that we add 3 more items after overriding android:textColor. These are from non-public style Widget.Material.Button.ButtonBar.AlertDialog. Since we cannot extend it directly, we must include the items it defines. Note: the dimen value(s) will have to be looked up and transferred to appropriate res/values(-xxxxx)/dimens.xml files(s) in your project.
The style CusButtonBarButtonStyle will be assigned to attribute buttonBarButtonStyle. But the question is, how will an AlertDialog know of this? From the source code:
protected AlertDialog(Context context) {
this(context, resolveDialogTheme(context, 0), true);
}
Passing 0 as the second argument for resolveDialogTheme(Context, int) will end up in the else clause:
static int resolveDialogTheme(Context context, int resid) {
if (resid == THEME_TRADITIONAL) {
....
} else {
TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(
com.android.internal.R.attr.alertDialogTheme,
outValue, true);
return outValue.resourceId;
}
}
We now know that the theme is held by alertDialogTheme attribute. Next, we look at what alertDialogTheme points to. The value of this attribute will depend on your activity's parent theme. Browse to your sdk folder and find the values/themes_material.xml inside android-21. Search for alertDialogTheme. Results:
<!-- Defined under `<style name="Theme.Material">` -->
<item name="alertDialogTheme">#style/Theme.Material.Dialog.Alert</item>
<!-- Defined under `<style name="Theme.Material.Light">` -->
<item name="alertDialogTheme">#style/Theme.Material.Light.Dialog.Alert</item>
<!-- Defined under `<style name="Theme.Material.Settings">` -->
<item name="alertDialogTheme">#style/Theme.Material.Settings.Dialog.Alert</item>
So, based on what your activity's base theme is, alertDialogTheme will hold one of these 3 values. To let AlertDialog know of CusButtonBarButtonStyle, we need to override attribute alertDialogTheme in our app's theme. Say, we're using Theme.Material as the base theme.
<style name="AppTheme" parent="android:Theme.Material">
<item name="android:alertDialogTheme">#style/CusAlertDialogTheme</item>
</style>
From above, we know that alertDialogTheme points to Theme.Material.Dialog.Alert when your app's base theme is Theme.Material. So, CusAlertDialogTheme should have Theme.Material.Dialog.Alert as its parent:
<style name="CusAlertDialogTheme"
parent="android:Theme.Material.Dialog.Alert">
<item name="android:buttonBarButtonStyle">#style/CusButtonBarButtonStyle</item>
</style>
Result:
So, instead of accepting fish to eat, can you teach me to fish
instead?
In the very least, I hope to have explained where the fish are.
P.S. I realize I have posted a mammoth.
Besides #Vikram excellent answer, it's worth noting that Android Studio can simplify your work enormously. You just need to hover your mouse over the Theme, it will show something like following.
actionBarStyle = #style/Widget.AppCompat.Light.ActionBar.Solid
=> #style/Widget.AppCompat.Light.ActionBar.Solid
You can also use mouse click to navigate between styles, like what you do with normal java code.
And you can find support library's res in
<sdk root>/extras/android/m2repository/com/android/support/<support library name>/<version number>/<support library>.aar/res
But the *.aar/res/values/values.xml contains all values, and it's not easy to read. You can get the original support library code and resources in
https://android.googlesource.com/platform/frameworks/support/+/master
There is a button named tgz to download current snapshot.
I am trying to create a layout (using eclipse) in which I need to vertically align various controls like TextView and Button. I am trying to keep all the widgets perfectly left aligned. Even if I specify the same left margins/paddings for the controls, still a difference of 1-2 pixels can be seen between different types of controls.
The problem is that the distance between widget’s border (blue rectangle in eclipse) and widget’s content/graphics varies across widgets (say TextView and Button).
I can apply workarounds by either specifying left padding for TextView or by reducing the left margin of the button container. But I am looking for cleaner solution. I am unable to find any attribute which controls the difference between widget's border and content.
Any pointers on how I can control this gap ?
Snapshot demonstrating the problem is below. Here is the layout XML that I am using for this problem:-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Dummy Button" />
</LinearLayout>
The images below show the snapshot of the dummy application. Please note the difference between left side margin of "Hello World" TextView and "Dummy Button".
The second pic shows the button widget when selected in Eclipse. The blue rectangle indicates the widget boundary/border. Is the difference between button's border (blue rectangle) and content (greyed rectangle) controllable by some property ?
This is a tough one the TextView and other Android widgets may have some intrinsic styles of their own (android version dependant as well).
Therefore to get around this you would have to create your own style.
In creating your own style always reference the android source code on this subject:
https://github.com/android/platform_frameworks_base/tree/master/core/res/res/values
https://github.com/android/platform_frameworks_base/blob/master/core/res/res/values/themes.xml
https://github.com/android/platform_frameworks_base/blob/master/core/res/res/values/styles.xml
There are multiple ways to create your own style.
One way is to theme your activity in your manifest.
First you need a styles.xml file, in your /values/ folder.
In here you would declare your new style:
<style name="Theme.MyTheme.Dark" parent="#android:style/Theme.NoTitleBar">
<item name="android:textViewStyle">#style/Widget.TextView.Black</item>
</style>
<style name="Theme.MyTheme.Light" parent="#android:style/Theme.NoTitleBar">
<item name="android:textViewStyle">#style/Widget.TextView.White</item>
</style>
The style above it inheriting from the Android style that hides the title bar, you can inherit from something else.
In this theme we then override the textViewStyle, this allows us to set custom values for our TextView's and override some of the intrinsic values.
<style name="Widget.TextView.White" parent="#android:style/Widget.TextView">
<item name="android:textColor">#FFFFFF</item>
</style>
<style name="Widget.TextView.Black" parent="#android:style/Widget.TextView">
<item name="android:textColor">#000000</item>
</style>
Finally you theme your activity in the AndroidManifest.xml:
<activity
android:name=".ui.phone.FirstActivity"
android:theme="#style/Theme.MyTheme.Dark" />
<activity
android:name=".ui.phone.SecondActivity"
android:theme="#style/Theme.MyTheme.Light" />
Now when you use a TextView in the FirstActivity it's text will be Black by default and in the second activity it will be white.
For your specific question:
You would have to go look in the source code files I linked at the top and see if there is any padding or minWidth or size attributes that are affecting your widgets and your layout.
Im thinking that more "global" styles are always overridden by more "local" Styles. For example, if I redefine all Buttons to have textSize=40dip (apply that Style as a Theme for the Application) and then apply another Style to a specific Button that says textSize=10dip, then that specific Button should get 10dip textSize.
And that is how it works, usually. But not when it comes to maxHeight. Here is the scenario:
In my styles.xml I have one Style where I inherit the default Button and change textSize and minHeight, and then another Style that sets some other values (but also inherits from Button), like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Button" parent="#android:style/Widget.Button">
<item name="android:textSize">26dip</item>
<item name="android:minHeight">60dip</item>
</style>
<style name="ButtonHeader" parent="#android:style/Widget.Button">
<item name="android:textSize">18dip</item>
<item name="android:minWidth">70dip</item>
<item name="android:maxHeight">10dip</item>
</style>
</resources>
I apply the first Style as a theme for my Activity which makes all the buttons larger (minHeight=60dip). But I have a "header" (where I have some other buttons) that I do not want to have a minHeight of 60dip, and for those buttons I want to use the ButtonHeader, setting the maxHeight to 10dip.
In my header.xml it looks like this:
<Button style="#style/ButtonHeader" android:text="UPP" android:id="#+id/Header_Button_UPP" android:layout_width="wrap_content" android:layout_height="wrap_content" ></Button>
<Button style="#style/ButtonHeader" android:text="ALT" android:id="#+id/Header_Button_ALT" android:layout_width="wrap_content" android:layout_height="wrap_content" ></Button>
<Button style="#style/ButtonHeader" android:text="NAV" android:id="#+id/Header_Button_NAV" android:layout_width="wrap_content" android:layout_height="wrap_content" ></Button>
<Button style="#style/ButtonHeader" android:text="HIS" android:id="#+id/Header_Button_HIS" android:layout_width="wrap_content" android:layout_height="wrap_content" ></Button>
I am specificly styling the buttons, overriding the "global" theme. It works in some parts; the textSize for these header-buttons is correctly set to 18dip, but the maxHeight is ignored - these buttons also increase in height to 60dip.
If I, in the style for ButtonHeader, set android:minHeight="100dip" the buttons in the header will increase in size to 100dip, overriding the Theme.
But, as stated above, when I have android:maxHeight instead, nothing happens.
What am I missing?
Shouldn't your ButtonHeader style override the minHeight property? It seems like you end up with minHeight=60dp and maxHeight=10dp, and minHeight wins. If you explictly set the minHeight to something else, you shouldn't have that problem.
as I underestand you have 2 different style for Button (Button - HeaderButton) and in HeaderButton Styles you set minHieght and MaxHeight (max height isworking) and now MinHeight face with an issue,
I implement your code and find that your MinHeight is not suitable for 18dip textsize, so you should either decrease your tex size or increase minheight size
let me know, whats happen to you