Drawable padding overrides layout padding - android

I have a TextView like so:
<TextView
android:id="#+id/friends"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp" />
And I'm setting the background like:
textView.setBackgroundResource(R.drawable.background_color);
where background_color.xml is:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#217dd2" />
</shape>
</item>
<item
android:left="5dip">
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#deebf6" />
</shape>
</item>
This removes my default padding of 8dp and replaces it with the left padding of 5dp that I have declared on the 2nd item of the layered-list. Any way to avoid this? Or another way to create a 2 color background for a View?

That's known issue, setBackgroundResource method resets paddings.
Try to set your background from XML:
<TextView
android:id="#+id/friends"
android:background="#drawable/background_color"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp" />
It will work properly in this case.

Related

Ripple effect over imageview

To describe my problem i created small example.
I have linearlayout with imageview and textview. For linearlayout i've set ripple drawable as background. But when i click or long click on linearlayout ripple animation shows under imageview. How show animation over imageview ?
main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/linear"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#drawable/ripple"
android:clickable="true"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="100dp"
android:src="#mipmap/index" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is ripple test"
android:textColor="#FF00FF00" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
drawable-v21/ripple.xml:
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#FFFF0000">
<item>
<shape android:shape="rectangle">
<solid android:color="#FF000000"/>
</shape>
</item>
</ripple>
drawable/ripple.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<corners android:radius="3dp" />
<solid android:color="#FFFF0000" />
</shape>
</item>
<item android:state_focused="true">
<shape android:shape="rectangle">
<corners android:radius="3dp" />
<solid android:color="#FFFF0000" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<corners android:radius="3dp" />
<solid android:color="#FF000000" />
</shape>
</item>
</selector>
screenshot how it looks now:
Add the ripple like this
android:foreground="?android:attr/selectableItemBackground"
based on this answer https://stackoverflow.com/a/35753159/2736039
Add android:background="#null" for the ImageView
If your app needs to run on API < 23, you won't be able to use the foreground attribute on views other than FrameLayout, which means adding another [useless] level in the view tree hierarchy.
Another solution is to wrap your image with a <ripple>, set it as your ImageView's background, and use tint and tintMode to "hide" the src image so the background image that has the ripple over it is visible.
<!-- In your layout file -->
<ImageView
android:adjustViewBounds="true"
android:background="#drawable/image_with_ripple"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="#drawable/image"
android:tint="#android:color/transparent"
android:tintMode="src_in" />
<!-- drawable/image_with_ripple.xml -->
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?colorControlHighlight">
<item android:drawable="#drawable/image" />
</ripple>
Not only this works on API 21+ but if your image has rounded corners – or is another type of non-rectangle shape, like a star or a heart icon – the ripple will remain in its bounds instead of filling the view's rectangle bounds, which gives a better look in some cases.
See this Medium article for an animated GIF to see how this technique compares to using a <FrameLayout> or the foreground attribute.
Resolve for API < 21
<ImageView
android:id="#+id/favorite_season"
style="?android:attr/borderlessButtonStyle"
android:background="?android:attr/selectableItemBackground"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_margin="22dp"
android:clickable="true"
android:focusable="true"
android:src="#drawable/ic_star"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
Simple use these two lines as attribute in that ImageView.
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"

Multi color Stroke image with XML

Does it possible to create multi-color stroke with the help of XML? I want to create exact view attached here.
Thanks
You could use a trick by creating a drawable shape with gradient and make it a parent's background... something like this:
gradient_stroke.xml (in res/drawable):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle" >
<gradient
android:angle="180"
android:startColor="#fff96200"
android:centerColor="#fffff60f"
android:endColor="#fff96200"
android:centerX="50%"
>
</gradient>
<corners android:radius="5dp"></corners>
</shape>
</item>
your_view.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:padding="2dp"
android:background="#drawable/gradient_stroke"
android:layout_height="wrap_content">
<Button android:text="Submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/green"
android:id="#+id/button"/>
</LinearLayout>
Just an idea - play around with it to get desired values...

Change background Drawable padding dynamically

I want to Create a View that receives a percentage and displays only this part of background dynamically, as a parameter.
E.g. when creating a view with parameter 0.8; the background is drawn only in 80% of View width (0% padding left, 20% padding right).
I tried to create a DrawableGradient as a View background, but it overlaps whole background and I cannot resize this background.
My next choice was to create InsetDrawable or Layer-List like in this answer: Android drawable with background and gradient on the left, but I cannot change the padding dynamically.
The example I use currently:
res/layout/acitvity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="5dp"
tools:context=".MainActivity" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/percentage_background_80"
android:text="80%"
android:textSize="16sp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/percentage_background_20"
android:text="20%"
android:textSize="16sp"/>
</LinearLayout>
drawable/percentage_background_20.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:bottom="5dp"
android:drawable="#drawable/background"
android:left="5dp"
android:right="5dp"
android:top="5dp"/>
<item
android:bottom="5dp"
android:drawable="#drawable/view_background"
android:left="5dp"
android:right="200dp"
android:top="5dp"/>
</layer-list>
drawable/percentage_background_80.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:bottom="5dp"
android:drawable="#drawable/background"
android:left="5dp"
android:right="5dp"
android:top="5dp"/>
<item
android:bottom="5dp"
android:drawable="#drawable/view_background"
android:left="5dp"
android:right="50dp"
android:top="5dp"/>
</layer-list>
drawable/background.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#android:color/white" />
</shape>
drawable/view_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item><shape>
<gradient
android:angle="0"
android:startColor="#android:color/holo_blue_dark"
android:endColor="#android:color/white"
android:type="linear" />
</shape>
</item>
</selector>
This is how it looks, but I cannot change the values of padding in a list from a source code. Do you know how can I achieve it?
Clarification:
in drawable/percentage_background_80.xml and drawable/percentage_background_20.xml there are elements:
android:right="XXXdp"
I want to change the values XXXdp programatically.
either use ClipDrawable or ScaleDrawable depending on wheter you just want to clip target Drawable or resize it
Need add to:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/percentage_background_80"
android:padding="your_padding"
android:text="80%"
android:textSize="16sp"/>
This should works. For dynamically, please read this:
— how to manually set textview padding?
— Adding Margins to a dynamic Android TextView
EDIT:
Also, you may add your TextView to layout and change background, like this:
<LinearLayout
android:id=#"+id/your_id"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/percentage_background_80"
android:text="80%"
android:textSize="16sp"/>
</LinearLayout>
And in your class just use method findViewById and set background.

