HTC One Sets EditText padding to 0 - android

As the question states, I'm running into some weird behavior where my left drawables are not given any left padding on an HTC One running Android 4.4.
The layout where I'm seeing this is
<LinearLayout>
<include layout="#layout/search_bar" />
<!-- Some Fragment layout information -->
</LinearLayout>
Inside search_bar I have a Layout which looks like.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<EditText
android:layout_width="match_parent"
android:layout_height="56dp"
style="#style/SearchBox.SingleSearchBar" />
</FrameLayout>
The SearchBox.SingleSearchBar style looks like (after some massaging of the style hierarchy).
<style name ="SearchBox.SingleSearchBar" parent="#android:style/Widget.TextView">
<item name="android:focusable">false</item>
<item name="android:gravity">center_vertical</item>
<item name="android:singleLine">true</item>
<item name="android:lines">1</item>
<item name="android:imeOptions">actionSearch|flagNoExtractUi</item>
<item name="android:layout_centerHorizontal">true</item>
<item name="android:selectAllOnFocus">true</item>
<item name="android:drawableLeft">#drawable/gray_magnifying_glass</item>
<item name="android:scrollHorizontally">true</item>
<item name="android:paddingLeft">#dimen/search_drawable_padding</item>
<item name="android:paddingRight">#dimen/search_drawable_padding</item>
<item name="android:paddingTop">#dimen/search_drawable_padding</item>
<item name="android:paddingBottom">#dimen/search_drawable_padding</item>
<item name="android:drawablePadding">#dimen/search_drawable_padding</item>
<item name="android:maxLines">1</item>
<item name="android:background">#drawable/search_bar_selector</item>
<item name="android:textAppearance">#style/TextAppearanceSearchBox</item>
<item name="android:textCursorDrawable">#drawable/search_box_cursor</item>
</style>
On every device that I've seen except for the HTC One, this runs fine: the left drawable is padded in search_drawable_padding dips from the left, and there is appropriate padding between the drawable and the text. However, for some reason, on the HTC One, there is no padding between the left edge of the text box and the drawable.
I logged the value for both getPaddingLeft() and getPaddingTop and found that on the HTC One they are 0px, while on a Samsung GS4 they are 48 pixels, which makes sense given that search_drawable_padding is 16dips.
Is there any way around this? Am I missing something really stupid that is forcing me to call setPadding in code in order to make this work?

Please check your background drawable search_bar_selector,
<item name="android:background">#drawable/search_bar_selector</item>
Setting the background can reset the value of padding to 0 (see here).
One solution to fix this is to set the padding value again in file search_bar_selector, (Good solution, since you need not to set padding value programmatically).
<padding android:bottom="#dimen/search_drawable_padding" android:left="#dimen/search_drawable_padding" android:right="#dimen/search_drawable_padding" android:top="#dimen/search_drawable_padding" />

Related

Material Design TextInputEditText Border Color When Not Activated

