如何在圆形图像视图周围添加阴影
Posted
技术标签:
【中文标题】如何在圆形图像视图周围添加阴影【英文标题】:How to add shadow around circular imageview 【发布时间】:2016-08-31 00:25:39 【问题描述】:我想在圆形 imageView 周围添加阴影。 这是我的代码。 我想做这样的形象
这是我的 .xml 文件 检查此图像。
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_ >
<RelativeLayout
android:id="@+id/layoutTop"
android:layout_
android:layout_
android:background="#355482" >
</RelativeLayout>
<RelativeLayout
android:id="@+id/layoutBottom"
android:layout_
android:layout_
android:layout_alignParentBottom="true"
android:layout_below="@+id/layoutTop"
android:background="@drawable/loading" >
<TextView
android:id="@+id/textView1"
android:layout_
android:layout_
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="113dp"
android:text="Profile"
android:textColor="#355482"
android:textSize="20dp"
android:textStyle="bold" />
</RelativeLayout>
<ImageView
android:id="@+id/overlapImage"
android:layout_
android:layout_
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="132dp"
android:adjustViewBounds="true"
android:background="@drawable/round_image"
android:src="@drawable/ic_launcher" />
这是round_image.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#ffffff" />
<corners android:radius="2dp"/>
<size
android:
android: />
<padding
android:bottom="0dp"
android:left="0dp"
android:right="0dp"
android:top="0dp" />
</shape>
我尝试了一些阴影效果的代码,但它不起作用。
【问题讨论】:
【参考方案1】:希望对你有帮助:)
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid android:color="@color/gray"/>
<!--shadow Color-->
</shape>
</item>
<item
android:left="0dp"
android:right="0dp"
android:top="0dp"
android:bottom="3dp">
<shape android:shape="oval">
<solid android:color="@color/lightgrey"/>//Background Color
</shape>
</item>
</layer-list>
根据需要更改背景颜色和阴影颜色..
【讨论】:
和截图不一样 你需要添加渐变,而不是纯色 这可能无法满足您的需求。但它解决了@damini 提出的问题:)【参考方案2】:它比你想象的要简单得多。您的 ImageView 需要根据椭圆形背景显示为圆形,因为它默认为方形。然后你需要包括海拔,它会按你的预期显示。您不能将椭圆背景设置为透明,因为它不允许 阴影高度。
这是drawable/white_oval.xml
:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid android:color="@android:color/white"/>
</shape>
</item>
</layer-list>
现在在您的图像视图中,我将跳过您如何包含图像
<ImageView
android:id="@+id/alert_icon"
android:layout_
android:layout_
android:contentDescription="@string/your_shadow_rulez"
android:background="@drawable/white_oval"
android:elevation="@dimen/elevation_fab" />
当然要确保您的图像视图的宽度和高度都匹配。海拔越大阴影越大
see how simple and nice this looks
【讨论】:
难以置信的简单,但如此巧妙的解决方案!我想,这正是 Android 系统为 View 绘制高程的方式。太奇怪了,没有人投票给你的解决方案! 这仅适用于普通视图。拥有优雅的按钮解决方案会很酷,它已经消失了。但我想,这将涉及使用ListAnimator
。有什么想法吗?
我没有任何想法。我只尝试过用于圆形图像视图。
就是这样。
您的解决方案效果很好,但我只在底部得到阴影。我没有得到圆形阴影的任何原因?【参考方案3】:
创建一个circle_shadow.xml
文件并使用此代码,它对我很有用。根据您的要求更改半径。
circle_shadow.xml
<!-- Drop Shadow -->
<item>
<shape android:shape="oval">
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid android:color="#00CCCCCC" />
<corners android:radius="3dp" />
</shape>
</item>
<item>
<shape android:shape="oval">
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid android:color="#10CCCCCC" />
<corners android:radius="3dp" />
</shape>
</item>
<item>
<shape android:shape="oval">
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid android:color="#20CCCCCC" />
<corners android:radius="3dp" />
</shape>
</item>
<item>
<shape android:shape="oval">
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid android:color="#30CCCCCC" />
<corners android:radius="3dp" />
</shape>
</item>
<item>
<shape android:shape="oval">
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid android:color="#50CCCCCC" />
<corners android:radius="3dp" />
</shape>
</item>
<!-- Background Color (white) -->
<item>
<shape android:shape="oval">
<solid android:color="@android:color/white" />
<corners android:radius="3dp" />
</shape>
</item>
【讨论】:
永远不要使用它,用这个背景绘制 ImageView 需要 120 毫秒,而简单的 FAB 只需要 35 毫秒。为什么?透支了6次。【参考方案4】:在回答之前,我想给一些建议。您只需将问题的标题放在 Google 中即可。我试着搜索circular imageview with shadow android:
不使用库:
在 shape 标记中更改 android:color="#BDBDBD"
。
你的round_image.xml
会是这样的:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#BDBDBD" />
<corners android:radius="2dp"/>
<size
android:
android: />
<padding
android:bottom="0dp"
android:left="0dp"
android:right="0dp"
android:top="0dp" />
</shape>
使用库:
你试过这个CircularImageView
你可以使用这个库,或者如果你不想使用,那么从这个库内部的 res 文件夹中获取一些代码。
谢谢。
【讨论】:
我不能使用任何库来制作这个圆形的 imagview。我想在 imagview 周围添加阴影而不使用任何 android 库。 round_image.xml 有可能发生一些变化吗? 我尝试了你的代码,但我想制作像上面编辑过的图像。感谢您的支持 该库适用于圆形图像,但如何添加阴影或模糊边缘?【参考方案5】:在这里,我分享了我的最佳实践,即在带有一些细节的圆形图像/资源上显示阴影效果。
以上示例图片的图标为 56dp x 56dp,并使用缩放视图进行裁剪,因此看起来可能不吸引人,但在肉眼下的实际设备上效果会很好。
上面的例子是通过使用传递的:
一定程度的海拔,让阴影。 为视图提供几乎两倍高程的边距以适应阴影。 确保父视图提供几乎两倍于高度的空间以适应阴影。 创建并使用 OutlineProvider 来创建阴影。现在我们从代码开始。
<FrameLayout
android:layout_
android:layout_
android:padding="@dimen/margin_14dp"> // Point no. 3
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/img"
android:layout_
android:layout_
android:layout_margin="@dimen/margin_14dp" // Point no. 2
android:elevation="@dimen/margin_8dp" // Point no. 1
android:src="@drawable/ic_bell" />
</FrameLayout>
让我们继续指出没有。 4,这里是圆形大纲的 OutlineProvider 类。
import android.graphics.Outline;
import android.view.View;
import android.view.ViewOutlineProvider;
public class CircularOutlineProvider extends ViewOutlineProvider
@Override
public void getOutline(View view, Outline outline)
outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), (view.getWidth() / 2F));
我们留下来使用 Java/Kotlin 类中的 OutlineProvider 在运行时发挥作用。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
findViewById(R.id.img).setOutlineProvider(new CircularOutlineProvider());
魔术会议结束!
如需更多体验和增强细节,请please read the official article。
【讨论】:
【参考方案6】:在您的可绘制布局中添加此 xml 代码并将其添加到您的背景中:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<layer-list>
<item>
<shape android:shape="oval">
<gradient
android:startColor="#FF000000"
android:endColor="#00000000"
android:gradientRadius="31dp"
android:type="radial"
/>
</shape>
</item>
<item android:top="4dp" android:left="4dp" android:right="4dp" android:bottom="4dp">
<shape android:shape="oval">
<size android:
android:/>
<solid android:color="@android:color/white" />
</shape>
</item>
</layer-list>
</item>
</selector>
【讨论】:
【参考方案7】:这个类是带有阴影、描边、饱和度的自定义圆形图像视图,使用这个自定义圆形图像视图,您可以使您的图像具有半径的圆形形状。圆形阴影ImageView的家伙不需要Github这个类就足够了。将 CircularImageView 动态添加到您的根布局中。
*Adding Circular ImageView to your layout dynamically*
RelativeLayout rootLayout= (RelativeLayout) findViewById(R.id.rootLayout);
rootLayout.addView(new CircularImageView(this,200,200,imageBitmap));
public CircularImageView(Context context, int width, int height, Bitmap bitmap)
super(context);
this.context = context;
this.width = width;
this.height = height;
------> here "bitmap" is the square shape(width* width) scaled bitmap ..
this.bitmap = bitmap;
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
paint3=new Paint();
paint3.setStyle(Paint.Style.STROKE);
paint3.setColor(Color.WHITE);
paint3.setAntiAlias(true);
paintBorder = new Paint();
imagePaint= new Paint();
paintBorder.setColor(Color.WHITE);
paintBorder.setAntiAlias(true);
this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
this.bitmap2 = Bitmap.createScaledBitmap(bitmap, (bitmap.getWidth() - 40), (bitmap.getHeight() - 40), true);
imagePaint.setAntiAlias(true);
invalidate();
@Override
protected void onDraw(Canvas canvas)
super.onDraw(canvas);
Shader b;
if (bitmap3 != null)
b = new BitmapShader(bitmap3, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
else
b = new BitmapShader(bitmap2, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
imagePaint.setShader(b);
canvas.drawBitmap(maskedBitmap(), 20, 20, null);
private Bitmap maskedBitmap()
Bitmap l1 = Bitmap.createBitmap(width,width, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(l1);
paintBorder.setShadowLayer(radius, x, y, Color.parseColor("#454645"));
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
final RectF rect = new RectF();
rect.set(20, 20, bitmap2.getWidth(), bitmap2.getHeight());
canvas.drawRoundRect(rect, corner_radius, corner_radius, paintBorder);
canvas.drawRoundRect(rect, corner_radius, corner_radius, imagePaint);
if (strokeWidth!=0.0f)
paint3.setStrokeWidth(strokeWidth);
canvas.drawRoundRect(rect, corner_radius, corner_radius, paint3);
paint.setXfermode(null);
return l1;
------> use seekbar here, here you have to pass "0 -- 250" here corner radius will change ..
public void setCornerRadius(int corner_radius)
this.corner_radius = corner_radius;
invalidate();
-------->use seekbar here, here you have to pass "0 -- 10.0f" here shadow radius will change
public void setShadow(float radius)
this.radius = radius;
invalidate();
----> use seekbar here, here you have to pass "0 -- 10.0f" here stroke size will change
public void setStroke(float stroke)
this.strokeWidth = stroke;
invalidate();
private Bitmap updateSat(Bitmap src, float settingSat)
int w = src.getWidth();
int h = src.getHeight();
Bitmap bitmapResult =
Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvasResult = new Canvas(bitmapResult);
Paint paint = new Paint();
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(settingSat);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix);
paint.setColorFilter(filter);
canvasResult.drawBitmap(src, 0, 0, paint);
return bitmapResult;
--------> use seekbar here, here you have to pass "0 -- 2.0f" here saturation will change
public void setSaturation(float sat)
System.out.println("qqqqqqqqqq "+sat);
bitmap3=updateSat(bitmap2, sat);
invalidate();
--------> Seekbar to change radius
radius_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
text_radius.setText(""+progress);
circularImageView.setCornerRadius(progress);
@Override
public void onStartTrackingTouch(SeekBar seekBar)
@Override
public void onStopTrackingTouch(SeekBar seekBar)
);
// Seekbar to change shadow
shadow_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
float f= 4+progress/10.0f;
text_shadow.setText(""+progress);
circularImageView.setShadow(f);
@Override
public void onStartTrackingTouch(SeekBar seekBar)
@Override
public void onStopTrackingTouch(SeekBar seekBar)
);
// Seekbar to change saturation
saturation_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
int progressSat = saturation_seekbar.getProgress();
float sat = (float) ((progressSat*4 / 100.0f)-1.0f);
circularImageView.setSaturation(sat);
text_saturation.setText(""+progressSat);
@Override
public void onStartTrackingTouch(SeekBar seekBar)
@Override
public void onStopTrackingTouch(SeekBar seekBar)
);
// Seekbar to change stroke
stroke_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
if (progress==0)
float f=(progress*10.0f/100.0f);
circularImageView.setStroke(f);
else
float f=(progress*10.0f/100.0f);
circularImageView.setStroke(f);
text_stroke.setText(""+progress);
@Override
public void onStartTrackingTouch(SeekBar seekBar)
@Override
public void onStopTrackingTouch(SeekBar seekBar)
);
//radius seekbar in xml file
<SeekBar
android:layout_
android:layout_gravity="center"
android:progress="50"
android:max="250"
android:id="@+id/radius_seekbar"
android:layout_ />
//saturation seekbar in xml file
<SeekBar
android:layout_
android:layout_gravity="center"
android:progress="50"
android:max="100"
android:id="@+id/saturation_seekbar"
android:layout_ />
//shadow seekbar in xml file
<SeekBar
android:layout_
android:layout_gravity="center"
android:progress="0"
android:max="100"
android:id="@+id/shadow_seekbar"
android:layout_ />
//stroke seekbar in xml file
<SeekBar
android:layout_
android:layout_gravity="center"
android:progress="0"
android:max="100"
android:id="@+id/stroke _seekbar"
android:layout_ />
【讨论】:
我认为如果您可以更好地格式化您的响应,将代码引用拆分为单独的类或布局,那将非常感激。这很难浏览。以上是关于如何在圆形图像视图周围添加阴影的主要内容,如果未能解决你的问题,请参考以下文章
如何在圆形 imageView android 上添加一个阴影和边界