I am developing an Android app for both Lollipop and Previous versions.
I am using CardView (This cardView does not have any child, it simply placed behind my View) to create shadow.
But the problem arise when it runs on the pre Lollipop devices.
so I set cardUseCompatPadding to true. I am wondering if I could get the value of this compat padding?
Is there anywhere I could find the reference to the value?
The compat padding added to the CardView depends on the elevation and the radius of the corners you have set. You can find the actual calculation in the RoundRectDrawableWithShadow class in the support library.
You can calculate it at runtime using something like:
float elevation = cardView.getMaxCardElevation();
float radius = cardView.getRadius();
double cos45 = Math.cos(Math.toRadians(45));
int horizontalPadding = (int) (elevation + (1 - cos45) * radius);
int verticalPadding = (int) (elevation * 1.5 + (1 - cos45) * radius);
Updates the backward compatible maximum elevation of the CardView.
Calling this method has no effect if device OS version is Lollipop or
newer and getUseCompatPadding() is false.
Use this code
android:elevation="3dp"or app:elevation="3dp" to your cardview
CardView uses elevation property on Lollipop for shadows and falls
back to a custom emulated shadow implementation on older platforms.
Due to expensive nature of rounded corner clipping, on platforms
before Lollipop, CardView does not clip its children that intersect
with rounded corners. Instead, it adds padding to avoid such
intersection (See setPreventCornerOverlap(boolean) to change this
behavior).
Before Lollipop, CardView adds padding to its content and draws
shadows to that area. This padding amount is equal to maxCardElevation
+ (1 - cos45) * cornerRadius on the sides and maxCardElevation * 1.5 + (1 - cos45) * cornerRadius on top and bottom.
Since padding is used to offset content for shadows, you cannot set
padding on CardView. Instead, you can use content padding attributes
in XML or setContentPadding(int, int, int, int) in code to set the
padding between the edges of the CardView and children of CardView.
Note that, if you specify exact dimensions for the CardView, because
of the shadows, its content area will be different between platforms
before Lollipop and after Lollipop. By using api version specific
resource values, you can avoid these changes. Alternatively, If you
want CardView to add inner padding on platforms Lollipop and after as
well, you can call setUseCompatPadding(boolean) and pass true.
To change CardView's elevation in a backward compatible way, use
setCardElevation(float). CardView will use elevation API on Lollipop
and before Lollipop, it will change the shadow size. To avoid moving
the View while shadow size is changing, shadow size is clamped by
getMaxCardElevation(). If you want to change elevation dynamically,
you should call setMaxCardElevation(float) when CardView is
initialized.
Related
I have an image 3264x1836 and I display it in a custom AppCompatImageView having dimensions 1280x720. I want to preserve the image size so I use ScaleType.CENTER, but I also want that its top-left corner is positioned at the coordinates 0,0 of my custom view, so I set the padding left and top accordingly.
Now, to achieve that I had to use 3264-1280 (the difference between the widths) as left padding and 1836-720 (the difference between the heights) as top padding while, in my opinion, these values should be both divided by 2.
Can somebody explain why?
It is likely that you are breaking the AppCompatImageView code by asking it to do something that wasn't anticipated or tested.
While the above could still be true, the padding that you are applying is correct. Here are the calculations:
For simplicity, let's take a look at the left padding needed to shift the graphic. The same sort of calculations will work for the top padding.
The width of the graphic is greater than the width of the ImageView.
d = wgraphic - wimageview
If the graphic is centered in the ImageView, then the overhang on the left and right sides will be 1/2 the difference in widths.
s = d / 2
The graphic is centered within the padding of the ImageView. The amount of padding that has to be specified must be just enough to shift the center of the graphic by the amount s.
The initial center of the ImageView without padding is
ci = wimageview / 2
The shifted center with left padding ( p ) is
cs = p + (wimageview - p) / 2
So,
s = cs - ci = p + (wimageview - p) / 2 - (wimageview / 2)
Solving for the padding needed for a shift of s we get p = 2s = d. In other words, the padding we need is twice the shift required which is what you are seeing.
A fix that doesn't involve padding would be to specify
android:scaleType="matrix"
You should remove the padding. The new scale type will apply the identity matrix to the image and place it in the top/left corner without resizing.
I have a project in zeplin and I have many views / layouts with
Shadows
outer
X 0dp Y 0dp
Blur 10dp Shadows 0dp
Color #000000
but I am not sure how to implement this in Android. How to specify blur shadow in Android along with a color? setShadowLayer in Paint is the only way? Most of the time I don't have a paint object though, especially for LinearLayout for example.
In my project, I am using RecyclerView in my listing using CardView. In my listing I have to set the corner radius of CardView dynamically based on device.
Is there any way to set cardview corner radius value dynamically?
Thanks.
Use CardView.setRadius(float), see androidx.cardview.
(It is worth noting that this will have no effect if you also invoke setBackgroundColor, make sure to use setCardBackgroundColor instead).
You must specify a pixel size, rather than dp value, e.g. for corner radius of 4dp you can invoke, in Kotlin:
radius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4f, context.resources.displayMetrics)
Can I Scale A Layout(e.g LinearLayout) from 0.5 to 1.0 while Keeping the size And position of the TextView inside the layout to 1.0 During the whole transformation (the overflow parts should hidden)?
I see That The Scale Animation in IOS Keep the scale of the Children And How Can I Achieve this in Android ?
Plus,On Starting Animation, The Parent Layout of the animated block has already make space for it,But in IOS ,the parent makes room gradually during the animation, does it have an option for me to do the same thing in Android ?
This can be done pretty easily with the Property Animation API.
havent tried it on LinearLayout but if the view children are ordered correctly with their "layout_width" & "layout_height" you can use the ValueAnimator class to scale the parent view via LayoutParams.width & height.
Only setback is API 11 and above.
When using a 9-patch image as a background, the padding seems to be always derived from the 9-patch image. Even if you do not use a padding bar in the 9 patch image it uses the drawable.
If the padding lines are not included, Android uses the left and top lines to define this drawable area.
http://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch
However you can override it in the XML by using android:padding=0dp or =Xdp.
Unfortunately using android:paddingLeft=Xdp does not work. So you are stuck with uniform padding.
I tried doing this:
android:padding="2dp"
android:paddingLeft="20dp"
It had no effect on the padding on the left. Placing them in a styles.xml produced similar results.
The only hack I have seen to get around this was to set the padding in code.
if (android:padding presented) it overrides all other padding values
else if (android:paddingXXX presented) it overrides bg drawable paddingXXX (XXX = Left|Right|Top|Bottom)
else if (view has drawable bg) padding values from this drawable (nine-patch in your case) will be used
else default padding will be applied (zero usually)
So do no use android:padding="2dp". padding property overrides everything. Just use paddingLeft = 20dp, paddingTop = 2dp, paddingRight = 2dp, paddingBottom = 2dp.
Or you can set paddingLeft = 20dp and other padding values will be taken from bg drawable.