SwipeRefreshLayout нет анимации при создании фрагмента

Я использую android.support.v4.widget.SwipeRefreshLayout с android.support.v7.widget.RecyclerView.
При создании представления фрагмента мне нужно показать SwipeRefreshLayout анимацию. Но когда я звоню setRefreshing(true) ничего не происходит. Но когда я обновляю данные, анимация меняется.
Я предполагаю, что анимация не отображается без дочерних элементов внутри SwipeRefreshLayout.
Как лучше показать эту анимацию?


person Maksym    schedule 21.10.2014    source источник


Ответы (5)


Об этой ошибке сообщается (сообщено здесь), и доступно ее временное решение:

mSwipeRefreshLayout.setProgressViewOffset(false, 0,
    (int) TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP, 
        24, 
        getResources().getDisplayMetrics()));
mSwipeRefreshLayout.setRefreshing(true);
person Tadas Šubonis    schedule 05.11.2014

Это зависит от того, на каком уровне API вы строите - если вы используете до API 20, вы можете просто включить setRefreshing(true), это запустит анимацию в ActionBar, но в API 21 (Material Design) они изменил прогресс, чтобы он был спиннером, а не «выдвигается на вид» до того, как он вращается

У вас есть 2 способа обойти это в API 21: 1) сдвинуть счетчик вниз с помощью setProgressViewOffset(), но не забудьте сместить его обратно после слов (обратите внимание, что это работает в px, в то время как setDistanceToTriggerSync() использует dp) 2) сделать дублирующий счетчик, который отображается при загрузке данных

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

Если вам нужно рассчитать плотность пикселей, вы можете получить ее из:

DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
float scale = metrics.density;
person Phil A    schedule 29.10.2014

Спасибо, парни.

Я только что понял, что самое простое решение — вызвать метод Measure(int, int) с ненулевыми значениями) перед вызовом setRefreshing(true). Проблема возникает из-за того, что setRefreshing(true) вызывается перед onMeasure.

Итак, вам нужно позвонить:

swipeRefreshLayout.measure(initialWidth, initialHeight);
swipeRefreshLayout.setRefreshing(true);
person Maksym    schedule 01.11.2014
comment
Это неправильный способ сделать это, потому что вы столкнетесь с различными NPE. - person Tadas Šubonis; 05.11.2014
comment
@TadasŠubonis Можете ли вы объяснить, какой NPE вы получите от этого? Я не вижу проблемы? - person John Shelley; 05.11.2014
comment
Также @Maksym, что вы использовали для значений меры? - person John Shelley; 05.11.2014
comment
В моем случае он (SwipeRefreshLayout) содержал RecyclerView, и при вызове .measure() он будет распространяться на внутренние компоненты RecyclerView, а затем будет выброшен NPE. Нет под рукой стека... - person Tadas Šubonis; 06.11.2014
comment
@TadasŠubonis, возможно, вы вызвали measure перед установкой менеджера компоновки в RecyclerView. - person TWiStErRob; 15.11.2014

Для правильной работы SwipeRefreshLayout должен содержать дочерний элемент. Убедитесь, что вы инициализировали его перед использованием в любом месте!

person Mike    schedule 21.10.2014

вы должны вызывать setRefreshing(true) после onDraw(), иначе анимация не будет отображаться.

поэтому в Activity вы можете сделать это в onCreate(), вот так:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // other codes

    new Handler().post(new Runnable() {
        @Override
        public void run() {
            swipeRefreshLayout.setRefreshing(true);
            refreshing = true;
            refreshData();
        }
    }
}

во фрагменте вы можете поместить эти коды в onActivityCreated().

person Spark.Bao    schedule 15.11.2015