打包android阴影不见,Android无pading超简单超实用阴影解决方案
前言
這個(gè)迭代,UI在給了幾張帶陰影的圖片,那種陰影范圍很大,實(shí)際內(nèi)容卻只有一點(diǎn)的圖片。
效果類似這樣。
不知道這張圖有沒有表達(dá)清楚,就是那種圖片之間陰影需要重疊才能使內(nèi)容對(duì)其,陰影還有顏色的效果。
Android 5.0后才支持elevation屬性,還不支持陰影顏色的設(shè)定。IOS同事笑了,他們說直接把陰影效果給他們,不要帶陰影的圖片,他們天然支持陰影,可以直接繪制。
于是,上網(wǎng)搜索,發(fā)現(xiàn)目前Andorid 平臺(tái)實(shí)現(xiàn)陰影大概有這么幾種方式
2、CardView 不支持陰影顏色
3、開源庫ShadowLayout
4、模仿FloatingActionButton 實(shí)現(xiàn)陰影等等。
這些方式是可以實(shí)現(xiàn)陰影的顯示,但是基本都是將陰影作為控件的一部分去實(shí)現(xiàn)的。這樣,就需要給控件設(shè)置一些padding值,才能讓陰影顯示出來。這種方式使得布局很不方便對(duì)齊。
我的解決方案
先上效果看看
既然將陰影作為控件的一部分去實(shí)現(xiàn)不利于控件的布局和對(duì)其,那就咱就在ViewGroup里去實(shí)現(xiàn)陰影。繪制的時(shí)候根據(jù)子view的位置繪制出陰影,這樣就不會(huì)影響控件的布局和對(duì)其了。
其實(shí)我覺得控件的陰影天然就應(yīng)該在父布局去實(shí)現(xiàn),就像現(xiàn)實(shí)中的陰影那樣。
實(shí)現(xiàn)思路
1、繼承ViewGoup
Android 中有FrameLayout、LinearLayout、RelativeLayout、ConstraintLayout等等,這些layout是為了進(jìn)行子view布局而設(shè)計(jì)的,如果不進(jìn)行背景色的設(shè)置,默認(rèn)是不走ondraw方法的。
我們可以繼承這些ViewGroup,設(shè)置setWillNotDraw(false)標(biāo)志位強(qiáng)制進(jìn)行繪制,這樣我們就既擁有了布局的功能,也擁有了繪制的功能。然后就能在onDraw方法中,根據(jù)子view的位置繪制背景了。
2、復(fù)寫onDraw方法繪制子view背景
這一步很簡(jiǎn)單,一個(gè)循環(huán)遍歷子view就好了
如何繪制
1、繪制之前 需要設(shè)置 setLayerType(View.LAYER_TYPE_SOFTWARE, null)關(guān)閉硬件加速,因?yàn)橐恍└呒?jí)繪制方法可能不支持硬件加速。
2、為paint設(shè)置 shadowLayer
paint.setShadowLayer(shadowLayoutParams.shadowRadius, shadowLayoutParams.xOffset
, shadowLayoutParams.yOffset, shadowLayoutParams.shadowColor);
復(fù)制代碼
3、最后的代碼
public class ShadowConstraintLayout extends ConstraintLayout {
Paint paint;
RectF rectF = new RectF();
public ShadowConstraintLayout(Context context) {
this(context, null);
}
public ShadowConstraintLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ShadowConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// 關(guān)鍵點(diǎn),使ViewGroup調(diào)用onDraw方法
setWillNotDraw(false);
paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int childCount = getChildCount();
// 根據(jù)參數(shù)在父布局繪制背景
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
ViewGroup.LayoutParams layoutParams = child.getLayoutParams();
if (layoutParams instanceof ShadowConstraintLayout.LayoutParams) {
ShadowConstraintLayout.LayoutParams shadowLayoutParams = (LayoutParams) layoutParams;
if (shadowLayoutParams.shadowRadius > 0 && shadowLayoutParams.shadowColor != Color.TRANSPARENT) {
rectF.left = child.getLeft();
rectF.right = child.getRight();
rectF.top = child.getTop();
rectF.bottom = child.getBottom();
paint.setStyle(Paint.Style.FILL);
paint.setShadowLayer(shadowLayoutParams.shadowRadius, shadowLayoutParams.xOffset
, shadowLayoutParams.yOffset, shadowLayoutParams.shadowColor);
paint.setColor(shadowLayoutParams.shadowColor);
canvas.drawRoundRect(rectF, shadowLayoutParams.shadowRoundRadius, shadowLayoutParams.shadowRoundRadius, paint);
}
}
}
}
public static class LayoutParams extends ConstraintLayout.LayoutParams {
private float xOffset;
private float yOffset;
// 陰影顏色
private int shadowColor;
// 陰影大小
private float shadowRadius;
// 陰影圓角大小
private float shadowRoundRadius;
public LayoutParams(int width, int height) {
super(width, height);
}
public LayoutParams(ShadowConstraintLayout.LayoutParams source) {
super(source);
xOffset = source.getXOffset();
yOffset = source.getYOffset();
shadowColor = source.getShadowColor();
shadowRadius = source.getShadowRadius();
shadowRoundRadius = source.getShadowRoundRadius();
}
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
TypedArray attributes = c.obtainStyledAttributes(attrs, R.styleable.ShadowConstraintLayout_Layout);
xOffset = attributes.getDimension(R.styleable.ShadowConstraintLayout_Layout_layout_xOffset, 0);
yOffset = attributes.getDimension(R.styleable.ShadowConstraintLayout_Layout_layout_yOffset, 0);
shadowRadius = attributes.getDimension(R.styleable.ShadowConstraintLayout_Layout_layout_shadowRadius, 0);
shadowColor = attributes.getColor(R.styleable.ShadowConstraintLayout_Layout_layout_shadowColor, 0);
shadowRoundRadius = attributes.getDimension(R.styleable.ShadowConstraintLayout_Layout_layout_shadowRoundRadius, 0);
attributes.recycle();
}
public LayoutParams(ViewGroup.LayoutParams source) {
super(source);
}
public float getXOffset() {
return xOffset;
}
public void setXOffset(float xOffset) {
this.xOffset = xOffset;
}
public float getYOffset() {
return yOffset;
}
public void setYOffset(float yOffset) {
this.yOffset = yOffset;
}
public int getShadowColor() {
return shadowColor;
}
public void setShadowColor(int shadowColor) {
this.shadowColor = shadowColor;
}
public float getShadowRadius() {
return shadowRadius;
}
public void setShadowRadius(float shadowRadius) {
this.shadowRadius = shadowRadius;
}
public float getShadowRoundRadius() {
return shadowRoundRadius;
}
public void setShadowRoundRadius(float shadowRoundRadius) {
this.shadowRoundRadius = shadowRoundRadius;
}
}
public ShadowConstraintLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new ShadowConstraintLayout.LayoutParams(this.getContext(), attrs);
}
protected ShadowConstraintLayout.LayoutParams generateDefaultLayoutParams() {
return new ShadowConstraintLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
}
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new ShadowConstraintLayout.LayoutParams(p);
}
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof ShadowConstraintLayout.LayoutParams;
}
}
復(fù)制代碼
使用起來大概像這樣。
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:background="@drawable/blue_round_bg"
app:layout_shadowColor="#805468A5"
app:layout_shadowRadius="8dp"
app:layout_shadowRoundRadius="5dp"
app:layout_yOffset="2dp" />
復(fù)制代碼
目前已實(shí)現(xiàn) FrameLayout、LinearLayout、RelativeLayout、ConstraintLayout等等
添加依賴 implementation 'com.github.ZhangHao555:AndroidGroupShadow:v1.0'
總結(jié)
以上是生活随笔為你收集整理的打包android阴影不见,Android无pading超简单超实用阴影解决方案的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 数据库表格数据库数据库中
- 下一篇: html语言把字变大,css怎么让字体变