以下是我所做的两种方法,
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="30dp" />
<solid android:color="@color/colorAccent" />
<stroke
android:width="2dp"
android:color="@color/colorAccent" />
<gradient
android:angle="135"
android:endColor="#000"
android:startColor="#ffff"
android:type="linear" />
</shape>
通过这样做我可以得到正确的效果,但颜色似乎合并,我想要两种颜色没有任何合并效果,然后我尝试这样,
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/white">
<shape android:shape="oval">
<corners android:radius="@dimen/size_30dp" />
</shape>
</item>
<item>
<rotate
android:fromDegrees="35"
android:pivotX="0%"
android:pivotY="100%">
<shape android:shape="rectangle">
<solid android:color="@color/textColorGreyExtraLight" />
</shape>
</rotate>
</item>
</layer-list>
这种方法实际上搞砸了用户界面,我也在圆角上妥协,
所以我有什么方法可以使用XML绘制这种效果?
任何形式的帮助将不胜感激。
FYI 可绘制的宽度和高度会有所不同,因此对角线应始终从左下边缘到右上边缘。
由于
答案 0 :(得分:8)
试试这个:
@media screen and (-webkit-min-device-pixel-ratio:0) {
#your-id {
font-size: 13px;
}
}
答案 1 :(得分:1)
当您要求提供基于XML的解决方案时,我很有兴趣构建自定义Drawable
来解决您的问题。它基本上只使用自定义路径和围绕它们的边框绘制两个形状。如果为颜色添加setter或使其成为构造函数参数,您将获得应用程序主题更改时所需的灵活性。如果XML是你的方式,请随意忽略这一点,我很乐意构建它。 :)
看起来像这样:
public class CustomDrawable extends Drawable {
private final int mBorderWidth;
private final int mCornerRadius;
private final Paint mBorderPaint = new Paint();
private final Paint mTopLeftShapePaint = new Paint();
private final Paint mBottomRightShapePaint = new Paint();
private final RectF mBorderRect = new RectF();
private final Path mTopLeftShapePath = new Path();
private final Path mBottomRightShapePath = new Path();
public CustomDrawable() {
mBorderWidth = 8;
mCornerRadius = 64;
mTopLeftShapePaint.setColor(Color.parseColor("#00a2e8"));
mTopLeftShapePaint.setStyle(Paint.Style.FILL);
mTopLeftShapePaint.setAntiAlias(true);
mBottomRightShapePaint.setColor(Color.parseColor("#3f48cc"));
mBottomRightShapePaint.setStyle(Paint.Style.FILL);
mBottomRightShapePaint.setAntiAlias(true);
mBorderPaint.setColor(Color.parseColor("#3f48cc"));
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setStrokeWidth(mBorderWidth);
mBorderPaint.setAntiAlias(true);
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mBorderRect.set(bounds);
mBorderRect.inset(mBorderWidth / 2, mBorderWidth / 2);
calculatePaths();
}
private void calculatePaths() {
// Calculate position of the four corners
RectF topLeftCorner = new RectF(mBorderRect.left, mBorderRect.top, mBorderRect.left + 2 * mCornerRadius, mBorderRect.top + 2 * mCornerRadius);
RectF topRightCorner = new RectF(mBorderRect.right - 2 * mCornerRadius, mBorderRect.top, mBorderRect.right, mBorderRect.top + 2 * mCornerRadius);
RectF bottomLeftCorner = new RectF(mBorderRect.left, mBorderRect.bottom - 2 * mCornerRadius, mBorderRect.left + 2 * mCornerRadius, mBorderRect.bottom);
RectF bottomRightCorner = new RectF(mBorderRect.right - 2 * mCornerRadius, mBorderRect.bottom - 2 * mCornerRadius, mBorderRect.right, mBorderRect.bottom);
// Calculate position of intersections of diagonal line and top-right / bottom-left corner
PointF topRightCornerIntersection = calculateCircleCoordinate(topRightCorner.centerX(), topRightCorner.centerY(), 315);
PointF bottomLeftCornerIntersection = calculateCircleCoordinate(bottomLeftCorner.centerX(), bottomLeftCorner.centerY(), 135);
// Build top left shape
mTopLeftShapePath.reset();
mTopLeftShapePath.moveTo(topLeftCorner.left, topLeftCorner.centerY());
mTopLeftShapePath.lineTo(bottomLeftCorner.left, bottomLeftCorner.centerY());
mTopLeftShapePath.arcTo(bottomLeftCorner, -180, -45, false);
mTopLeftShapePath.lineTo(topRightCornerIntersection.x, topRightCornerIntersection.y);
mTopLeftShapePath.arcTo(topRightCorner, -45, -45, false);
mTopLeftShapePath.lineTo(topLeftCorner.centerX(), topLeftCorner.top);
mTopLeftShapePath.arcTo(topLeftCorner, -90, -90, false);
// Build bottom right shape
mBottomRightShapePath.reset();
mBottomRightShapePath.moveTo(bottomLeftCorner.centerX(), bottomLeftCorner.bottom);
mBottomRightShapePath.lineTo(bottomRightCorner.centerX(), bottomRightCorner.bottom);
mBottomRightShapePath.arcTo(bottomRightCorner, 90, -90, false);
mBottomRightShapePath.lineTo(topRightCorner.right, topRightCorner.centerY());
mBottomRightShapePath.arcTo(topRightCorner, 0, -45, false);
mBottomRightShapePath.lineTo(bottomLeftCornerIntersection.x, bottomLeftCornerIntersection.y);
mBottomRightShapePath.arcTo(bottomLeftCorner, 135, -45, false);
}
private PointF calculateCircleCoordinate(float centerX, float centerY, double angdeg) {
double angle = Math.toRadians(angdeg);
double x = centerX + mCornerRadius * Math.cos(angle);
double y = centerY + mCornerRadius * Math.sin(angle);
return new PointF((float) x, (float) y);
}
@Override
public void draw(@NonNull Canvas canvas) {
canvas.drawPath(mTopLeftShapePath, mTopLeftShapePaint);
canvas.drawPath(mBottomRightShapePath, mBottomRightShapePaint);
canvas.drawRoundRect(mBorderRect, mCornerRadius, mCornerRadius, mBorderPaint);
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return PixelFormat.UNKNOWN;
}
}
免责声明:此快速草案不包括边缘案例,例如:角半径对于给定的视图边界来说太大了。
答案 2 :(得分:1)
似乎,最简单的方法是以SVG
格式绘制背景并直接将其用作背景,或者,如果您想以编程方式更改颜色,则可以将SVG
转换为矢量绘图(例如, this工具)而不是用作背景。对于您的示例VectorDrawable
(two_colored_roundrect.xml
)可以是这样的:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="550dp"
android:height="390dp"
android:viewportWidth="550"
android:viewportHeight="390">
<path
android:fillColor="#00bfbf"
android:strokeColor="#003f7f"
android:strokeWidth="5"
android:pathData="M1.50016,66.028801l0,0c0,-35.411501 28.03274,-64.118481
62.611443,-64.118481l28.463097,0l0,0l136.615303,0l256.152985,0c16.605011,0
32.529999,6.75751 44.274994,18.780581c11.744995,12.0231 18.338013,28.3319
18.338013,45.3379l0,160.295204l0,0l0,96.177002l0,0c0,35.410004
-28.03302,64.11499
-62.613007,64.11499l-256.152985,0l-136.615303,0l-28.463097,0c-34.578703,0
-62.611443,-28.704987 -62.611443,-64.11499l0,0l0,-96.177002l0,0l0,-160.295204z" />
<path
android:strokeColor="#003f7f"
android:strokeWidth="5"
android:pathData="M 19.5 368.149994 L 529.5 21.149994" />
<path
android:fillColor="#003f7f"
android:strokeColor="#003f7f"
android:strokeWidth="5"
android:pathData="M529.617981,20.690901c11.744995,12.0231 18.338013,28.3319
18.338013,45.3379l0,160.295204l0,0l0,96.177002l0,0c0,35.410004
-28.03302,64.11499
-62.613007,64.11499l-256.152985,0l-136.615303,0l-28.463097,0c-17.289352,0
-32.942213,-7.176239 -44.272736,-18.778748l509.779114,-347.146349z" />
</vector>
和布局xml文件一样:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="{YOUR_CONTEXT}">
<View
android:layout_width="300dp"
android:layout_height="200dp"
android:layout_centerInParent="true"
android:background="@drawable/two_colored_roundrect"
/>
</RelativeLayout>
(View
的位置和尺寸 - 仅举例),因此你应该得到这样的结果:
您可以更改路径描边和填充的颜色,例如this问题的答案。
答案 3 :(得分:1)
我有一个库可以做到这一点。 Basicilly我绘制了2个三角形,您可以指定左角到右角或右角到左角的方向。
答案 4 :(得分:0)
所以,根据this post,现在可以使用带有矢量绘图的颜色资源。 所以你要做的是:
现在你有了drawable,用你想要使用的资源替换所有颜色。 (例如:android:fillColor="#0000"
成为android:fillColor="@color/custom_black"
)。
然后在ImageView
中,而不是android:src=""
使用app:srcCompat
来设置drawable。
不要忘记在您的gradle文件中添加vectorDrawables.useSupportLibrary = true
下的defaultConfig
。
我已经在API 19和24上进行了测试,但它确实有效。
编辑:我正在使用支持库版本26.0.2