In my app "Tide Now WA" which I recently tested for compatibility using
the new Nexus 9 tablet (Lollipop - API 21).
It writes some button text. This app writes the text correctly using Android 2.3 and Android
4.0. I.e. mixed capital and lower case letters.
When same app is run on my Nexus 9 all the letters
in the text are capitalized.
FWIW my manifest contains the following statement:
uses-sdk android:minSdkVersion="10" android:targetSdkVersion="14"
Can I fix this in my code or is it a bug in the O.S.
thanks
I don't have idea why it is happening but there 3 trivial attempts to make:
Use android:textAllCaps="false" in your layout-v21
Programmatically change the transformation method of the button. mButton.setTransformationMethod(null);
Check your style for Allcaps
Note: public void setAllCaps(boolean allCaps), android:textAllCaps are available from API version 14.
Here's what I did in my values/themes.xml
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="buttonStyle">#style/MyButton</item>
</style>
<style name="MyButton" parent="Widget.AppCompat.Button">
<item name="android:textAllCaps">false</item>
</style>
This is fixable in the application code by setting the button's TransformationMethod, e.g.
mButton.setTransformationMethod(null);
Set android:textAllCaps="false". If you are using an appcompat style, make sure textAllCaps comes before the style. Otherwise the style will override it. For example:
android:textAllCaps="false"
style="#style/Base.TextAppearance.AppCompat"
add this line in style
<item name="android:textAllCaps">false</item>
this one is working .... just in your code in your bottom code add this one :
android:textAllCaps="false"
it should deactivate the caps letter that U trying to type small .
Lollipop default comes with "textAllCaps true", so you have to manually make it to false
Use this line android:textAllCaps="false" in your xml
<Button
android:id="#+id/btn_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/login_str"
android:background="#color/colorBlue"
android:textColor="#color/colorWhite"
android:textAllCaps="false"
/>
Add android:textAllCaps="false" in <Button> tag that's it.
There is an easier way which works for all buttons, just change appearance of buttons in your theme, try this:
in values-21/styles.xml
<resources>
<style name="myBaseTheme"
parent="#android:style/Theme.Material.Light">
<item name="android:colorPrimary">#color/bg</item>
<item name="android:colorPrimaryDark">#color/bg_p</item>
<item name="android:textAppearanceButton">#style/textAppearanceButton</item>
</style>
<style name="textAppearanceButton" parent="#android:style/TextAppearance.Material.Widget.Button">
<item name="android:textAllCaps">false</item>
</style>
</resources>
PS: it's recommended to follow material design's principles, you should show capitalized text in Buttons, http://www.google.com/design/spec/components/buttons.html
Java:
yourButton.setAllCaps(false);
Kotlin:
yourButton.isAllCaps = false
XML:
android:textAllCaps="false"
Styles:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="buttonStyle">#style/yourButtonStyle</item>
</style>
<style name="yourButtonStyle" parent="Widget.AppCompat.Button">
<item name="android:textAllCaps">false</item>
</style>
In layout:
<Button
.
.
style="#style/yourButtonStyle"
.
.
/>
You could add android:textAllCaps="false" to the button.
The button text might be transformed to uppercase by your app's theme that applies to all buttons. Check themes / styles files for setting the attribute android:textAllCaps.
Using the android.support.v7.widget.AppCompatButton in the XML layout will allow you to avoid having to have a layout-21 or programmatically changing anything. Naturally this will also work with AppCompat v7 library.
<android.support.v7.widget.AppCompatButton
android:id="#+id/btnOpenMainDemo"
android:textAllCaps="false"
style="#style/HGButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/btn_main_demo"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"/>
Hope this helps.
In Android Studio IDE, you have to click the Filter icon to show expert properties. Then you will see the textAllCaps property. Check it, then uncheck it.
If you have arrived here because your facebook button text appears in all caps then just add this android:textAllCaps="false" in your xml file. It worked for me.
OK, just ran into this. Buttons in Lollipop come out all uppercase AND the font resets to 'normal'. But in my case (Android 5.02) it was working in one layout correctly, but not another!? Changing APIs didn't work. Setting to all caps requires min API 14 and the font still resets to 'normal'. It's because the Android Material Styles forces a change to the styles if there isn't one defined (that's why it worked in one of my layout and not the other because I defined a style). So the easy fix is to define a style in the manifest for each activity which in my case was just: android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
(hope this helps someone, would have saved me a couple of hours last night)
If you use appcompat-v7, you can subclass AppCompatButtonand setSupportAllCaps(false), then use this class for all your buttons.
/**
* Light extension of {#link AppCompatButton} that overrides ALL CAPS transformation
*/
public class Button extends AppCompatButton {
public Button(Context context, AttributeSet attrs) {
super(context, attrs);
setSupportAllCaps(false);
}
public Button(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setSupportAllCaps(false);
}
}
See AppCompatButton#setSupportAllCaps(boolean) Android docs.
By default, Button in android provides all caps keyword. If you want button text to be in lower case or mixed case you can disable textAllCaps flag using android:textAllCaps="false"
I do not know why the answer of #user1010160 got rating of 0. I would have given it +1 if I had enough reputations.
Since my app is designed for API less than 14 and I did not want to add code to my program I did not find a solution until I read his answer. What he said was that even though you have done what is needed in the Application styles it will not work unless you add a style to your activity and there you set textAllCaps to false.
It is not enough to have a style for the activity (my activity had a style), because the style might defaults to the AllCaps property. You have to set explicitly, in the activity too, that property to false.
I now have it both in the Application and in the Activity parts of the manifest file.
Another programmatic Kotlin Alternative:
mButton.transformationMethod = null
Related
According to the documentation
A Button which supports compatible features on older versions of the
platform, including:
Allows dynamic tint of its background via the background tint methods
in ViewCompat. Allows setting of the background tint using
R.attr.backgroundTint and R.attr.backgroundTintMode. This will
automatically be used when you use Button in your layouts and the
top-level activity / dialog is provided by appcompat. You should only
need to manually use this class when writing custom views.
Now, this makes me assume that the following two buttons would look exactly the same on high level devices.
<androidx.appcompat.widget.AppCompatButton
android:text="AppCompatButton"
android:id="#+id/appcompatbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:layout_below="#id/appcompatbutton"
android:id="#+id/button"
android:layout_width="wrap_content"
android:text="Button"
android:layout_height="wrap_content" />
However, here is how it actually looks:
I ran this on the following emulator:
Galaxy Nexus, API:28 (720 x 1280 xhdpi)
And when I apply buttonStyle in my appTheme like this:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="buttonStyle">#style/Widget.MaterialComponents.Button</item>
</style>
It changes the AppCompatButton but not the normal button like this:
(Note the slight difference in the rounded edges)
I also tried to create a custom button that both inherited from android.widget.Button and also androidx.appcompat.widget.AppCompatButton, both of these buttons show the same behaviour as using AppCompatButton in xml does. So it feels like the only outlier is Button in XML.
Question 1:
This all seems incredibly confusing according to me. Can someone clarify this as either a bug or feature?
EDIT 1
Doing debugging I found that the Button actually gets transformed into a MaterialButton, see the following:
Question 2:
Why is this transformation happening?
EDIT 2
Question 2 answer:
The transformation of Button to MaterialButton is due to the parent theme I was using.
Question 3:
How do you implement a custom button which works just like Button in xml would?
As a side note and personal opinion, also a slight repetition, this system is not only confusing but its hard to get it right and foolproof for future changes. In addition to this, the documentation is very poor. I would appreciate if an answer to this would be included as well, or at least a discussion regarding it, how to deal with it for example.
Short answers.
This all seems incredibly confusing according to me. Can someone clarify this as either a bug or feature?
They use different styles.
Why is this transformation happening?
There is an auto-inflation enabled which will replace <Button with <com.google.android.material.button.MaterialButton at runtime.
How do you implement a custom button which works just like Button in xml would?
You can customize the attributes in xml or the theme attributes.
Long answers.
They use different styles.
The default style of MaterialButton is Widget.MaterialComponents.Button.
This style inherits from Widget.AppCompat.Button but changes some attributes.
Here you can find the differences.
The main difference is here:
<item name="shapeAppearance">?attr/shapeAppearanceSmallComponent</item>
You can read more about shaping in the official doc.
If you navigate through the style you will find:
<style name="ShapeAppearance.MaterialComponents.SmallComponent">
<item name="cornerSize">#dimen/mtrl_shape_corner_size_small_component</item>
</style>
where mtrl_shape_corner_size_small_component = 4dp.
It explains the slight difference in the rounded edges.
Also you are using
<item name="buttonStyle">#style/Widget.MaterialComponents.Button</item>.
It doesn't work for the MaterialButton. You have to use:
<item name="materialButtonStyle">#style/Widget.MaterialComponents.Button</item>
The auto-inflation is here.
The MaterialComponentsViewInflater replaces some framework widgets with Material Components ones at inflation time, provided a Material Components theme is in use.
Something similar happens also with AppCompat (you can check that MaterialComponentsViewInflater extends AppCompatViewInflater).
It means that, the <Button is replaced <com.google.android.material.button.MaterialButton at runtime, if you are using a Material Theme.
There are different options. One of these is to define a custom style for buttons.
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
...
<item name="materialButtonStyle">#style/MyButtonStyle</item>
</style>
<style name="MyButtonStyle" parent="Widget.MaterialComponents.Button">
<item name="cornerRadius">xxx</item>
</style>
or
<style name="MyButtonStyle" parent="Widget.MaterialComponents.Button">
<item name="shapeAppearanceOverlay">#style/SShapeAppearanceOverlay.MyApp.Button.Rounded</item>
</style>
<style name="ShapeAppearanceOverlay.MyApp.Button.Rounded" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">xxdp</item>
</style>
I changed the <Button> to <ImageButton>
Quick and short way.
Don't forget to check & change references in java/kotlin files. Compiler will alert you any way.
I have a quick question!
In my styles.xml file, I have
<style name="TextViewStyle" parent="android:Widget.TextView">
<item name="android:padding">20px</item>
<item name="android:background">#9cd0e8</item>
<item name="android:textColor">#254b7c</item>
<item name="android:textSize">18sp</item>
<item name="android:textStyle">bold</item>
</style>
And in my activity_main.xml, I have
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:theme="#+styles/TextViewStyle"
android:text="Sample Text"/>
What I am trying to do is, in my Android application, on a certain activity I plan to place many TextViews with similar properties. Instead of writing these 'properties' every time with each TextView instance, I grouped them together in a style in styles.xml file and set theme of each of my TextViews to that style.
It works fine and does what I want it to do, but only with APIs above 21! My application's supposed to support devices from API level 15 up. Why is my approach not working with lower APIs?
Please help soon. I need to finish this soon.
EDIT
By 'working', I meant that the attributes I set in my style (padding, color, etc.) appear on the TextViews as they should. In lower APIs however, the TextViews appear as if I had not applied any attribute on them. Plain text appears instead of a styled one.
remove parent from your style
remove android:theme from textView, (why there is + sign?)
instead of theme put this into your textView
style="#style/TextViewStyle"
btw, use dp instead of px ;)
How to create an ImageButton without border (just the image should be visible)? One could achieve this by setting imageButton.setBackgroundDrawable(null), but this also removes the focus and selection colors.
The goal is that initially only the image without borders is visible. But when the user focuses/touches/clicks the image this should be indicated by hightlighting the image like regular buttons.
Solution in Java-Code for API 14 is preferred. Thank you!
As has been mentioned, the borderlessButtonStyle built into the default themes on API11 and above is the simplest way to achieve this effect. You mentioned you are creating your buttons in Java code instead of XML, so there are two options depending on how you need to apply the style.
Option #1: Add it to the theme
If all the Button or ImageButton instances in your application (or at least within the Activity) need to have this style applied, add the styling to your theme instead:
<resources>
<style name="AppTheme" parent="android:Theme.Holo.Light">
<!-- Default style for ImageButtons -->
<item name="android:imageButtonStyle">?android:borderlessButtonStyle</item>
<!-- Default style for Buttons -->
<item name="android:buttonStyle">?android:borderlessButtonStyle</item>
</style>
</resources>
With this theme applied to your Application or Activity, you won't have to declare the style of each element, you can just declare them as
Button button = new Button(context);
ImageButton imageButton = new ImageButton(context);
And the styling will be pulled from the theme.
Option #2: Declare it in the constructor
If only a couple buttons need to be styled this way, you can pass the style attribute you want to apply directly to each view, like so:
Button button = new Button(context, null, android.R.attr.borderlessButtonStyle);
ImageButton imageButton = new ImageButton(context, null, android.R.attr.borderlessButtonStyle);
This version supplies a different default style attribute for the widget to use.
Use borderlessButtonStyle to ImageButton
<ImageButton
style="?android:borderlessButtonStyle"
android:layout_width="58dp"
android:layout_height="wrap_content"
android:contentDescription="Delete"
android:src="#android:drawable/ic_delete" />
Ref : Google I/O 2013 - Android Design for UI Developers
Use a selector for the background like this:
/res/drawable/my_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/my_drawable" />
<item android:drawable="#android:color/transparent" />
</selector>
my_drawable is whatever drawable you want as your border.
Then your ImageButton
<ImageButton
android:layout_height="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/my_selector"
android:src="#drawable/your_bitmap" />
your_bitmap is your actual image.
Your answer is here in the Nick Butcher and Roman Nurik talk for Google I/O 2013 about android design for UI developers.
Min: 31:40:
https://www.youtube.com/watch?v=Jl3-lzlzOJI#t=31m40s
The only problem with this approach is that style="?android:borderlessButtonStyle" is available for API 11 and above so if you want the same behaviour on any API before the 11, then you will have to stick with selectors.
By the way I highly recommend you to watch the whole talk because it is really interesting.
You have to add
imageButton.setClickable(true);
imageButton.setFocusable(true);
And it will works...
That's the way in your xml file :
android:clickable="true"
android:focusable="true"
Hope this help
I hope this will help you. please give the background as transparent
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/facebookbuttonanimation"
android:background="#00000000"
/>
You can design different images for clicked/not clicked states and set them in the onTouchListener as shown in the selected answer for this SO post.
Then you can set the image back to the previous image on post longclick or click.
I've been at this for days now, and I am at the point of giving up, so any help is much appreciated!
I've been trying to implement the simonVT numberpicker in my android app. Completely new to android, so including the library, referencing this library and getting everything to compile has been a few days mission in itself. Now I finally have everything compiling I get the following error at runtime:
04-06 10:58:37.126: E/AndroidRuntime(14324): java.lang.RuntimeException:
Unable to start activity ComponentInfo{com.example.goalminder/com.example.goalminder.AddGoal}:
android.view.InflateException: Binary XML file line #81:
Error inflating class net.simonvt.numberpicker.NumberPicker
Here is the opening of my layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/net.simonvt.numberpicker"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
NB - The 'xmlns:app' part above has a yellow warning marker - it's not being used. I included this per another stackoverflow answer re. a similar problem. Have left in to discourage this suggestion.
Here is the xml for the numberpicker:
<net.simonvt.numberpicker.NumberPicker
android:id="#+id/dayPicker"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginRight="10dp"
android:layout_weight="1"/>
I have included the theme as instructed by Simon in my theme file. I wasn't really sure what name to give it, so I called it 'NumberPicker':
<resources>
<!-- Copy one of these attributes to your own theme (choose either dark or light).
<item name="numberPickerStyle">#style/NPWidget.Holo.NumberPicker</item>
<item name="numberPickerStyle">#style/NPWidget.Holo.Light.NumberPicker</item>
-->
<style name="NumberPicker" parent="android:Theme">
<item name="numberPickerStyle">#style/NPWidget.Holo.NumberPicker</item>
</style>
<style name="NumberPicker" parent="android:Theme.Light">
<item name="numberPickerStyle">#style/NPWidget.Holo.Light.NumberPicker</item>
</style>
</resources>
I have also added the following to my android manifest as a child of application:
<activity
android:name="net.simonvt.numberpicker.Numberpicker" />
<activity
android:name="net.simonvt.numberpicker.Scroller" />
I've been all over stackoverflow, so what we have above is a scatter gun approach of everything I have seen recommended so. As stated before, I'm floundering with this and am close to implementing a standard ugly list.
NB - I got all this working with the native android implementation of Numberpicker. I want to use Simon VT's backport version however as I will be looking to support API < 11, which includes Gingerbread which I believe has a 39.7% distribution. Please let me know if you think I don't need to support this far back.
you need add theme for the activity on AndroidManifest.xml:
Example:
<activity android:name="yourActivity" android:theme="#style/SampleTheme.Light"/>
If you don't want to create a theme for your own project, you may do the following to the source code of numberpicker to set it to use the default theme NPWidget_Holo_numberPicker.
Replace the constructor with the following
public NumberPicker(Context context, AttributeSet attrs) {
this(context, attrs, R.style.NPWidget_Holo_NumberPicker);
}
then change the assignment of TypedArray attributesArray to the following:
TypedArray attributesArray = context.obtainStyledAttributes(
attrs, R.styleable.NumberPicker, 0, defStyle);
See Simon's usage notes:
Requires adding a single attribute to your theme. Check the sample app for how this is done.
values/theme.xml:
<style name="SampleTheme" parent="android:Theme">
<item name="numberPickerStyle">#style/NPWidget.Holo.NumberPicker</item>
</style>
values-v11/themes.xml:
<style name="SampleTheme" parent="android:Theme.Holo">
<item name="numberPickerStyle">#style/NPWidget.Holo.NumberPicker</item>
</style>
Try replacing net.simonvt.numberpicker.NumberPicker with com.your.package.NumberPicker.
I was having practically the same problem, I was getting the error
11-18 21:13:18.627: W/ResourceType(13799): No package identifier when getting value for resource number 0x00000000
I finally realised that I had to add the style item into my own style definitions (as Paul Lammertsma shows above) as I was just copy/pasting SimonVT's styles, which of course my application wasn't using:
<style parent="#android:style/Theme.Holo.NoActionBar.Fullscreen" name="NoActionBar">
<item name="numberPickerStyle">#style/NPWidget.Holo.NumberPicker</item>
</style>
Then, after it still not working, I found I'd completely missed a themes.xml file (I have three for different API levels).
I'm having a slight issue with the Light theme and a fast scrolling ListView. As you can see in the image below, when using the Light theme the pop up for the current letter when dragging the scroll bar contains black text on a dark gray background, making it very hard to read and just look ugly.
If I override android:textColorPrimary in a Theme it changes color, but so do all the items in the ListView, as well as other UI elements elsewhere in the app, so it's not a viable solution.
I'm using GreenDroid and it's associated classes, but looking through the source code, it seems to just use a standard ListView so is unlikely to be the issue.
I also found this question, which makes it seem likely that it's not a GreenDroid issue, but unfortunately the solution given by the author in a comment doesn't explain in enough detail how to fix it.
Any ideas as to how to solve this?
Thanks,
Daniel
The easiest way to do this is to define a special Theme that you apply only to the ListActivity, like this.
<style name="Theme.MyApp" parent="#style/Theme.GreenDroid.Light.NoTitleBar">
...
</style>
<style name="Theme.MyApp.TweakedItems" parent="#style/Theme.MyApp">
...
<!-- Default color for Android Dark Theme -->
<item name="android:textColorPrimary">#android:color/primary_text_dark</item>
</style>
Then you can modify any ItemView from GreenDroid to apply a different color.
<?xml version="1.0" encoding="utf-8"?>
<greendroid.widget.itemview.TextItemView
xmlns:android="http://schemas.android.com/apk/res/android"
style="?attr/gdTextItemViewStyle"
android:id="#+id/gd_text"
android:layout_height="?attr/gdItemViewPreferredHeight"
android:minHeight="?attr/gdItemViewPreferredHeight"
android:paddingLeft="?attr/gdItemViewPreferredPaddingLeft"
android:singleLine="true"
android:ellipsize="end"
android:gravity="center_vertical"
android:textColor="#000000" />
Starting from API Level 11 you can change the color using fastScrollTextColor
i've found an answer here:
https://gist.github.com/DHuckaby/d6b1d9c8e7f9d70c39de
public class CustomListView extends ListView {
public CustomListView(Context context, AttributeSet attrs) {
super(new ContextThemeWrapper(context, R.style.CustomListView), attrs);
}
}
styles.xml
<resources>
<style name="CustomListView" parent="#style/GlobalTheme">
<item name="android:textColorPrimary">?android:textColorPrimaryInverse</item>
</style>
</resources>