如何在纵向和横向的 Android 背景上创建纯色圆弧
How to create Arc with solid colour on Android background in Portrait and landscape
我当前的 Android 应用程序 UI 需要一个双色调背景和一个弯曲的圆弧作为边框,如下图所示
我可以在肖像中实现这种效果(虽然我不喜欢使用负边距值)如下...
<ImageView
android:id="@+id/backgroud_arc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="-150dp"
android:layout_marginEnd="-150dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/background_circle" />
背景圆是这个可绘制的形状
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/background" />
<size
android:width="120dp"
android:height="60dp" />
<corners
android:bottomLeftRadius="60dp"
android:bottomRightRadius="60dp" />
</shape>
有没有更简单的方法可以达到我想要的效果?
在风景中,这个可绘制对象被严重“剪裁”。
与其使用不灵活的可绘制背景,不如在 canvas 上绘制颜色和曲线。
为此,我们创建了一个自定义视图 ArcBackgroundView
,如下所示。代码不言自明:
import android.content.Context
import android.content.res.Configuration
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import android.view.View
import androidx.core.content.ContextCompat
class ArcBackgroundView(context: Context, attrs: AttributeSet) : View(context, attrs) {
private val paint = Paint()
private val path = Path()
init {
paint.isAntiAlias = true
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
if (canvas == null) {
return
}
// Draw background color
canvas.drawColor(ContextCompat.getColor(context, R.color.blue))
// Draw curve portion of background
// Setup color
paint.color = ContextCompat.getColor(context, R.color.white)
val curveStartAndEndY = 0.6f * measuredHeight // <------ You can change this value based on your requirement
// Set curve's control point's Y position (downwards bulge of curve) based on orientation
var curveControlPointY = measuredHeight / 1.4f // <------ You can change this value based on your requirement
if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
// Since in landscape mode, the curve will have greater arc length,
// we need to give the curve more downwards bulge as compared to that in portrait mode.
curveControlPointY = measuredHeight / 1.2f // <------ You can change this value based on your requirement
}
// Now we draw the entire path for curve
path.moveTo(0f, curveStartAndEndY)
path.quadTo(
measuredWidth / 2f,
curveControlPointY,
measuredWidth.toFloat(),
curveStartAndEndY
)
path.lineTo(measuredWidth.toFloat(), 0f)
path.lineTo(0f, 0f)
path.lineTo(0f, curveStartAndEndY)
canvas.drawPath(path, paint)
}
}
ArcBackgroundView
现在可以在 xml 中使用,如下所示:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.myapp.ArcBackgroundView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
纵向和横向的结果输出如下所示:
除了如图所示创建自定义视图外,如果需要,您还可以创建一个名为 ArcBackgroundFrameLayout
的自定义视图 FrameLayout
。将 onDraw() 的代码复制粘贴到您的 ArcBackgroundFrameLayout's
onDraw()
中。现在您可以直接使用自定义容器,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<com.example.myapp.ArcBackgroundFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@color/teal_200"
android:gravity="center"
android:text="THIS IS A TEXT VIEW ON TOP OF THE DUAL TONE BACKGROUND"
android:textSize="28sp"
android:textStyle="bold" />
</com.example.myapp.ArcBackgroundFrameLayout>
注意 android:background="@color/black"
添加了 ArcBackgroundFrameLayout
。必须为容器添加一些背景(不一定是黑色),否则不会调用#onDraw()。您不必担心这种黑色,因为它不会显示。我们正在从覆盖的 onDraw()
.
内部更改背景颜色
纵向和横向的结果输出如下所示:
如果您有任何其他要求,请告诉我。我会编辑这个答案。
代码在 Kotlin 中。如果您的项目在 Java,请再次告诉我。我可以编辑并提供相同的 Java 版本。
谢谢。
我当前的 Android 应用程序 UI 需要一个双色调背景和一个弯曲的圆弧作为边框,如下图所示
我可以在肖像中实现这种效果(虽然我不喜欢使用负边距值)如下...
<ImageView
android:id="@+id/backgroud_arc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="-150dp"
android:layout_marginEnd="-150dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/background_circle" />
背景圆是这个可绘制的形状
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/background" />
<size
android:width="120dp"
android:height="60dp" />
<corners
android:bottomLeftRadius="60dp"
android:bottomRightRadius="60dp" />
</shape>
有没有更简单的方法可以达到我想要的效果?
在风景中,这个可绘制对象被严重“剪裁”。
与其使用不灵活的可绘制背景,不如在 canvas 上绘制颜色和曲线。
为此,我们创建了一个自定义视图 ArcBackgroundView
,如下所示。代码不言自明:
import android.content.Context
import android.content.res.Configuration
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import android.view.View
import androidx.core.content.ContextCompat
class ArcBackgroundView(context: Context, attrs: AttributeSet) : View(context, attrs) {
private val paint = Paint()
private val path = Path()
init {
paint.isAntiAlias = true
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
if (canvas == null) {
return
}
// Draw background color
canvas.drawColor(ContextCompat.getColor(context, R.color.blue))
// Draw curve portion of background
// Setup color
paint.color = ContextCompat.getColor(context, R.color.white)
val curveStartAndEndY = 0.6f * measuredHeight // <------ You can change this value based on your requirement
// Set curve's control point's Y position (downwards bulge of curve) based on orientation
var curveControlPointY = measuredHeight / 1.4f // <------ You can change this value based on your requirement
if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
// Since in landscape mode, the curve will have greater arc length,
// we need to give the curve more downwards bulge as compared to that in portrait mode.
curveControlPointY = measuredHeight / 1.2f // <------ You can change this value based on your requirement
}
// Now we draw the entire path for curve
path.moveTo(0f, curveStartAndEndY)
path.quadTo(
measuredWidth / 2f,
curveControlPointY,
measuredWidth.toFloat(),
curveStartAndEndY
)
path.lineTo(measuredWidth.toFloat(), 0f)
path.lineTo(0f, 0f)
path.lineTo(0f, curveStartAndEndY)
canvas.drawPath(path, paint)
}
}
ArcBackgroundView
现在可以在 xml 中使用,如下所示:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.myapp.ArcBackgroundView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
纵向和横向的结果输出如下所示:
除了如图所示创建自定义视图外,如果需要,您还可以创建一个名为 ArcBackgroundFrameLayout
的自定义视图 FrameLayout
。将 onDraw() 的代码复制粘贴到您的 ArcBackgroundFrameLayout's
onDraw()
中。现在您可以直接使用自定义容器,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<com.example.myapp.ArcBackgroundFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@color/teal_200"
android:gravity="center"
android:text="THIS IS A TEXT VIEW ON TOP OF THE DUAL TONE BACKGROUND"
android:textSize="28sp"
android:textStyle="bold" />
</com.example.myapp.ArcBackgroundFrameLayout>
注意 android:background="@color/black"
添加了 ArcBackgroundFrameLayout
。必须为容器添加一些背景(不一定是黑色),否则不会调用#onDraw()。您不必担心这种黑色,因为它不会显示。我们正在从覆盖的 onDraw()
.
纵向和横向的结果输出如下所示:
如果您有任何其他要求,请告诉我。我会编辑这个答案。
代码在 Kotlin 中。如果您的项目在 Java,请再次告诉我。我可以编辑并提供相同的 Java 版本。
谢谢。