fragmanından kullanılarak bağlanma güncellemesi UI veri bağlamayı

oy
0

Görünüşe hangi açıkça do not get android içinde databainding bir bilim var. Bazı şeylerin sadece iş diğerleri görünüşte işlevsiz olan parçanın ya ViewModel aracılığıyla güncelleme görüşlerini mücadele biten tutun.

Ben, bir oturum açma düğmesini devre dışı metin değişikliği ve sonra geri değiştirene bir API yanıt almak kadar onun tıklandığında sonra alfa ayarlamak istiyorum. Oldukça düz ileri. Im onun İlk seferinde değişen durdurma beri geri değişecek kodu dahil değil.

Bu I yazma tekrar tekrar aynı sorunu vardı ise, düğme hiç değişmez. fragmanda gözlemci (günlüğünde ben denir bekleniyor olması nedeniyle sırayla gösterir) çağrılan ancak kullanıcı arayüzü sadece doesnt güncelleme. Yine bir emülatör üzerinde koştum ve defalarca gözlemci günlüğü doesnt kadar sonradan ardından beklendiği gibi güncellenmiş görünümü, sorta görünür. Ben butonuna tıkladım ama en azından API tepkisi önce değişti düğmesi geri geldi güncellenmesi yoktu. Ben app durdu ve onu ve orijinal konuya im sırt, onun güncellememesi yeniden koştu.

SingleLiveEvent kullanılarak Im googles mimari örneklerinden modifiye edilmemiş https://github.com/android/architecture-samples/blob/dev-todo-mvvm-live/todoapp/app/src/main/java/com/example/android/architecture/ planları / todoapp / SingleLiveEvent.java

activity_main_login <- onun bir parçası değil etkinlik ama sığınak henüz refactored. Bir düzen kap olmadan çalışmayabilir böylece bu kesilir.

<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();
}

İşte günlükleri çalıştırıldığında benziyorsun, ve giriş tuşuna basın budur ...

D/MainViewModel: loginClicked()
D/MainFragment: showLoading changed
D/MainViewModel: login()
Oluştur 13/01/2020 saat 21:52
kaynak kullanıcı
Diğer dillerde...                            


1 cevaplar

oy
0

Ben yaptığı Retrofit2 kodu dahil değil o / API çağrısı aldı ama parçacığı ile yapmak zorunda. I senkron güçlendirme kaynak olarak adlandırılan yöntem sarılı

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

login () şimdi bunun gibi daha fazla görünüyor Yani

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 çağrısı kendisi kendi iş parçacığı üzerinde yapılan (ve oldu) olmalıdır rağmen şeyin tamamı sadece sebebiyle Thread.Join en muhtemel UI iş parçacığı kaldırdı (). Bu güncelleme değil DataBindings neden oldu. Bu RxJava kullanılarak çözümlenmiş olabilir ama henüz o ve basit bir görev için onun gerekli değildir uyguladık.

Cevap 14/01/2020 saat 23:25
kaynak kullanıcı

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