Ripple effect over the actual border - android

I have created a listview and added a border to it's items.
something like this:
<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content"
android:baselineAligned="false"
android:orientation="horizontal"
android:background="#drawable/listviewborderbox"
android:padding="10dp" >
<LinearLayout
android:id="#+id/sharedbyyouNameLayout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".70"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:id="#+id/sharedbyyoutext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:text="#string/sampletext1"
android:textColor="#color/blackText"
android:textSize="14sp" />
<TextView
android:id="#+id/sharedbyyouselected"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:text="#string/sampletext2"
android:textColor="#color/blackText"
android:textSize="16sp"
tools:ignore="RtlHardcoded" />
</LinearLayout>
<LinearLayout
android:id="#+id/sharedbyyouLayoutforarrow"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".10"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="#+id/arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_next"
tools:ignore="RtlSymmetry,RtlHardcoded,ContentDescription" />
</LinearLayout>
</LinearLayout>
And I have ripple effect value in Drawable-v21 like this:
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#android:color/white"> <item android:drawable="#color/footercolor"/> </ripple>
Border shape xml in drawable folder is this:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#color/colorforbodybox" />
<corners android:radius="10dip"/>
<stroke android:width="2dip" android:color="#color/colorforborder" />
</shape>
Ripple effect works but ripple effect is shown outside the border line that I have drawn. Please check pic below:
How do I make the ripple effect not to cross the border in the list view?

To achieve rounded corner ripple effect change your ripple xml file to:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#android:color/white"
tools:targetApi="lollipop">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<corners android:radius="10dp"/>
<solid android:color="#color/footercolor"/>
</shape>
</item>
</ripple>

The problem I had was that the corner radius of my views was not a fixed value therefore using the xml suggested didn't work for me.
I needed a something that would adapt the ripple effect every time regardless of the shape used so...
I used a simple view extension:
fun View.addRippleEffect(rippleColorId: Int = R.color.rippleColor) { // Here you can pass the color you want for the ripple effect and assign a "default" value
val rippleColor = ColorStateList.valueOf(ContextCompat.getColor(App.context(), rippleColorId))
this.background = RippleDrawable(
rippleColor, // This is the color of the effect and needs to be a ColorStateList
this.background, // ( = content ) With this you use your view's background as the content of the ripple effect
this.background) // ( = mask ) With this the ripple will take the shape of the background and not "spill over". (Could be null IF you did set the previous variable "content = this.background")
}
OR, if you want to separate the two layers:
fun View.addRippleEffect(rippleColorId: Int = R.color.rippleColor) {
val rippleColor = ColorStateList.valueOf(ContextCompat.getColor(App.context(), rippleColorId))
this.foreground = RippleDrawable( //Using the foreground allows you to give the view whatever background you need
rippleColor,
null, //Whatever shape you put here will cover everything you've got underneath so you probably want to keep it "null"
this.background)
}
Basically you give a view a background (rounded rectangle with borders in your case) then you can simply call the extension in your Activity/Fragment:
whateverView.addRippleEffect()
//or
whateverView.addRippleEffect(R.color.red)
See: https://developer.android.com/reference/android/graphics/drawable/RippleDrawable

1. Create the Ripple Drawable Contains the Backgound Shape
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?colorControlHighlight"> //defaul ripple color
<item>
<shape //the background shape when it's not being click
android:shape="rectangle">
<solid
android:color="#color/colorPrimary" />
<corners
android:radius="32dp" />
</shape>
</item>
</ripple>
2. Applying the Drawable to the View and REMOVE THE SHADOW
<Button
style="?borderlessButtonStyle" //remove the default shadow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/background_button" //here
android:text="Sign up"
android:textAllCaps="false"
android:textColor="#android:color/white" />

Try setting clipToOutline of your View / ViewGroup to true, either in the code or through XML, it should limit the ripple's area accordingly (as long as you background shape matches the requirements, see the docs for more details).

Related

How to merge an edittext with spinner in Android?

