Databinding обновления пользовательского интерфейса от фрагмента с использованием привязки

голоса
0

Видимо есть наука databainding в андроиде из которых я явно не получают. Я все в конечном итоге борьба с видом обновления через фрагмент или ViewModel, где некоторые вещи «просто работать» другие, казалось бы, нефункциональные.

Я хочу, чтобы отключить кнопку входа в систему, изменить его текст и установить альфа после его щелкнули, пока я не получу ответа API, то я могу изменить его обратно. Довольно прямо вперед. Im не включая код, который изменит его обратно, так как его остановку при изменении его в первый раз.

Во время написания этого я был один и тот же вопрос снова и снова, кнопка никогда не меняется. Наблюдатель в фрагменте вызывается (В журнале он показывает в порядке, я ожидаю, что это было назвать), но интерфейс как раз не обновление. Я побежал его на эмуляторе снова и повторно журнал наблюдателя не появляется значительно позже, а затем представления обновленной, как и ожидалось, Сорта. Оно не обновлять, когда я нажал на кнопку, но по крайней мере, кнопка изменилась до ответа API вернулся. Я остановил приложение и повторно побежал это и им вернуться к первоначальному вопросу, его не обновляются.

Im используя SingleLiveEvent немодифицированных из образцов Googles архитектуры https://github.com/android/architecture-samples/blob/dev-todo-mvvm-live/todoapp/app/src/main/java/com/example/android/architecture/ чертежи / todoapp / SingleLiveEvent.java

activity_main_login <- его фрагмент не деятельность, а я нету переработан еще. Это усеченный поэтому он не может работать без контейнера макета.

<layout
    xmlns:android=http://schemas.android.com/apk/res/android
    xmlns:app=http://schemas.android.com/apk/res-auto
    xmlns:tools=http://schemas.android.com/tools>

    <data>
        <variable
            name=mainViewModel
            type=com.example.viewmodel.MainViewModel />
    </data>
    ...
    <Button
        android:id=@+id/btnLogin
        android:layout_width=135dp
        android:layout_height=47dp
        android:layout_marginLeft=8dp
        android:layout_marginRight=8dp
        android:layout_marginTop=16dp
        android:onClick=@{() -> mainViewModel.loginClicked()}
        android:text=@string/login
        android:textColor=#ffffff
        android:textStyle=bold
        android:background=#e05206
        app:layout_constraintLeft_toLeftOf=parent
        app:layout_constraintRight_toRightOf=parent
        app:layout_constraintTop_toBottomOf=@+id/fingerprintSwitch
        tools:layout_editor_absoluteX=101dp />
    ....
</layout>

MainFragment

ActivityMainLoginBinding binding;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    Log.d(TAG, -> onCreateView() );
    super.onCreateView(inflater, container, savedInstanceState);

    mainViewModel = new ViewModelProvider(this).get(MainViewModel.class);

    getLifecycle().addObserver(mainViewModel);

    binding = DataBindingUtil.inflate(inflater, R.layout.activity_main_login, container, false);
    mView = binding.getRoot();
    binding.setMainViewModel(mainViewModel);
    binding.setLifecycleOwner(this); // Yeah this is what I forgot last time...

    return mView;
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    AppLog.d(TAG, -> onViewCreated() );
    super.onViewCreated(view, savedInstanceState);

    mainViewModel.getShowLoading().observe(getViewLifecycleOwner(), showLoading -> {
        AppLog.d(TAG, showLoading changed);
        this.loading = true;

        binding.btnLogin.setText(R.string.loggingIn);
        binding.btnLogin.setEnabled(false);
        binding.btnLogin.setAlpha(.5f);
    });
}

MainViewModel

private SingleLiveEvent<Boolean> showLoading = new SingleLiveEvent<>();

public void loginClicked() {
    Log.d(TAG, loginClicked());
    showLoading.setValue(true);
    login();
}

Вот то, что журналы выглядеть, когда он работает, и нажать кнопку входа ...

D/MainViewModel: loginClicked()
D/MainFragment: showLoading changed
D/MainViewModel: login()
Задан 13/01/2020 в 21:52
источник пользователем
На других языках...                            


1 ответов

голоса
0

Не то, чтобы я включил код Retrofit2, который сделал / получил вызов API, но он должен был сделать с резьбой. Я завернут метод, который под названием синхронного модифицированный ресурс в

new Handler().post(() -> { });

Так Логин () выглядит, как это сейчас

private void login() {
    new Handler().post(() -> {
        // original retrofit call
        Thread t = new Thread(() -> authResponse = restApi.doAuthSync());
        t.start();

        // Joining thread so we wait for the response
        // I believe this to be the actual culprit of the problem
        try {
            t.join();
        } catch (InterruptedException e) {
            Log.e(TAG, e.getMessage());
        }

        // handle authResponse
        ...
    });
}

Даже при том, что сам по себе API вызов должен быть сделан на своем собственном потоке (и был) все, что только поднял поток пользовательского интерфейса, скорее всего, из-за Thread.join (). Это вызвало DataBindings не обновление. Это может быть решена с помощью RxJava, но я не выполнил, что еще и для простой задачи ее не нужно.

Ответил 14/01/2020 в 23:25
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more