我在等着看是否有人会用我还不知道的东西来回答这个问题,也许他们会用我知道的东西来回答。您可以执行以下操作
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:left="5dp" android:right="5dp" android:bottom="5dp">
<shape>
<solid android:color="#FFE5E5" />
</shape>
</item>
<!-- 95dp assumes the width is 100 -->
<!-- Left side gradient -->
<item android:right="95dp" android:bottom="5dp">
<shape android:dither="true">
<gradient android:angle="180"
android:endColor="#00333333"
android:startColor="#ff333333"
android:type="linear"/>
</shape>
</item>
<!-- Right side gradient -->
<item android:left="95dp" android:bottom="5dp">
<shape android:dither="true">
<gradient android:angle="0"
android:endColor="#00333333"
android:startColor="#ff333333"
android:type="linear"/>
</shape>
</item>
<!-- Bottom gradient -->
<!-- To prevent overlap we set 10dp on left and right -->
<item android:top="95dp" android:left="5dp" android:right="5dp">
<shape android:dither="true">
<gradient android:angle="270"
android:endColor="#00333333"
android:startColor="#ff333333"
android:type="linear"/>
</shape>
</item>
<!-- Creates the left-corner gradient -->
<item android:top="95dp" android:right="95dp">
<shape android:dither="true">
<gradient android:gradientRadius="15"
android:centerX="1"
android:centerY="0"
android:endColor="#00333333"
android:startColor="#ff333333"
android:type="radial"/>
</shape>
</item>
<!-- Create the right-corner gradient -->
<item android:top="95dp" android:left="95dp">
<shape android:dither="true">
<gradient android:gradientRadius="15"
android:centerX="0"
android:centerY="0"
android:endColor="#00333333"
android:startColor="#ff333333"
android:type="radial"/>
</shape>
</item>
</layer-list>
这有两个问题使它不合理。
- gradientRadius 值不是倾角值,因此缩放到不同的屏幕尺寸会使角落的尺寸不正确。
- 用于向右移动的量 (95dp) 和底部渐变意味着在开发时必须知道大小并且不能调整大小。
我能想到的执行您想要的投影的最佳方法是将 TextView 子类化并覆盖 onDraw() 函数并手动绘制类似于我在上面的 xml 中的渐变。
例如:(更新)
@Override
protected void onDraw(Canvas canvas) {
//Gets the pixel size from dp (5)
DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
final int gradientWidth = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, metrics);
final int startColor = 0x00333333;
final int endColor = 0xff333333;
Rect clip = new Rect();
getDrawingRect(clip);
int saveNumber = canvas.save(Canvas.CLIP_SAVE_FLAG);
//Set a smaller clip rect (drawing area) so that the original background gets drawn, and our drop shadow isn't put on top
canvas.clipRect(new Rect(clip.left + gradientWidth, clip.top + gradientWidth, clip.right - gradientWidth, clip.bottom - gradientWidth), Region.Op.REPLACE);
super.onDraw(canvas);
//Return to the original clip rect
canvas.restoreToCount(saveNumber);
Paint paint = new Paint();
paint.setDither(true);
paint.setAntiAlias(true);
//The left gradient
LinearGradient leftGradient = new LinearGradient(0, 0, gradientWidth, 0, startColor, endColor, Shader.TileMode.CLAMP);
paint.setShader(leftGradient);
canvas.drawRect(0, 0, gradientWidth, getHeight() - gradientWidth, paint);
//The right gradient
LinearGradient rightGradient = new LinearGradient(getWidth() - gradientWidth, 0, getWidth(), 0, endColor, startColor, Shader.TileMode.CLAMP);
paint.setShader(rightGradient);
canvas.drawRect(getWidth() - gradientWidth, 0, getWidth(), getHeight() - gradientWidth, paint);
//The bottom gradient
canvas.save();
canvas.rotate(270, getWidth()/2, getHeight()/2);
int nX = (getWidth()/2) - (getHeight()/2);
int nY = 0 - ((getWidth()/2) - (getHeight()/2));
LinearGradient bottomGradient = new LinearGradient(nX, nY, nX + gradientWidth, nY, startColor, endColor, Shader.TileMode.CLAMP);
paint.setShader(bottomGradient);
canvas.drawRect(nX, nY + gradientWidth, nX + gradientWidth, nY + getWidth() - gradientWidth, paint);
canvas.restore();
//Draw the bottom-left corner
int doubleWidth = 2*gradientWidth;
LinearGradient leftCorner = new LinearGradient(0, 0, gradientWidth, 0, startColor, endColor, Shader.TileMode.CLAMP);
paint.setShader(leftCorner);
Bitmap b = Bitmap.createBitmap(doubleWidth, doubleWidth, Bitmap.Config.ARGB_8888);
Canvas bCanvas = new Canvas(b);
bCanvas.save();
bCanvas.rotate(315, doubleWidth/2, doubleWidth/2);
RectF leftCornerRect = new RectF(0, 0, doubleWidth, doubleWidth);
bCanvas.drawArc(leftCornerRect, 135, 90, true, paint);
bCanvas.restore();
canvas.drawBitmap(b, 0, getHeight() - doubleWidth, null);
//Draw the bottom-right corner
Matrix matrix = new Matrix();
matrix.postRotate(270);
Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, true);
canvas.drawBitmap(b2, getWidth()-doubleWidth, getHeight()-doubleWidth, null);
}
然后可以在xml中实现(修改路径为正确):
<com.so.SO_Questions.Views.SO_TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#ff000000"
android:padding="5dp"
android:layout_margin="10dp"
android:background="#7799cc"
android:text=""/>
这仍然存在一些问题,因为我目前没有时间解决它们。主要的两个是角渐变不完全匹配,所以他们需要一些调整,并且clipRect没有像我期望的那样工作,所以背景颜色正在通过。
如果您有任何问题或需要更多帮助,请告诉我。此外,如果您解决了 onDraw 的任何问题,请告诉我,我将更新我的答案,或者您可以将其添加为评论。