How can I make an EditText with a drop-down in Android?
For reference i have added an image. I am trying to combine an edittext with spinner but I am not able to achieve the same.
Can anyone add suggestion or xml mockup?
Well, You can use a LinearLayout with a horizontal orientation and create a custom drawable for the rounded border.
Implementation
First, you need to draw the rounded border by creating a new Drawable resource file.
In your res/drawables folder create rounded_border.xml
rounded_border.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<corners android:radius="4dp" />
<stroke android:width="2dp" android:color="#2E2E2E" />
</shape>
</item>
</selector>
Then, you can add the LinearLayout to your layout as follows.
your_layout.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="#drawable/rounded_border"
android:orientation="horizontal">
<EditText
android:layout_width="0dp"
android:layout_height="match_parent"
android:background="#null"
android:paddingHorizontal="16dp"
android:text="(504) 596-3245"
android:layout_weight="2"/>
<View
android:layout_width="2dp"
android:background="#2E2E2E"
android:layout_height="match_parent"/>
<Spinner
android:layout_width="0dp"
android:layout_height="match_parent"
tools:listitem="#layout/spinner_item_text"
android:layout_weight="1"/>
</LinearLayout>
Remarks
You can Customize the border width, color, and radius from the rounded_border.xml.
Final Results
could refer this lib demo : https://github.com/z2wenfa/SpinnerEditText
could use the lib directly
dependencies {
compile 'com.github.z2wenfa:SpinnerEditText:1.0.1'
}
or could refer: https://github.com/z2wenfa/SpinnerEditText/blob/master/spinneredittext-lib/src/main/java/com/z2wenfa/spinneredittext/SpinnerEditText.java

AppCompatButton getting flat after change the background color

I just updated my android Studio and every time that I try to change the background color of AppCompatButton the layout gets flat and looses the ripple effect, it wasn't like that.
And normal :
In my old project, works fine too!
<androidx.appcompat.widget.AppCompatButton
android:clickable="true"
android:onClick="Login"
android:layout_marginEnd="50dp"
android:layout_marginTop="17dp"
android:textColor="#color/primaryDarkColor"
android:layout_marginStart="50dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="12dp"
android:text="Logar"
android:focusable="true" />
A good way to change your buttons background and keep the ripple effect is to create a separate drawable for them.
So you would create a default_button_background.xml with some pre-defined colors
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/button_ripple_color">
<item>
<shape android:shape="rectangle">
<corners android:radius="#dimen/button_corner_radius" />
<solid android:color="#color/buttonBackground" />
</shape>
</item>
</ripple>
Then you can assign this drawable to your button background like:
<androidx.appcompat.widget.AppCompatButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/default_button_background"/>

CardView: How do I add a gradient background while maintaining the radius

