Ограничение целочисленного значения Layout Binding от 0 до 10 в android с привязкой данных

Я пытаюсь установить предел целого числа с минимальным значением 0 и максимальным значением 10 в Android с помощью привязки данных. Для этого у меня есть привязываемый адаптер, который устанавливает значение целого числа с двумя слушателями, один из которых увеличивает значение, а другой уменьшает его. Теперь, наконец, я хотел установить предел этого целого числа, минимум 0 и максимум 10.

@BindingAdapter("quantity")
public static void setQuantityText(TextView textView, int quantity) {
    textView.setText(String.valueOf(quantity));
}
public static class ListenerIncrease implements View.OnClickListener {

    private FragmentBinding binding;

    public ListenerIncrease(FragmentBinding binding) {
        this.binding = binding;
    }

    @Override
    public void onClick(View v) {
        int quantity = binding.getQuantity();
        binding.setQuantity(++quantity);
    }
}
public static class ListenerDecrease implements View.OnClickListener {

    private FragmentBinding binding;

    public ListenerDecrease(FragmentBinding binding) {
        this.binding = binding;
    }
    @Override
    public void onClick(View v) {
        int quantity = binding.getQuantity();
        binding.setQuantity(--quantity);
    }
}

person Tushar Rai    schedule 06.05.2016    source источник


Ответы (1)


Я думаю, было бы проще, если бы вы обрабатывали щелчки немного по-другому. Часть лямбда-выражения работает только в Android Studio 2.1 и выше.

<Button android:onClick="@{(view)->Handlers.increment(view, 10)}" .../>
<Button android:onClick="@{(view)->Handlers.decrement(view, 0)}" .../>
<TextView app:quantity="@{quantity}"/>

И тогда ваш класс обработчика имеет:

public static void increment(View view, int max) {
    FragmentBinding binding = DataBindingUtil.findBinding(view);
    binding.setQuantity(Math.max(max, binding.getQuantity() + 1));
}

public static void decrement(View view, int min) {
    FragmentBinding binding = DataBindingUtil.findBinding(view);
    binding.setQuantity(Math.min(min, binding.getQuantity() - 1));
}

В качестве альтернативы вы можете использовать полноценную двустороннюю привязку. В предстоящей Android Studio 2.2 вы сможете сделать это:

<Button android:onClick="@{()->Handlers.increment(quantityView, 10)}" .../>
<Button android:onClick="@{()->Handlers.decrement(quantityView, 0)}" .../>
<TextView android:id="@+id/quantityView" app:quantity="@={`` + quantity}"/>

И тогда ваш класс обработчика имеет:

private static int getCurrentIntValue(TextView view) {
    try {
        return Integer.parseInt(view.getText().toString());
    } catch (NumberFormatException e) {
        return 0;
    }
}
public static void increment(TextView view, int max) {
    int value = getCurrentIntValue(view);
    binding.setQuantity(Math.max(max, value + 1));
}

public static void decrement(View view, int min) {
    int value = getCurrentIntValue(view);
    binding.setQuantity(Math.min(min, value - 1));
}

Трюк, добавленный в Android Studio 2.2, — это поддержка преобразований для конкатенации строк с пустой строкой. Это полезный ярлык. Без этого (Android Studio 2.1) вам нужно будет добавить собственную двустороннюю привязку для текста integer-to-TextView:

@InverseBindingAdapter(attribute = "quantity")
public static int getQuantity(TextView view) {
    return getCurrentIntValue(view);
}

а вот упрощенный адаптер для привязки. Используйте один из TextViewBindingAdapter.java в качестве шаблона, если вам нужно добавить наблюдатели за текстом в тот же TextView:

@BindingAdapter("onQuantityChanged")
public static void setQuanityWatcher(TextView view,
        final InverseBindingListener quantityChanged) {
    TextWatcher newTextWatcher;
    if (quantityChanged == null) {
        newTextWatcher = null;
    } else {
        newTextWatcher = new TextWatcher() {
            @Override
            public void afterTextChanged(Editable s) {
                quantityChanged.onChange();
            }
            // others are empty...
        }
    }
    TextWatcher oldTextWatcher = ListenerUtil.trackListener(
        view, newTextWatcher, R.id.textWatcher);
    if (oldTextWatcher != null) {
        view.removeTextChangeListener(oldTextWatcher);
    }
    if (newTextWatcher != null) {
        view.addTextChangedListener(newTextWatcher);
    }
 }

Обратите внимание, что я ничего из этого не компилировал, поэтому могут быть опечатки.

person George Mount    schedule 06.05.2016
comment
msg:Идентификаторы должны иметь определенные пользователем типы из XML-файла. представление отсутствует ****\ ошибка привязки данных **** - person Tushar Rai; 07.05.2016
comment
Это означает, что вы используете идентификаторы без импорта типа. - person George Mount; 07.05.2016
comment
Я импортировал представление ‹import type=com.xyz.www.fragment/›, но все равно показывает ошибку. Я импортирую правильный вид - person Tushar Rai; 07.05.2016
comment
Возможно, вы можете отредактировать свой вопрос и добавить макет - person George Mount; 07.05.2016
comment
Джордж. Я импортирую представление с помощью ‹import type=android.view.View/›, но все равно выдает ошибку «Ошибка: сбой выполнения для задачи ':app:compileDebugJavaWithJavac'». › java.lang.RuntimeException: обнаружены ошибки привязки данных. ****/ ошибка привязки данных ****msg: Идентификаторы должны иметь определенные пользователем типы из XML-файла. вид отсутствует - person Tushar Rai; 11.05.2016
comment
Судя по сообщению об ошибке, вы используете «просмотр», а не «просмотр». - person George Mount; 19.05.2016