I'm placing a TextInputEditText widget onto a white background. When the fragment first loads, the widget does not have focus. The border around the widget is white (or almost white), so it is invisible on a white background. Here is a screenshot of that widget, drawn on a black background for contrast:
As soon as I tap on the widget, the border becomes that of my primary color, which is exactly what I want. Here is a similar screenshot after the widget is activated.
I'm trying to control these colors through a style, and I've tried everything that I can think of, but I cannot figure out how to adjust that color. Here is my style (feel free to laugh at the various attempts):
<style name="MyTextInputLayout" parent="Base.Widget.MaterialComponents.TextInputLayout">
<item name="android:colorBackground">#android:color/black</item>
<item name="android:textColorHint">#color/colorPrimary</item>
<item name="android:paddingStart">16dp</item>
<item name="android:paddingEnd">16dp</item>
<item name="android:colorControlActivated">#android:color/black</item>
<item name="android:colorControlNormal">#android:color/black</item>
<item name="android:colorControlHighlight">#android:color/black</item>
<item name="android:backgroundTint">#android:color/black</item>
<item name="android:colorAccent">#android:color/black</item>
</style>
<style name="MyTextInputEditText" parent="ThemeOverlay.MaterialComponents.TextInputEditText">
<item name="android:textColor">#android:color/black</item>
<item name="android:colorBackground">#android:color/black</item>
<item name="android:colorControlActivated">#android:color/black</item>
<item name="android:colorControlNormal">#android:color/black</item>
<item name="android:colorControlHighlight">#android:color/black</item>
<item name="android:backgroundTint">#android:color/black</item>
<item name="android:colorAccent">#android:color/black</item>
</style>
And finally, the xml of the layout in case it is helpful:
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
style="#style/MyTextInputLayout">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/reg_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/username"
style="#style/MyTextInputEditText"/>
</com.google.android.material.textfield.TextInputLayout>
How can I change this border color when the widget is not active (i.e. does not have focus)?
I solved this in two main steps:
First problem I had was that the parent style for my TextInputLayout style needed to be changed to Widget.MaterialComponents.TextInputLayout.OutlinedBox.
Once I figured that out, I traced through the Android xml for that style and got to a file called mtrl_box_stroke_color.xml. This is a selector where the three colors for the standard TextInputLayout border are declared. That file looks like this:
So I copied that and created my own file in the res/color folder that I called edit_text_box_border.xml. I modified the three colors to suit my purposes, ultimately coming up with this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorPrimary" android:state_focused="true"/>
<item android:alpha="0.87" android:color="#color/colorPrimary" android:state_hovered="true"/>
<item android:alpha="0.12" android:color="#color/colorPrimary" android:state_enabled="false"/>
<item android:alpha="0.38" android:color="#color/colorPrimary"/>
</selector>
Then, back in my style, I had to get rid of my many color attempts and add an item for boxStrokeColor that pointed to this file. Here are both styles:
<style name="MyTextInputLayout" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<item name="android:textColorHint">#color/colorPrimary</item>
<item name="android:paddingStart">16dp</item>
<item name="android:paddingEnd">16dp</item>
<item name="boxStrokeColor">#color/edit_text_box_border</item>
</style>
<style name="MyTextInputEditText" parent="ThemeOverlay.MaterialComponents.TextInputEditText.OutlinedBox.Dense">
<item name="android:textColor">#android:color/black</item>
</style>
Now, when I run the app, I start out with this:
Which then turns into this when I tap on it:
That's what I was going for, so problem solved. Hope this helps someone.
1.
<com.google.android.material.textfield.TextInputLayout
...
style="#style/Widget.MaterialComponents.TextInputLayout.OutlineBox"
app:boxStrokeColor = "#android:color/holo_purple"
//border color when in active status
...
2. add the following in colors.xml file
<color name="mtrl_textinput_default_box_stroke_color">#00ff00</color>
//border color when in inactive status
Add
app:boxStrokeColor="#color/black"
app:hintTextColor="#color/black"
to your XML file. I tried all the color options. You can replace the "#color/black" with any color HEX code. Also write app:color and android will show you all the color options, there are many color fields that can be changed, like the error field which we can set to red to indicate the user has entered Invalid Data.
In case you need to change the outline color dynamically (for automatic field validation, for example) you can use the following hack:
Set
app:errorTextColor="#color/colorAccepted"
app:errorIconTint="#color/colorAccepted"
for TextInputLayout in xml.
Then in code:
text_input_layout.errorIconDrawable = null to remove the error icon
and text_input_layout.error = " " to enable the coloring or text_input_layout.error = null to disable it.
This way TextInputLayout takes more space. To resolve this you can customize the errorTextAppearance by defining your own style:
<style name="ErrorTextStyle" parent="TextAppearance.MaterialComponents.Caption">
<item name="android:textSize">0sp</item>
</style>
Note:
That's clearly a hack rather than a proper solution.
I use this:
<style name="TextInputLayoutTheme" parent="TextAppearance.AppCompat">
<item name="android:textColorHint">#color/secondaryTextLight</item>
<item name="android:backgroundTint" tools:targetApi="lollipop">#color/colorAccent</item>
<item name="android:textColor">#color/white</item>
<item name="colorControlActivated">#color/colorAccent</item>
</style>
and in the xml:
<com.google.android.material.textfield.TextInputEditText
style="#style/TextInputLayoutTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

