Наблюдение поля @Bindable в синглтоне prefs не обновляется, если текст не обновлен - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть одноэлементный класс, содержащий мои предпочтения, и я пытаюсь привязать поле, которое изменит формат при изменении предпочтения.

Это своего рода работа (поле открыто), но оно только обновляет поле при изменении текста, а не при изменении предпочтения.

Я пытался вызвать notifyPropertyChanged(BR.useDecimalTime);, пытался наблюдать событие SingleLiveData (которое вызывается и вызывает executePendingBindings(), но не не обновлять формат).

Некоторые соответствующие фрагменты кода:

PreferenceRepository. java

public class PreferenceRepository extends BaseObservable implements SharedPreferences.OnSharedPreferenceChangeListener {
    public static final String DECIMAL_TIME = "pref_decimal_time";
    private static boolean useDecimalTime;
    private SingleLiveEvent<Object> prefsUpdated = new SingleLiveEvent<>();

    @Contract(pure = true)
    @Bindable
    public static boolean isUseDecimalTime() {
        return useDecimalTime;
    }

    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, @NotNull String key) {
        switch (key) {
            case DECIMAL_TIME:
                useDecimalTime = sharedPreferences.getBoolean(key, false);
                notifyPropertyChanged(BR.useDecimalTime);
                break;
            default:
                Log.e(TAG, "onSharedPreferenceChanged: Unknown key ["+key+"]");
        }
        prefsUpdated.call();
    }

Фрагмент. xml

    <data>
        <import type="java.util.Map"/>
        <import type="android.view.View" />
       <variable
            name="viewmodel"
            type="com.example.HomeViewModel" />
        <variable
            name="prefs"
            type="com.example.prefs.PreferenceRepository" />
    </data>

        <com.example.ui.view.timetextview.TimeView
            android:id="@+id/shiftHoursView"
            style="@style/TextAppearance.MyTheme.Mono"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            minutes="@{viewmodel.shiftMinutes}"
            mode="@{prefs.isUseDecimalTime}"
            app:layout_constraintBaseline_toBaselineOf="@id/textView11"
            app:layout_constraintStart_toStartOf="@id/guideline_33"
            tools:text="0:00" />

и соответствующий BindingAdapters. java метод для полноты:

    @Contract("null, _, _ -> fail")
    @BindingAdapter(value = {"minutes", "mode"}, requireAll = false)
    public static void setTimeMinutes(View view, Integer minutes, Boolean decimal) {
        if(!(view instanceof TimeView)) {
            throw new UnsupportedOperationException("Can only set minutes on a TimeView");
        }

        if(view.getVisibility() != View.VISIBLE) return;

        if(minutes == null) {
            minutes = 0;
            Log.e(TAG, "setTimeMinutes: null minutes");
        }

        if(decimal == null) {
            ((TimeView) view).setTime(minutes);
        } else {
            ((TimeView) view).setTime(minutes,  decimal);
        }
    }

TimeView - это пользовательское представление, которое расширяет TextView, если это имеет значение.

РЕДАКТИРОВАТЬ:

При вызове binding.invalidateAll() все обновляется немедленно, но мне остается только задаться вопросом, является ли это правильным способом сделать это или если есть лучший способ.

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