I want to re-create the image below with a CardView. To achieve this, I created a gradient file (btn_gradient.xml) and then proceeded to create the CardView.
CardView implementation:
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="44dp"
android:layout_margin="25dp"
app:cardElevation="0dp"
app:cardCornerRadius="4dp"
app:cardPreventCornerOverlap="false">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="#drawable/btn_gradient"
android:text="Create Account"
android:textColor="#000000"
android:textStyle="bold"
android:textAllCaps="false"/>
</android.support.v7.widget.CardView>
Everything works fine this way except that the radius disappears and this is not what I want. Is there a way I can set the gradient directly on the CardView? The cardBackgroundColor attribute accepts only colors, not drawables.
Any help would be appreciated.
Addendum: As requested, this is my btn_gradient.xml file:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:type="linear"
android:angle="0"
android:startColor="#ffc200"
android:endColor="#fca10b" />
</shape>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/_10sdp"
app:cardCornerRadius="#dimen/_10sdp"
app:cardElevation="#dimen/_1sdp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#drawable/gradient_16"
android:padding="#dimen/_6sdp">
</LinearLayout>
</androidx.cardview.widget.CardView>
and gradient be like
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#5B86E5"
android:endColor="#36D1DC"
android:angle="180" />
<corners
android:radius="10dp">
</corners>
</shape>
CardView card_radius and gradient radius should be same dimentions
If I may ask, are you per-chance testing/running on a pre-lollipop Android device? Your code seems to work as you desire (curved corners showing with the gradient) except on Android 4.
To achieve the desired result on pre-lollipop devices, you can add <corners android:radius="4dp" /> to your #drawable/btn_gradient file, (you would have to set the corner radius to match the CardView's cardCornerRadius.
Move this line
android:background="#drawable/btn_gradient"
To the CardView object
UPDATE
My bad:
Inside the place a layout to wrap the content of the .
In this case, I'd go with a <FrameLayout> like this:
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLyout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/btn_gradient">
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#004e92"
android:endColor="#614385"
android:angle="90" />
<corners
android:topRightRadius="10dp"
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp"
android:topLeftRadius="10dp">
</corners>
</shape>
[![enter image description here][1]][1]
<LinearLayout 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"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
android:background="#drawable/color"
tools:context=".MainActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="10dp"
android:layout_height="100dp">
<LinearLayout
android:layout_width="match_parent"
android:background="#drawable/cardcolor"
android:layout_height="100dp">
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
</ScrollView>``
</LinearLayout>
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/iewIm.png
[1]: https://i.stack.imgur.com/pHIlW.png
I've tried integrating the gradient on card view dynamically & faced the issue that the corner radius got impacted that was set on the view property in xml file like app:cardCornerRadius="#dimen/margin_20".
Solution :
Implementing the gradient on card view. I'm getting 2 gradients from api that will be incorporated from left to right.
` try {
val startColor = sample?.gradient1
val endColor = sample?.gradient2
val colors =
intArrayOf(Color.parseColor(startColor),
Color.parseColor(endColor))
val gradientDrawable = GradientDrawable(
GradientDrawable.Orientation.LEFT_RIGHT, colors
)
myCardView.background = gradientDrawable
} catch (e: Exception) {
// default color to white
myCardView.setBackgroundColor(
ContextCompat.getColor(
mContext,
R.color.white
)
)
}`
Now on running the code, the card view renders with the gradient value but the issue occurs with the corner radius of card view that was set statically at xml. The corner radius got removed. To solve the issue, we simply use to set the radius of the gradient drawable that holds the drawable color in gradient form. Just add below 3 lines before setting the background.
gradientDrawable.colors = colors
// setting the corner radius on gradient drawable
gradientDrawable.cornerRadius = 40f
myCardView.background = gradientDrawable
The final code with gradient configuration & setting the corner radius is :
try {
val startColor = sample?.gradient1
val endColor = sample?.gradient2
val colors =
intArrayOf(Color.parseColor(startColor),
Color.parseColor(endColor))
val gradientDrawable = GradientDrawable(
GradientDrawable.Orientation.LEFT_RIGHT, colors
)
gradientDrawable.colors = colors
// setting the corner radius on gradient drawable
gradientDrawable.cornerRadius = 40f
myCardView.background = gradientDrawable
myCardView.background = gradientDrawable
} catch (e: Exception) {
// default color to white
myCardView.setBackgroundColor(
ContextCompat.getColor(
mContext,
R.color.white
)
)
}`
Screenshot for better view of code :
Hope this will help. Happy Coding :) Cheers!
Do not use android:background attribute in XML file.
use app:cardBackground instead.
To wrap it up, first create a gradient background XML file in drawables.
then assign it to the app:cardBackgroundColor like this:
app:cardBackgroundColor="#drawable/gradient_background"
if you don't know how to create the gradient_background.xml, write click on drawables directory, create new xml file and paste the code below.
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<gradient android:startColor="#color/secondaryColor"
android:endColor="#color/primaryColor"
android:angle="90"/>
</shape>

Showing contact name with initial letter in circle

I need to display the contact name initial letter inside circle like in lollipop contacts. I didn't find any solution.
The circle should different colour for each user.
You can follow this. If you wanna save time you can use this library.
Edit
The link may be invalid any point of time. So I want to add the details below this.
repositories{
maven {
url 'http://dl.bintray.com/amulyakhare/maven'
}
}
dependencies {
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
}
You can add which ever methodology you are following.
Basically you have to add one ImageView with same height and width and add this TextDrawable as a background of your view.
TextDrawable drawable = TextDrawable.builder()
.buildRect("A", Color.RED);
ImageView image = (ImageView) findViewById(R.id.image_view);
image.setImageDrawable(drawable);
The library has support for circle,square and rectangle drawables.
I didn't see any library for this but my solution is draw a circle in run time in a predefined layout in your xml use this :
How to draw circle by canvas in Android?
Then in your list adapter choose first letter of each name string using substring(0,1)
,and using setText() you can set list item textView to first letter.
If you need source code let me know to put it for you.
UPDATE:
I recently used very easy approach for this in one of my apps,
you should make a layout like this in your layout folder:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rlWeekDay"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="right"
android:layout_margin="3dp"
android:background="#drawable/circle_shape">
<TextView
android:id="#+id/tvWeekDayFirstLetter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text=" E "
android:textStyle="bold"
android:textColor="#color/colorPrimary"
android:textSize="20sp" />
</RelativeLayout>
And your shape in drawable folder as circle_shape.xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval"
android:dither="true">
<corners
android:bottomRightRadius="100dp"
android:bottomLeftRadius="100dp"
android:topLeftRadius="100dp"
android:topRightRadius="100dp"/>
<solid android:color="#ccc" />
</shape>
</item>
<item android:bottom="3dp">
<shape android:shape="oval"
android:dither="true">
<solid android:color="#color/white"/> <!-- this one is ths color of the Rounded Button -->
<corners
android:bottomRightRadius="100dp"
android:bottomLeftRadius="100dp"
android:topLeftRadius="100dp"
android:topRightRadius="100dp"/>
</shape>
</item>
</layer-list>
Then in your listView or recyclerview use this as the item to inflate.like this
Simple and small code to do this -
<com.google.android.material.button.MaterialButton
android:id="#+id/"
android:layout_width="40dp"
android:layout_height="50dp"
android:text="A"
android:clickable="false"
app:backgroundTint="#color/Blue200"
android:padding="0dp"
app:cornerRadius="50dp"
/>
By using a Material Card View and a Textview, it would be easy to create such a view.
<com.google.android.material.card.MaterialCardView
android:layout_width="50dp"
android:layout_height="50dp"
app:cardBackgroundColor="#color/red"
app:cardCornerRadius="50dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/initialTv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="AB" />
</com.google.android.material.card.MaterialCardView>

How to change background color of button with image in Android

In my Android app I have button with arrow image on the right side. On my SettingsActivity you can change the color of app (change the color of buttons and TextViews).
I changed the color of TextViews fine, but when I changed the color of buttons, the image (arrow on the right side) is gone.
Thats my code now. It change color and delete the imge.
loginButton = (Button) findViewById(R.id.btnLogin);
loginButton.setTextColor(color);
I find this on some post. But this only works for ImgageView, not for button.
loginButton = (Button) findViewById(R.id.btnLogin);
GradientDrawable bgShape = (GradientDrawable)loginButton.getBackground();
bgShape.setColor(getResources().getColor(Color.BLACK));
text.setTextColor(color);
I also tryed to change the color like this. But this does not change the color at all.
Drawable button = context.getResources().getDrawable(R.drawable.button);
button.setColorFilter(new
PorterDuffColorFilter(0xffff00,Mode.MULTIPLY));
The last thing which I hope should work is to define new drawable for every color. But this is really awful...
I also think, that the problem is not only with the image. I think this solution overrides all the drawable file...
Is there anyone who knows how to change the color of drawable and keep the image on the button?
EDIT: Just trying... I can move all colors to colors.xml file. And change the path of color to all drawable files. Like
<resource>
Color 1
Color 2
Color 3
...
</resource>
But than how can drawable files decide which color it should use?
EDIT2: Button layout:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
style="#style/bgGrey">
<RelativeLayout
android:layout_height="0dip"
android:layout_weight="30"
android:layout_width="fill_parent"
>
<TextView
...
/>
</RelativeLayout>
<LinearLayout
...>
<TextView
.../>
<EditText
.../>
<TextView
.../>
<EditText
.../>
<Button
android:id="#+id/btnLogin"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/password"
android:gravity="center|left"
android:paddingLeft="15dp"
android:layout_marginTop="10dp"
android:background="#drawable/login_button_background"
android:text="Login" />
</LinearLayout>
</LinearLayout>
Button drawable, background.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/layer"></item>
</selector>
layer.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:left="0dp" android:top="5dp" android:bottom="5dp" android:right="0dp" >
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#ffb500"/>
</shape>
</item>
<item android:left="350dp" android:top="5dp" android:bottom="5dp" android:right="5dp" >
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#ffb500"/>
</shape>
</item>
<item android:right="15dp" >
<bitmap android:src="#drawable/btn_right" android:gravity="right" android:tileMode="disabled" />
</item>
</layer-list>
An alternative approach can be: Remove the arrow from the background and set it as Compound Drawable.
As Button extends TextView, you can set drawables to the top, bottom, left or right.
In the XML, just set the property drawableRight to an arrow, or via JAVA code:
button.setCompoundDrawablesWithIntrinsicBounds (idLeft, idTop, idRight, idBottom)
So to set a right arrow:
button.setCompoundDrawablesWithIntrinsicBounds (0, 0, R.drawable.your_arrow, 0);
This way, the background is independent from the arrow, and it will be easier to modify it without creating complex versions or selectors.
There are methods and properties to adjust the drawable padding so you can place it more or less where you need it.

Categories

Resources