Widget.AppCompat.Button.Colored Button transparent when disabled

I'm trying to fight the default behaviour of the Widget.AppCompat.Button.Colored style. By default the button is semi transparent. I want it to be opaque.
Here is my code:
Button in layout:
<Button
android:id="#+id/search"
style="#style/Widget.AppCompat.Button.Colored"
android:theme="#style/AccentButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Search"/>
styles.xml
<style name="AccentButton" parent="ThemeOverlay.AppCompat.Light">
<item name="colorAccent">#color/colorAccent</item>
<item name="colorButtonNormal">#f00</item>
</style>
If I remove the style="#style/Widget.AppCompat.Button.Colored" part the button will not turn transparent if disabled.
I've tried to look into the Appcompat/Android source code. No luck though. I can't find the part where it is set to be transparent. The goal is the get a nice solution using mostly AppCompat code. I know I can create a custom drawable button backgroud. I would like to avoid it. Any ideas?
The solution is to use: <item name="android:disabledAlpha">1.0</item> like this:
<style name="AccentButton" parent="ThemeOverlay.AppCompat.Light">
<item name="colorAccent">#color/colorAccent</item>
<item name="colorButtonNormal">#f00</item>
<item name="android:disabledAlpha">1.0</item>
</style>
How I got to this answer
After some struggle I've found btn_colored_material.xml source code.
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:alpha="?attr/disabledAlpha"
android:color="?attr/colorButtonNormal" />
<item android:color="?attr/colorAccent" />
</selector>
It uses the disabledAlpha attribute. So it was only a matter of using it.
One thing I still don't get is why I have to use it with the android: prefix. I would expect that:
?android:attr/something to be set with <item name='android:something'>(...)
?attr:something to be set with <item name='something'>(...)
My guess is that if Android soruce code code uses it's own attributes it doesn't need the prefix.

Ripple effect on toolbar which has action menu in android

I am not sure If this is happening only for me or even for others, here is what is happening:
I have set menu.xml which four icons
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.ylg.default.Home">
<item
android:id="#+id/action_key"
android:icon="#drawable/key"
android:orderInCategory="9999999"
android:title="#string/lock"
app:showAsAction="always" />
<item
android:id="#+id/action_alert"
android:icon="#drawable/bell"
android:orderInCategory="9999999"
android:title="#string/alert_action"
app:showAsAction="always" />
<item
android:id="#+id/action_home"
android:icon="#drawable/home_tool"
android:orderInCategory="9999999"
android:title="#string/office"
app:showAsAction="always" />
<item
android:id="#+id/action_logo"
android:icon="#drawable/rupees"
android:orderInCategory="9999999"
android:title="#string/home"
app:showAsAction="always" />
</menu>
The icons shows properly with ripple effect on my Nexus 5 but the problem is that the title gets cut hence I changed the padding values for icons (Right and left) in my style using:
<style name="Theme.default" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:actionButtonStyle">#style/MyActionButtonStyle</item>
</style>
<style name="MyActionButtonStyle" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:minWidth">40dp</item>
<item name="android:paddingLeft">2dp</item>
<item name="android:paddingRight">2dp</item>
</style>
If I put this the menu icons reduces their spacing between each other but ripple effect is not seen when I touch the icons.
I am not sure why this happening? Anybody there who can help me with this?
Thanks!
The parent you've used for MyActionButtonStyle has no proper background. The parent should be Widget.AppCompat.Light.ActionButton.
<style name="MyActionButtonStyle" parent="Widget.AppCompat.Light.ActionButton">
But anyway that's not a good idea reducing the space between the menu items. Instead, use
app:showAsAction="ifRoom"
So items that do not fit will be put into overflow. This is necessary because there is always a smaller dp screen that Nexus 5 resulting in title being cut even more. The lint should have warned you about this.