Gradient Background that doesn't scale

I need to create a gradient that is 230dp high (i.e., not the whole screen), with the rest of the screen a solid color. I can't figure out how to do this -- everything I try ends up with the gradient expanding to fill the whole screen. My current XML looks like this:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:top="230dp">
<shape android:shape="rectangle" >
<color android:color="#333333" />
</shape>
</item>
<item>
<shape android:shape="rectangle" >
<gradient
android:angle="270"
android:endColor="#333333"
android:startColor="#D9D9D9"
android:type="linear" />
<size android:height="230dp" />
</shape>
</item>
</layer-list>
I then apply that drawable as the background to my LinearLayout in XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#333333" >
<LinearLayout
android:id="#+id/container"
android:orientation="vertical"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:background="#drawable/grey_gradient_bg" >
<!-- a bunch of content, buttons, etc. -->
</LinearLayout>
</LinearLayout>
But the gradient expands to fill the whole screen.
I have tried using a PNG for the background, but I get the banding problems described here, and the fixes haven't helped me yet.
Use a RelativeLayout instead of a LinearLayout
Instead of using your gradient as a background of the main container of the layout, add a child View, set the height explicitly to the size you want (230dp), and set the background of that view to your gradient.
If your project doesn't require API < 21 you may set the size of your gradient directly in your drawable, like that:
<item android:height="230dp">
<shape android:shape="rectangle" >
<gradient
android:angle="270"
android:endColor="#333333"
android:startColor="#D9D9D9"
android:type="linear" />
</shape>
</item>
Anyway, to support API < 21 without this behavior, you may add this drawable and then, another drawable with the same name in the drawable-v21, but it without android:height="230dp".
Setting height in gradient tag or size really doesn't work.
Something like this might help you :)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:layout_width="fill_parent"
android:layout_height="320dip"
android:orientation="vertical"
android:background="#drawable/grey_gradient_bg">
</LinearLayout>
The problem you encountered was because your layout had fill_parent on height.
Hope this will help you.
Good luck,
Arkde
Here's my solution using the other answers:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#333333" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="230dp"
android:background="#drawable/grey_gradient_bg"
android:layout_alignParentTop="true" />
<LinearLayout
android:id="#+id/container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:layout_alignParentTop="true" >
<!-- all the content -->
</RelativeLayout>
</RelativeLayout>
grey_gradient_bg is now simple:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<gradient
android:angle="270"
android:endColor="#333333"
android:startColor="#D9D9D9"
android:type="linear" />
</shape>

how to create a pointy button on android?

How can I create a pointy button like iPhone back button in Android XML ?
I want to create using like this
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" >
<shape>
<gradient
android:startColor="#f8bb49"
android:endColor="#f7941d"
android:angle="270" />
<stroke
android:width="1dp"
android:color="#8c8382" />
<corners.....
Path and PathShape can build whatever you want. By layering a couple together and using a gradient fill you can create the 3D effect (recessed) effect.
However, you will need a class that you can use to create a drawable reference if you want to be able to use an XML definition. Sorry I have not worked out the exact code, but it's something I'm planning to do (which is how I found your question).
Looks like you have an image you can work with. Read the docs on 9-patches to set margins and resizable areas.
http://developer.android.com/guide/developing/tools/draw9patch.html
Create image like that and use ImageButton instead of Button
and , use this property for ImageButton
android:background="#drawable/createdimage"
I did this for the following back button
https://drive.google.com/file/d/0B1cySRpqElgyTkptOFpQa3NsdDQ
using the XML files:
left_arrow.xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item >
<rotate
android:fromDegrees="-45"
android:toDegrees="-45"
android:pivotX="89%"
android:pivotY="-22%" >
<shape
android:shape="rectangle" >
<stroke android:color="#color/calendarOrange" android:width="3dp"/>
<solid
android:color="#color/drakBlue" />
</shape>
</rotate>
</item>
</layer-list>
button_body.xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:left="-4dp">
<shape android:shape="rectangle" >
<stroke android:color="#color/calendarOrange" android:width="3dp"/>
<solid
android:color="#color/drakBlue" />
</shape>
</item>
</layer-list>
Getting them together:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:weightSum="1.0"
>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/left_arrow"
android:layout_weight="0.7"
>
</RelativeLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/button_body"
android:layout_weight="0.3"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textColor="#color/white"
android:text="Back"
android:gravity="center"
android:textStyle="bold"
android:textSize="22dp"
/>
</RelativeLayout>
</LinearLayout>
PS: You might need to change the android:pivotX and android:pivotY parameters depending on your conteiner layout

Categories

Resources