DataBinding frissítés UI a fragmens felhasználásával kötési

szavazat
0

Úgy látszik, van egy tudomány databainding az android, amiről nyilvánvalóan nem kap. Folyton kiöntött harci frissítése nézetek keresztül a fragmentum vagy viewmodel ahol bizonyos dolgokat „csak a munka” mások látszólag nem működik.

Azt szeretné tiltani a belépés gomb, változtassa meg a szöveget, és állítsa be az alfa után kattintanak, amíg nem kap egy API választ, akkor azt változtassa vissza. Szép egyenes továbbít. Im nem értve a kódot, amely meg fogja változtatni vissza óta megállás változik ez az első alkalom.

Miközben ezt írom én ugyanazt a kérdést újra és újra, a gomb nem változik. A megfigyelő a fragmentum hívódik (A naplóban azt mutatja sorrendben elvárom, hogy hívták), de az UI csak doesnt frissítés. Futottam azt egy emulátor újra és újra és újra a megfigyelő log doesnt jelenik csak sokkal később, majd a nézet frissül a várakozásoknak megfelelően, sorta. Ez didnt frissül, amikor rákattintottam a gombot, de legalább a gomb megváltozik, mielőtt API válasz jött vissza. Abbahagytam az alkalmazást, és újra futott, és im vissza az eredeti kérdés, hogy nem frissíti.

Im használ SingleLiveEvent módosítatlan származó googles építészet minták https://github.com/android/architecture-samples/blob/dev-todo-mvvm-live/todoapp/app/src/main/java/com/example/android/architecture/ tervrajzok / todoapp / SingleLiveEvent.java

activity_main_login <- annak egy töredéke nem tevékenység, hanem én kikötõ refactored még. Ez van csonkítva, így lehet, hogy nem a munka nélkül egy elrendezést tartályba.

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

Itt van, amit a naplók kinézni, ha fut, és rákattint a belépés gomb ...

D/MainViewModel: loginClicked()
D/MainFragment: showLoading changed
D/MainViewModel: login()
A kérdést 13/01/2020 23:52
a forrás felhasználó
Más nyelveken...                            


1 válasz

szavazat
0

Nem mintha benne a Retrofit2 kódot, amely az / megkapta az API-hívás, de ez volt köze a menet. Tekertem a módszert, amelyet az úgynevezett szinkron retrofit forrás

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

Tehát login () úgy néz ki, mint ez most

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

Annak ellenére, hogy az API-hívás maga kell tenni a saját szál (és volt) az egész dolog csak felemelte az UI szál legvalószínűbb oka az thread.join (). Ez okozta a Databindings nem frissítés. Ez már megoldódott a RxJava de nem hajtották végre, hogy még, és egy egyszerű feladat annak nem szükséges.

Válaszolt 15/01/2020 01:25
a forrás felhasználó

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