Управление видимостью представления с помощью привязки данных

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <import type="android.view.View" />
        <variable
            name="notificationResponse"
            type="myms.models.NotificationResponse"/>
    </data>
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

...........
<TextView
        android:id="@+id/tv_empty_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/_12dp"
        android:layout_marginRight="@dimen/_12dp"
        android:minHeight="@dimen/_60dp"
        android:gravity="center"
        android:textSize="@dimen/_18sp"
        android:textStyle="bold"
        android:text="No Message"
        android:background="@color/white"
        android:visibility="@{notificationResponse.payloads.size() > 0 ? View.GONE : View.VISIBLE}"/>

......
</FrameLayout>
</layout>

Чего я хочу добиться, так это того, что по умолчанию представление должно быть GONE, и после асинхронного вызова в моем коде, где я фактически привязываю объект notificationResponse, он должен решить, показывать или скрывать представление.


person eC Droid    schedule 11.10.2017    source источник
comment
простой поиск в Google возвращает это   -  person Selvin    schedule 11.10.2017
comment
stackoverflow.com/questions/34823611/   -  person Prakhar1001    schedule 11.10.2017
comment
Пожалуйста, прочитайте вопрос полностью.   -  person eC Droid    schedule 11.10.2017
comment
@PrakhaRaM, лол, это случайный вопрос, даже не связанный с этим   -  person Selvin    schedule 11.10.2017
comment
установите переменную, которую я показал здесь, является логической как ложную и установите ее истинной, когда вы получите ответ от вашего вызова сервера, на основе которого вы решите, сделать ли ваше представление исчезнувшим или видимым.   -  person Prakhar1001    schedule 11.10.2017


Ответы (3)


Интерпретация кода, который вы написали android:visibility="@{notificationResponse.payloads.size() > 0 ? View.GONE : View.VISIBLE}",

Когда размер вашего списка содержит более одного данных, вы хотите скрыть это TextView, а в другом случае вы хотите его показать.

Не тогда, когда вы вызываете свой API, размер вашего списка определенно будет меньше или равен 0, поэтому он не будет виден.

Решение:

Передайте некоторую переменную, которая указывает, что API все еще вызывается в фоновом режиме, и когда вызов API выполнен, установите для этой переменной значение false.

android:visibility="@{notificationResponse.payloads.size() > 0 || !loading ? View.GONE : View.VISIBLE}"

Это означает, что если размер вашего списка больше единицы и вызов API выполнен, TextView должен скрыться.

По умолчанию значение загрузки должно быть ложным, когда вы вызываете API, измените это значение на true, а когда вызов API снова будет выполнен, установите его на false.

person Ravi    schedule 12.10.2017
comment
Но правильным оператором будет android:visibility="@{notificationResponse.payloads.size() > 0 || loading ? View.GONE : View.VISIBLE}", а переменная должна быть объявлена ​​внутри тега данных, например <variable name="loading" type="Boolean"/>. - person eC Droid; 12.10.2017
comment
and variable should be declared inside data tag Да это очевидно. android:visibility="@{notificationResponse.payloads.size() > 0 || loading ? View.GONE : View.VISIBLE}" Спасибо, обновлю ответ :) - person Ravi; 12.10.2017
comment
Это было для любого, кто смотрел на ответ. - person eC Droid; 12.10.2017

Во фрагменте/активности вы можете создать поле int itemsCount = 0, и после получения ответа установите itemsCount = response.payloads.size(), а в xml установите itemCount вместо NotificationResponse.

На самом деле вам нужно установить новую переменную в привязке, чтобы повлиять на представление. Это означает, что если вы хотите получить результат без изменения xml, просто установите новый список для своей переменной и после получите список набора ответов из ответа.

person Eugene Troyanskii    schedule 11.10.2017
comment
Спасибо, звучит многообещающе. Нужно ли мне передавать свою активность или фрагмент в качестве переменной внутри тега данных? - person eC Droid; 11.10.2017
comment
Спасибо, но эта переменная будет иметь тот же эффект, что и payloads.size(), так как изначально обе будут равны 0. - person eC Droid; 12.10.2017
comment
Но ваше предложение было очень ценным, я понял, что это правильный подход вместо передачи объекта. - person eC Droid; 12.10.2017

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

первый способ (согласно комментариям ниже) выглядит так:

public void setLoading(boolean loading) {
    isLoading = loading;
    notifyPropertyChanged(BR._all);
}

и

notifyPropertyChanged(BR.loading);

ref

Но есть более простой способ сделать это, я бы сделал это следующим образом: сначала измените эту строку в вашем представлении

android:visibility="@{notificationResponse.payloads.size() > 0 ? View.GONE : View.VISIBLE}"/>

to

android:visibility="gone"/>

А затем в свой AsyncTask добавьте что-то вроде этого:

protected void onPostExecute(Boolean toBeShown) {
    if(toBeShown){
        tvEmptyView.setVisibility(View.VISIBLE);
    }else{
        tvEmptyView.setVisibility(View.GONE);
    }
}
person Yamen Nassif    schedule 11.10.2017
comment
Что вы не понимаете в разделе Управление видимостью представления через привязку данных? Я почти уверен, что автор знает, как сделать это вручную - person Selvin; 11.10.2017
comment
xD, stackoverflow.com/a/40859353/2724879 это ответ, который я нашел давным-давно, но, как я уже сказал, I would have done it the following way Я просто дал другой подход - person Yamen Nassif; 11.10.2017
comment
и это гораздо лучше подходит к вопросу :) - person Selvin; 11.10.2017