Android: Создание своих собственных визуальных элементов

Придумал себе новую андроидную задачку. Она включает в себя отрисовку нового, ни на что не похожего элемента управления и взаимодействие с ним.

Создадим свой собственный визуальный элемент управления. Делается это созданием нового класса, наследуемого от класса View.
Всё, что данный элемент управления должен отрисовать в себе делается в оверрайднутом методе onDraw, у которого в качестве параметра – канва. В этом методе самое главное – это в самом конце вызвать метод invalidate() – он даст знать Андроиду, что надо перерисовать канву. Если этот метод не вызвать, то чёрт его знает сколько придётся ждать пока Андроид решит, что данные устарели и принудительно перерисует наш элемент управления.

Предположим, что нам надо перерисовывать содержимое элемента управления в зависимости от того что пользователь навозюкал там внутри пальцем. За это отвечает метод onTouchEvent. Принимаемый им параметр event позволяет узнать всё, что пользователь делал с нашим контролом – как возюкал или тыкал и где конкретно он это делал.

Этих методов достаточно, чтобы контрол уже работал. Мы ставим наш контрол на лэйаут и далее у нас появляется задача как-то управлять этим контролом снаружи. Например, нам нужно знать координаты места где пользователь повозюкал пальцем. Метод, который мы описали ранее – это встроенный метод контрола, он не может никак повлиять на внешние для этого контрола вещи. Но мы можем создать в том классе статические глобальные (для класса) переменные и менять их из того метода, а уж доступ к этим переменным нам обеспечен – за счёт того, что они статические. Статические – значит они общие для нашего класса, а не создаются с каждым инстансом. Это не очень хороший стиль программирования с моей точки зрения, но если контрол в программе присутствует в единственном экземпляре – то почему бы и нет.

public class myNewView extends View
{

static int X; // Переменные, доступные снаружи
static int Y;

public myNewView(Context context, AttributeSet attrs)
{
super(context, attrs);
}

@Override
public boolean onTouchEvent(MotionEvent event)
{
super.onTouchEvent(event); // очень важная строка, позволяет не только обработать
//касание здесь, но и при назначении метода onClick в
//Activity, инстантиировавшего наш
//контрол - обработать нажатие еще и там.
X=(int) event.getX(); // установка переменных для доступа к ним снаружи
Y=(int) event.getY();
return true;
}

@Override
protected void onDraw(Canvas canvas)
// метод OnDraw вызвается Андроидом тогда, когда нужно отрисовать данный View
{
// Здесь можно нарисовать всё что угодно на canvas
invalidate();// invalidate() нужен для того, чтобы оповестить Android,
//что нужно выполнить метод OnDraw снова, без него View не будет перериcовываться.
}
}