I'm working on an App and want to have an elevation effect on ImageView or any View (!CardView in support library) in Pre L APIs. But i'm not able to achieve that what i tried is used android:elevation property but it doesn't have any effect (No elevation).
I can't find any API, if someone point out any documentation to achieve this in Pre L or any snippet from Support library is highly appreciated.
If you want to set views in 3D shape, View.setElevation() and View.setTranslationZ() is a good idea.
But unfortunately, the two attributes and methods are introduced since Android API 21. So, you can't use them on pre-L or API 21- devices.
But, there is still a way to custom your views' shadows and outlines.
The bounds of a view's background drawable determine the default shape of its shadow. Outlines represent the outer shape of a graphics object and define the ripple area for touch feedback.
Consider this view, defined with a background drawable:
<TextView
android:id="#+id/myview"
...
android:elevation="2dp"
android:background="#drawable/myrect" />
The background drawable is defined as a rectangle with rounded corners:
<!-- res/drawable/myrect.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#42000000" />
<corners android:radius="5dp" />
</shape>
The view casts a shadow with rounded corners, since the background drawable defines the view's outline. Providing a custom outline overrides the default shape of a view's shadow.
To define a custom outline for a view in your code:
Extend the ViewOutlineProvider class.
Override the getOutline() method.
Assign the new outline provider to your view with the
View.setOutlineProvider() method.
You can create oval and rectangular outlines with rounded corners using the methods in the Outline class. The default outline provider for views obtains the outline from the view's background. To prevent a view from casting a shadow, set its outline provider to null.
Hopefully it helps.
P.S.:
yourAppNs:elevation="4dp" will be a good idea if you are using android-design-library.
ViewCompat.setElevation()/getElevation() doesnt work on pre Lollipop.
There isnt anything worth checking out at the support library, at least until version 21.1.1
As for creating an elevation effect by yourself
take a look at
this
Related
I'm using android.widget.CardView in my application.
In my Android 11 device, when radius is larger than the View, it will automatically adjust to half the size of the View.(I don’t know which version this was adjusted)
In the lower system version(I use Android 7.1 to test), CardView will turn into a diamond shape when the radius is larger than the View.
Anyone know why and how to solve? Thx
Very often, the Glide library is used to load images. This library can help round the edges as follows
Glide.with(context)
.load(url)
.circleCrop()
.into(imageView)
Make friends with this library and you will be happy. Not only does it help the image to take shape, but it also uses memory correctly https://github.com/bumptech/glide
P.S: In my opinion, using CardView is very limiting for you.
You could use as a root element for example a Constraint Layout and as a background use a rounded shape as you like (rectangle) and place your image inside the layout.
To hold the shape I often using the next attribute (an example is below):
app:layout_constraintDimensionRatio="W,1:2".
In your case ratio must be 1:1 because it is circle not ellipse, then you can use
app:layout_constraintDimensionRatio="W,1:1" or app:layout_constraintDimensionRatio="H,1:1"
I'm not sure if this will work in CardView, but it works well in ConstraintLayout.
Here is one of the common and most simple method to make the image get a circular border using card view in android in XML
first create a card view inside your XML and inside that create a image view with exactly 1dp less then the card view in both width and height and then try to adjust the cardCornerRadius as per your requirements, that's it it is as simple as that.
I'm using androidx.cardview.widget.CardView here.
<androidx.cardview.widget.CardView
android:layout_width="70dp"
android:layout_height="70dp"
app:cardCornerRadius="35dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true">
<ImageView
android:id="#+id/rounded_profile_img"
android:layout_width="69dp"
android:layout_height="69dp"
android:scaleType="centerCrop"/>
</androidx.cardview.widget.CardView>
Thank you hope y'll like it and it is helpful for everyone.
I've got an xml for the shape and color of my drawable :
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/light_red"/>
<corners android:radius="10dp"/>
</shape>
But I would like to use this drawable as a global one, like having the corners rounded when I'm using it, but being able to change the backgroundColor.
But when I'm trying to change the backgroundColor programatically, it overrides the color like I want but it also override the rounded corners which becomes flat.
For the moment, if I want to have rounded corners with different colors, I need to create multiple XML files with only the android:color changing.
To programmatically change a color globally defined in a shape, use this:
findViewById(R.id.your_xml_element).getBackground().setColorFilter(Color.BLUE, PorterDuff.Mode.SRC_ATOP);
Just for other people coming here after, I did some research with what you gave me, this setColorFilter is deprecated since API 29.
I found the solution for non deprecated method (a little bit longer but working):
findViewById(R.id.your_xml_element).getBackground().setColorFilter(BlendModeColorFilterCompat.createBlendModeColorFilterCompat(Color.BLUE, BlendModeCompat.SRC_ATOP));
I'm developing an application that has an embedded chat on it.
In order to draw the bubbles* where the text is displayed, I'm using a custom view which extends from FrameLayout, just like in here:
https://github.com/florent37/ShapeOfView/blob/master/shapeofview/src/main/java/com/github/florent37/shapeofview/ShapeOfView.java
or here:
https://github.com/MasayukiSuda/BubbleLayout/blob/master/bl/src/main/java/com/daasuu/bl/BubbleLayout.java
*bubbles -> you know: the rounded corner rectangle with a little arrow at the left or right, depending on who wrote the message
The thing is that, if the message to be shown is long enough (a couple of thousands of characters depending on the phone's memory) the background drawable is not shown anymore.
I found that this is expected because I'm exceeding the maximum canvas size (the maximum height, in this case)
I know that the canvas maximum size in android depends on the phone on which you are measuring it.
For example, this is the limit for an old phone (Moto G 1st gen):
And this is the limit for a newer phone, with more memory:
Question: Is there another way you can think of, to define a view with an arbitrary shape as the background which overcomes this limitation?
PD: Yes, the code looks strange because I'm using xamarin to develop, but the question is general enough, and I don't care the language of the solution if it does exist :)
UPDATE
Added example code to reproduce this issue.
You just have to create any background in xml, let's say that we call it "bubble_background.xml":
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
And then use it as background for a TextView, like in :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/bubble"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/cell_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:autoLink="all"
android:linksClickable="true"
android:textSize="#dimen/atlas_text_size_message_item"
android:layout_marginRight="8dp"
android:layout_marginLeft="8dp"
android:background="#drawable/bubble_background" />
</LinearLayout>
Now, if your text is long enough, the background won't be visible (it is a good idea to wrap the TextView in a ScrollView...)
UPDATE
This is the result of testing the background that was suggested by #cherryBu
Of course, I've got the same result because it is exactly what I was doing, but still, I had to test it, just in case, you know how this is.... :)
The top and bottom thin rectangles with round corners and the little triangle at the right (all in blue) are part of my current solution (one which doesn't make me happy but works: I'm "drawing" the bubble by composing it using those 3 partial images and setting the background of the text to the same color). The text is white, that's why you can't really see much of it. In the current code I'm setting the background to blue (not an image, because it can't be drawn -again :) -, only a plain color; the same as you can see in the other parts of the "bubble")
bubble_background.xml:
<?xml version="1.0" encoding="utf-8" ?>
<!-- For all properties see: http://developer.android.com/guide/topics/resources/menu-resource.html -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:bottomLeftRadius="20dp"
android:bottomRightRadius="20dp"
android:topLeftRadius="20dp"
android:topRightRadius="20dp" />
<padding
android:bottom="50dp"
android:left="50dp"
android:right="50dp"
android:top="50dp" />
<stroke android:width="10dp" android:color="#B2F7FE"/>
<solid android:color="#ffffff" />
</shape>
I use this as TextView background, I add very long text in it, but the shape still exist.
Update:
In case anyone is struggling with this issue: there is no solution and the maximum canvas size cannot be changed nor exceeded if you want to display a background like in this case.
Workaround solution, for my particular case:
Each bubble is composed using 4 items and a relative layout:
an image at the top, a thin blue/green rectangle with round top corners
an image at the bottom, a thin blue/green rectangle with round bottom corners
the text itself, with the same blue/green color set as background
a little blue/green triangle located at the right or left, according to who is sending the message to complete the chat bubble
I did not find any other solution and this one is working.
Of course, this won't work for you if you want to use an image instead of a plain color or simple pattern as backgournd
I'm the one who originally posted the question and the same which suggests the hacky and ugly solution from below.
I found a better and proper solution to this issue: the canvas size limit is only a problem when you have the Hardware acceleration turned on; so once I turned it off, I was able to render bubbles of any size.
The hardware acceleration can be customized in different ways and at different levels: Application, Activity, Window, or even at the View level, with some limitations.
For more information about what can and can't be done, please refer to the Goggle's documentation about this topic: https://developer.android.com/guide/topics/graphics/hardware-accel
I got a little circle TextView from Vicky Vicent ("Android: Creating a Circular TextView?")
In my situation this one should show a Level and I would like to define the background color for certain areas by myself. How can I change this one with my Activity?
<solid android:color="#9FE554" />
To change the solid color of the xml drawable resource use the below code.
GradientDrawable bgShape = (GradientDrawable)textview.getBackground();
bgShape.setColor(Color.BLACK);
I want to put 20 ImageView objects in LinearLayout rotated so that they form a circle. Is this possible and how, and is this the right approach for creating circular layout of ImageView objects?
Thanks
I'm not conversant with the android API, but it doesn't look like you can bend a LinearLayout into a circle. Rotating it should only change it's angle (horizontal versus vertical versus diagonal).
Probably, you're going to want to do something based off of an AbsoluteLayout or RelativeLayout, then perform geometry-related math to find out the positions the various elements need to be at.
Ideally, for future re-use, you should actually create a new CircularLayout that could be applied to containers. You want the API to require a List of some sort of the elements (plus optionally padding), then have the layout perform the necessary math.
LinearLayout can only present child elements either vertical or horizontal. You can position the ImageViews to form a circle if you use a RelativeLayout, but rotating them will include lots of calculations
consider using the canvas and draw paint functions
Try this:
Your XML
<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/myImageontoolbar"
android:padding="5dp"
android:layout_width="10mm"
android:layout_height="10mm"
android:layout_gravity="left"
app:srcCompat="#android:drawable/sym_def_app_icon" />
Your Gradle
compile 'de.hdodenhof:circleimageview:2.1.0'