Нативная разработка мобильных приложений


Как создать свое представление



Download 3,69 Mb.
Pdf ko'rish
bet47/228
Sana21.07.2022
Hajmi3,69 Mb.
#834838
1   ...   43   44   45   46   47   48   49   50   ...   228
Bog'liq
Нативная разработка мобильных приложений

Как создать свое представление
Типичным подходом к созданию своего представления является определе
-
ние класса, наследующего класс 
View

V
iewGroup
или один из существующих их 
подклассов, и добавление в него своих функциональных возможностей. Воз
-
можности пользовательского представления несколько ограничены – он мо
-
жет изменять уже нарисованное (текст, цвета, фигуры) или то, что ему под
-
чинено. Первое можно реализовать с помощью метода 
onDraw
класса 
View
. Этот 
метод принимает один параметр – предварительно заполненный экземпляр 
Canvas
, имеющий те же размеры, что и само представление. Более подробно 
о доступных возможностях объекта 
Canvas
можно узнать в документации для 
разработчика, но если говорить кратко, здесь можно делать все, что угодно. Вы 
можете вызывать методы для рисования, вывода текста и отображения гео
-
метрических фигур. Можно также использовать геометрические классы, такие 
как 
Rect
или 
Path
, для отображения более сложных структур, и объекты 
Paint
для 
настройки цвета, заливки или текстуры.
Например, следующий простой подкласс 
View
рисует красный круг (точнее, 
овал), вписанный в границы представления:
Java
public class Oval extends View {
private Paint mPaint = new Paint();
{
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.FILL);
}
public Oval(Context context) {
super(context);
}
public Oval(Context context, AttributeSet attrs) {
super(context, attrs);
}
public Oval(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawOval(0, 0, getWidth(), getHeight(), mPaint);
}
}


62

Пользовательские компоненты
Kotlin
class Oval @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null,
defStyleAttr: Int = 0, defStyleRes: Int = 0) : View(context, attrs, defStyleAttr,
defStyleRes) {
private val paint = Paint()
init {
paint.color = Color.RED
paint.style = Paint.Style.FILL
}
override fun onDraw(canvas: Canvas) {
canvas.drawOval(0f, 0f, width.toFloat(), height.toFloat(), paint)
}
}
Как видите, есть возможность определить свои методы для настройки цвета 
или добавить свое свойство 
Paint
для вывода растрового изображения, созда
-
ния теней или градиентов.
Аналогично можно определить подкласс 
TextView
, который всегда выводит 
рамку вдоль нижней границы, например для использования в 
LinearLayout
или 
RecyclerView
:
Java
public class BottomBorderTextView extends TextView {
private Paint mPaint = new Paint();
{
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.BLACK);
}
public BottomBorderTextView(Context context) {
super(context);
}
public BottomBorderTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public BottomBorderTextView(Context context, @Nullable AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
// не забывайте вызывать super.onDraw для вывода текста, фона, смежных
// элементов и пр.
super.onDraw(canvas);
canvas.drawLine(0, getHeight(), getWidth(), getHeight(), mPaint);
}
}


Android 

63
Kotlin
class BottomBorderTextView @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0, defStyleRes: Int = 0) :
TextView(context, attrs, defStyleAttr, defStyleRes) {
private val paint = Paint()
init {
paint.style = Paint.Style.FILL
paint.color = Color.RED
}
override fun onDraw(canvas: Canvas) {
// не забывайте вызывать super.onDraw для вывода текста, фона, смежных
// элементов и пр.
super.onDraw(canvas)
canvas.drawLine(0, height, width, height, paint)
}
}
Также можно добавить новый метод для изменения цвета рамки или ее пе
-
рерисовывания:
Java
public void setBorderColor(int color) {
mPaint.setColor(color);
// вызов invalidate уведомляет систему о необходимости перерисовать 
// представление при отображении следующего кадра
invalidate();
}
Kotlin
fun setBorderColor(color: Int) {
paint.color = color
// вызов invalidate уведомляет систему о необходимости перерисовать 
// представление при отображении следующего кадра
invalidate()
}
С другой стороны, пользовательская версия 
ViewGroup
может реализовать но
-
вую стратегию размещения или включать набор дочерних экземпляров 
View
и 
ViewGroup
, образующих сложный компонент, такой как средство выбора даты 
или медиапроигрыватель. Подобный подход к использованию 
ViewGroup
обыч
-
но называют созданием пользовательского «компонента», он требует более 
глубокого погружения. Мы затронем эту тему далее, но вы обязательно долж
-
ны ознакомиться с дополнительными подробностями в документации (
https://
oreil.ly/ugTKF
).
Суть этого подхода сводится к переопределению двух методов: 
onMeasure
и 
onLayout