Changing height of buttons

I'm trying to change the height of a couple of buttons in my app.
I have tried setting #android:color/transparent as the android:background and I have also tried setting a layout_height to values like 16dp.
How could I give my buttons a smaller height?
Here is the style xml:
<style name="Theme.PMBAppTheme.TextButton">
<item name="android:textStyle">bold</item>
<item name="android:textSize">14sp</item>
<item name="android:textColor">#drawable/text_button_text</item>
<item name="android:background">#ff3300</item>
<item name="android:padding">0dp</item>
<item name="android:height">20sp</item>
</style>
And the layout:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/register_btn_privacy"
android:text="#string/privacy_policy"
style="#style/Theme.PMBAppTheme.TextButton"
/>
text_button_text:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_focused="true" android:state_pressed="true" android:color="#color/muted_pink_over" />
<item android:state_focused="false" android:state_pressed="true" android:color="#color/muted_pink_over" />
<item android:color="#color/muted_pink" />
</selector>
set the height of the button to wrap_content:
android:layout_height="wrap_content"
That should set the height of the button to its minimum to display its text.
In Vapor API (a jQuery style framework for Android I just released) there is a method you can use called .size(int,int). This sets the size of your View depending on the type of container in which it sits. So something like:
$.Button(R.id.register_btn_privacy).size(int width, int height);
What's cool is, you can also chain calls to adjust the other properties of your View. For example:
$.Button(R.id.register_btn_privacy)
.size(50,100) // set size
.text("Privacy Policy") // set the text
.bgColor(Color.RED) // set the background color
.color(Color.WHITE); // set the text color
Check it out if you're interested at the Vapor API website, it's basically designed to make Android dev a lot easier and like using jQuery.
Remove this from your style
<item name="android:height">20sp</item>
So you end up with
<style name="Theme.PMBAppTheme.TextButton">
<item name="android:textStyle">bold</item>
<item name="android:textSize">14sp</item>
<item name="android:textColor">#drawable/text_button_text</item>
<item name="android:background">#ff3300</item>
<item name="android:padding">0dp</item>
</style>
Button inherits from TextView and according to TextView android:height, this is probably setting the height exactly and causing it to ignore your layout_height.

How to overflow views to the next row, instead of disappearing into the unknown

I am trying to fit TextViews in the screen, so that every textview contains 1 word of a long sentence.
This is a very long sentence, so long that it does not
fit in the screen.
Here fit in the screen are 4 textviews, which I need to move to the next line. Basically, this way I can get click events for each word (since I need to support Android 2.2, and Spannable needs getX and getY that 2.2 does not support).
Layout
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:fitsSystemWindows="true"
android:orientation="horizontal" >
<TextView
android:id="#+id/word1"
style="#style/select_part_of_speech_word" />
<TextView
android:id="#+id/word2"
style="#style/select_part_of_speech_word" />
..... more TextViews.....
<TextView
android:id="#+id/word15"
style="#style/select_part_of_speech_word" />
</LinearLayout>
Style applied
<style name="select_part_of_speech_word" parent="#android:style/TextAppearance.Medium">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginBottom">10dp</item>
<item name="android:layout_marginTop">10dp</item>
<item name="android:text">#string/randomTutorialText</item>
<item name="android:textColor">#android:color/black</item>
<item name="android:textSize">25sp</item>
<item name="android:visibility">visible</item>
<item name="android:lines">1</item>
</style>
With this, the textviews just seem to disappear. I guess if I use a horizontal scrollview, I will be able to view all 15 textviews, but I need them to overflow to the next available space below. Can this be done ?
So you want something equivalent to a FlowLayout.
You could try Romain Guy's implementation.

Categories

Resources