Как создать пользовательский нарисованный в форме кольца в Android
Как можно добиться такой кривой:
2 ответа
Самым простым решением было бы использовать VectorDrawable
, Создать новый чертеж
custom_ring.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="100dp"
android:height="100dp"
android:viewportHeight="700"
android:viewportWidth="700">
<path
android:pathData="M0,0Q350,150,700,0L700,200Q400,300,0,200"
android:strokeColor="@color/colorPrimary"
android:strokeWidth="1"
android:fillColor="@color/colorYellow"/>
</vector>
А затем добавить его в качестве фона для требуемого представления
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/custom_ring" />
Подробная информация о VectorDrawables
VectorDrawables достаточно просты для понимания, и можно получить простые формы, созданные в самой Android Studio. Для более сложных фигур вам придется прибегнуть к другим инструментам для создания файлов SVG, которые впоследствии можно будет конвертировать в VectorDrawables в AS.
Подробнее см. В этом посте, чтобы получить представление о том, как работать с VectorDrawables.
Я постараюсь дать построчное объяснение для файла custom_ring.xml, который я использовал. Насколько мне известно, это правильно, хотя я открыт для предложений и исправлений.
Высота и ширина
Насколько я заметил, векторные рисунки невосприимчивы к масштабированию. Единственное условие - соотношение сторон должно быть сохранено (я могу ошибаться здесь).
Когда я впервые знакомился с чертежами, я удивлялся, почему высота и ширина были обязательными полями. Я использовал для изменения значений на разные значения и никогда не наблюдал каких-либо изменений в предварительном просмотре. Мне потребовалось больше времени, чем действительно необходимо, чтобы понять, что это значение требуется, чтобы дать правильные размеры представлению, которое его содержит. Например, если у вас есть ImageView
и установите его высоту и ширину wrap_content
ImageView
примет высоту и ширину, равные значению, установленному в свойстве Высота и ширина вектора соответственно.
Высота и ширина области просмотра
Я не могу объяснить лучше, чем это изображение
Установка окна просмотра, как у меня в посте, позволяет на самом деле рисовать (почти так же, как вы делали бы с логотипом) на координатной плоскости, координаты которой варьируются от (0,0) в верхнем левом углу до (700,700) на Нижний правый.
Путь
Ширина обводки: определяет ширину контура.
Цвет заливки: заполняет область между первой и последней точкой в данных пути цветом.
Данные пути: Вероятно, самый важный элемент и наименее понятный. Пожалуйста, прочитайте пост, который я связал выше. Это дает довольно хорошее объяснение.
M0,0
(Инструкция Moveto) перемещает курсор к координате 0,0 без рисования.
Q350,150,700,0
создает квадратичную кривую из текущей позиции курсора (которую мы получили (M0,0)) в (700,0), что является последними 2 параметрами инструкции Q. Первые 2 параметра инструкции Q (350,150) определяют форму и размер кривой. Например,
<path
android:pathData="M0,0Q350,750,700,0"
android:strokeColor="#FF0000"
android:strokeWidth="10"/>
будет генерировать эту кривую
в то время как
<path
android:pathData="M0,0Q50,750,700,0"
android:strokeColor="#FF0000"
android:strokeWidth="10"/>
сделал бы кривую как это. Обратите внимание на изменение, вызванное изменением Q350, 700 700,0 на Q50, 750 700,0
Изменение второго параметра определит амплитуду кривой.
<path
android:pathData="M0,0Q350,350,700,0"
android:strokeColor="#FF0000"
android:strokeWidth="10"/>
дам
L350,350
(Инструкция Lineto) будет рисовать линию от текущей позиции курсора до координат (350,350)
<path
android:pathData="M0,0L350,350"
android:strokeColor="#FF0000"
android:strokeWidth="10"/>
нарисует нижнюю линию
Это все, что вам нужно, чтобы выяснить, как я записал данные пути для кривой в вопросе.
Сначала установите форму в XML, как это в белом цвете
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:bottomLeftRadius="150dp"
android:bottomRightRadius="150dp"
android:topLeftRadius="0dp"
android:topRightRadius="0dp" />
<stroke
android:width="0.6dp"
android:color="@color/prefered_color" />
<padding
android:bottom="0dp"
android:left="0dp"
android:right="0dp"
android:top="0dp" />
<solid android:color="@color/white" />
</shape>
который будет производить такую форму
Снова сделайте оранжевую форму, которая будет помещена под белую форму, которая будет похожа
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:bottomLeftRadius="150dp"
android:bottomRightRadius="150dp"
android:topLeftRadius="0dp"
android:topRightRadius="0dp" />
<stroke
android:width="0.6dp"
android:color="@color/prefered_color" />
<padding
android:bottom="0dp"
android:left="0dp"
android:right="0dp"
android:top="0dp" />
<solid android:color="@color/orange" />
</shape>
Поместите оранжевую фигуру под первый макет, имеющий фон белого цвета с некоторым отрицательным значением MarginTop.