Как сделать границу выделения, которая отслеживает установленную кнопку-переключатель? - PullRequest
6 голосов
/ 19 февраля 2011

У меня есть набор RadioButton с пользовательским стилем.Я хочу отобразить рамку вокруг кнопки, которая в данный момент отмечена.Это должно быть достаточно просто с использованием XML, но теперь я хочу, чтобы граница была анимированной.Если установлен новый переключатель, граница должна «вылететь» на новое место с причудливой анимацией:

+------+
|* btn1| o btn2
+------+

    +------+
 o b|n1  * |tn2
    +------+

        +------+
 o btn1 |* btn2|
        +------+

. Поэтому я решил сделать границу отдельным объектом View,так что я могу оживить это правильно.Беда в том, чтобы отследить расположение соответствующей радиокнопки на экране.

Я пытаюсь заставить ее работать без анимации.Моя текущая попытка выглядит примерно так (показаны только соответствующие атрибуты):

    <RelativeLayout
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true">
        <RadioGroup
            android:id="@+id/radio_group">
            <RadioButton/>
            <RadioButton/>
            <RadioButton/>
        </RadioGroup>
        <View
            android:id="@+id/selection_border"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"/>
    </RelativeLayout>

В OnCheckedChangeListener из RadioGroup я перемещаю границу выделения, устанавливая ее поле (я мог установитьположение, но это немного сложнее с RelativeLayout):

View radioButton = findViewById(checkedId);
View selectionBorder = findViewById(R.id.selection_border);
ViewGroup radioGroup = (ViewGroup)findViewById(R.id.radio_group);

RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(selectionBorder.getLayoutParams());
params.leftMargin = radioGroup.getLeft() + radioButton.getLeft();
params.topMargin = radioGroup.getTop() + radioButton.getTop();
selection.setLayoutParams(params);

selection.requestLayout();

Однако при инициализации возникает проблема.Поскольку макетирование еще не выполнено, положение границы установлено неправильно.Кажется, что невозможно немедленно вызвать ретрансляцию, а также не представляется возможным получить событие после выполнения макета.

Все эти хлопоты заставляют меня поверить, чтобыть более чистым способом выполнить то, что я хочу.Какие-нибудь яркие идеи?

Ответы [ 2 ]

1 голос
/ 22 июня 2011

Чтобы решить вашу проблему с инициализацией (у меня с ней было много проблем в прошлом): если мне нужно знать, когда завершена компоновка представления, я даю ему runnable в Activity.onCreate (), затем вызываю запускается из View.onSizeChanged (). Я довольно часто использовал этот шаблон и нашел его очень надежным. Вам просто нужно помнить, чтобы вызывать runnable только из onSizeChanged (), только если новая ширина и высота больше 0 и если они не равны старой ширине и высоте.

Итак, в вашей деятельности:

public void onCreate() {
    ...
    yourView.setLayoutRunnable(new Runnable() {
        @Override
        public void run() {
            //do post-layout stuff...
        }
    });
    ...
}

и по вашему мнению:

public Runnable layoutRunner;

public void setLayoutRunnable(Runnable runner) {
    layoutRunner = runner;
}

@Override
public void onSizeChanged(int w, int h, int oldw, int oldh) {
    if (w > 0 && h > 0 && (w != oldw || h != oldh)) {
        if (layoutRunner != null) layoutRunner.run();
    }
}

Если у вас есть несколько представлений, для которых всем необходимо завершить свои макеты, прежде чем приступить к работе, вы должны вести подсчет при получении уведомлений, чтобы вы знали, когда они сделаны.

А что касается вашей темы в целом, я реализовал нечто похожее на вашу концепцию переключателя в игре, которую я написал, но я решил переопределить View с нуля, чтобы сделать это. У меня были все варианты набора в одном представлении, поэтому я заменил представление RadioGroup, а не представление RadioButton. Каждый вариант имеет значение и степень. Я всегда использовал текст, но изображения работали бы так же легко. Затем я просто отследил нажатия и перетаскивания относительно экстентов опций и переместил «селектор» на временный обработчик (а-ля анимации в javascript).

1 голос
/ 21 марта 2011

лучший способ, которым я считаю, это установить флажок лечить как изображение.Два типа проверены / не проверены.Затем вы в основном перемещаете изображение по экрану.Работайте с TouchEvents и изображениями, если пользователь нажимает мышью на область, излучающую изображение, которое, как вы знаете, выбрано.Это легко, потому что теперь вы имеете дело только с изображениями, канвой и стандартными координатами x, y.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...