onMeasure
сообщает родителю, сколько места 
требует
пользователь
-
ский компонент. Иногда это все доступное пространство; иногда ровно столь
-
ко, сколько требуется для отображения содержимого.


64

Пользовательские компоненты
onMeasure
ожидает два параметра типа 
int

widthMeasureSpec
и 
heightMeasureSpec

Эти значения включают биты, определяющие «режим» (например, флаг 
MATCH_
PARENT
, указывающий, что компоненту должно быть отведено все пространство 
его родителя), а также размеры в пикселях.
Для чтения этих значений из параметров можно использовать методы 
Mea­
sureSpec.getMode
и 
MeasureSpec.getSize
.
Второй метод – 
onLayout
. Существуют разнообразные события, которые вы
-
зывают повторное размещение элементов в дереве представлений, например 
изменение размера родительского или дочернего элемента, добавление/уда
-
ление дочернего элемента или переупорядочение дочерних элементов. Кроме 
того, есть возможность явно потребовать выполнить повторное размещение 
элементов вызовом 
View.requestLayout
.
Реализация по умолчанию метода 
onLayout
ничего не делает (хотя конкрет
-
ные подклассы 
ViewGrou
p
, такие как 
FrameLayout
и 
Linearlayout
, переопределяют 
этот метод). У вас есть возможность выбирать, как 
ViewGroup
будет размещать 
свои дочерние элементы. Например, вертикально ориентированный 
Linear­
Layout
сначала измерит все дочерние элементы (в 
onMeasure
); затем, в 
onLayout

разместит первый дочерний элемент вверху, второй дочерний элемент – под 
ним, третий – под вторым и т. д. Вертикальный размер этого компонента бу
-
дет равен сумме вертикальных размеров его дочерних элементов. 
FrameLayout
действует проще (и эффективнее): все дочерние элементы размещаются неза
-
висимо друг от друга, причем для каждого дочернего элемента явно опреде
-
ляется параметр 
LayoutParams
со значениями координат левого верхнего угла 
элемента.
Например, следующий код использует 
FrameLayout
для отображения содержи
-
мого в 
Ac ti vi ty
и располагает 
TextView
на расстоянии ста пикселей от верхнего 
и левого края. Появление других дочерних экземпляров 
View
в этом контейне
-
ре не повлияет на положение 
TextView
, потому что при выполнении операции 
onLayout
класс 
FrameLayout
проверяет только значения координат дочерних эле
-
ментов в 
LayoutParams
:
Java
public class MyAc ti vi ty extends Ac ti vi ty {
@Override
public void onCreate(Bundle savedInstanceState) {
FrameLayout container = new FrameLayout(this);
setContentView(container);
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
lp.leftMargin = 100;
lp.topMargin = 100;
TextView textView = new TextView(this);
textView.setText("Hello world!");
container.addView(textView, lp);
}
}


Android 

65
Kotlin
class MyAc ti vi ty : Ac ti vi ty() {
override fun onCreate(savedInstanceState: Bundle?) {
val container = FrameLayout(this)
setContentView(container)
val lp = FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT)
lp.leftMargin = 100
lp.topMargin = 100
val textView = TextView(this)
textView.text = "Hello world!"
container.addView(textView, lp)
}
}
Вот пример реализации 
onLayout
, которая располагает дочерние элементы по 
горизонтали, пока не останется свободного места, после чего переходит к сле
-
дующей строке. Иногда такое размещение называют «потоковым» («FlowLay
-
out»):
Java
@Override
protected void onLayout(boolean changed, int left, int top, 
int right, int bottom) {
int x = 0;
int y = 0;
int tallest = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
tallest = Math.max(tallest, childHeight);
if (childWidth + x > getWidth()) {
x = 0;
y += tallest;
tallest = 0;
}
child.layout(x, y, c + childWidth, y + childHeight);
x += childWidth;
}
}
Kotlin
override fun onLayout(changed: Boolean, left: Int, top: Int, 
right: Int, bottom: Int) {
var x = 0
var y = 0
var tallest = 0
for (i in 0 until childCount) {
val child = getChildAt(i)
val childWidth = child.measuredWidth


66

Пользовательские компоненты
val childHeight = child.measuredHeight
tallest = Math.max(tallest, childHeight)
if (childWidth + x > width) {
x = 0
y += tallest
tallest = 0
}
child.layout(x, y, x + childWidth, y + childHeight)
x += childWidth
}
}
Также можно добавлять свои методы и свойства, чтобы получить функцио
-
нальность, необходимую вашему компоненту.

Download 3,69 Mb.

Do'stlaringiz bilan baham:
1   ...   43   44   45   46   47   48   49   50   ...   228




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish