#android #android-drawable
Вопрос:
Мой текущий пользовательский интерфейс приложения для Android требует двухцветного фона с изогнутой дугой в качестве границы, как показано на следующем рисунке
Я могу добиться этого эффекта в портрете (хотя мне не нравится использовать отрицательные значения полей) следующим образом…
<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>
Есть ли более простой метод, который я могу использовать для достижения желаемого эффекта?
В пейзаже этот рисунок очень плохо «обрезан».
Комментарии:
1. Вы можете использовать векторную графику для ваших желаемых дизайнов.
Ответ №1:
Вместо того, чтобы использовать негибкий рисоваемый фон, мы должны рисовать цвета вместе с кривой на холсте.
Для этого мы создаем пользовательский вид 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>
Результирующие выходные данные для портретной и альбомной ориентации показаны ниже:
Помимо создания пользовательского представления, как показано на рисунке, при необходимости вы также можете создать, скажем, пользовательский FrameLayout
вызов ArcBackgroundFrameLayout
. Скопируйте и вставьте код 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()
.
Результирующие выходные данные для портретной и альбомной ориентации показаны ниже:
Если у вас есть какие-либо другие требования, пожалуйста, дайте мне знать. Я отредактирую этот ответ.
Код находится в Котлине. Если ваш проект на Java, пожалуйста, дайте мне знать еще раз. Я могу отредактировать и дать Java-версию того же самого.
Спасибо.