Подтвердить что ты не робот

Как отрегулировать расстояние прокрутки в SwipeRefreshLayout?

Я реализовал SwipeRefreshLayout в своем приложении. Мне нужно изменить высоту, которую нужно прокрутить, чтобы вызвать метод onRefresh(). Какой метод следует использовать для добавления пользовательской высоты?

Реализация SwipeRefreshLayout

private SwipeRefreshLayout swipeLayout;

В oncreate

swipeLayout   = (SwipeRefreshLayout)view.findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(this);
        swipeLayout.setColorScheme(android.R.color.holo_blue_dark, 
                android.R.color.holo_green_dark, 
                android.R.color.holo_purple, 
                android.R.color.holo_orange_dark);   
        swipeLayout.setSoundEffectsEnabled(true);

Реализация AsyncTask в методе onrefresh

   @Override
public void onRefresh() 
{
    // Asynctask to perform some task  

}
4b9b3361

Ответ 1

Если вы используете API 21 в библиотеке поддержки, обратитесь к и, пожалуйста, запустите Han He answer здесь. Существует метод установки расстояния триггера под названием setDistanceToTriggerSync.


До API 21, как упоминалось выше, нет никаких общедоступных или внутренних методов для изменения расстояния триггера.

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

swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);

// define a distance
Float mDistanceToTriggerSync = yourCalculation(); 

try {
    // Set the internal trigger distance using reflection.
    Field field = SwipeRefreshLayout.class.getDeclaredField("mDistanceToTriggerSync");
    field.setAccessible(true);
    field.setFloat(swipeLayout, mDistanceToTriggerSync);
} catch (Exception e) {
    e.printStackTrace();
}

Если вы используете высоту макета для определения расстояния, вы можете использовать что-то вроде GlobalLayoutListener.

mDistanceToTriggerSync

В SwipeRefreshLayout имеется внутренняя переменная, называемая mDistanceToTriggerSync. Это используется для определения того, на каком расстоянии запускается обновление.

В исходном коде он устанавливается кодом ниже в SwipeRefreshLayout:

final DisplayMetrics metrics = getResources().getDisplayMetrics();
mDistanceToTriggerSync = (int) Math.min(
        ((View) getParent()) .getHeight() * MAX_SWIPE_DISTANCE_FACTOR,
                REFRESH_TRIGGER_DISTANCE * metrics.density);

В приведенном выше примере используется высота родительского представления и некоторые константы для вычисления расстояния триггера. MAX_SWIPE_DISTANCE_FACTOR (0.6) и REFRESH_TRIGGER_DISTANCE (120) являются частными константами в классе, которые вы не можете изменить.

Вы можете использовать приведенное выше, чтобы вычислить расстояние триггера и использовать собственные константы для коэффициентов расстояния прохождения.

GlobalLayoutListener

Настройка mDistanceToTriggerSync может быть выполнена внутри глобального приемника макета, чтобы высота макета могла быть правильно восстановлена ​​для вычисления расстояния триггера. Вызов getHeight в представлении onCreate всегда будет возвращать 0, потому что он еще не нарисован. Я получил код здесь. Вам может потребоваться или не нужно делать это в зависимости от ваших требований.

ViewTreeObserver vto = swipeLayout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        // Calculate the trigger distance.
        final DisplayMetrics metrics = getResources().getDisplayMetrics();
        Float mDistanceToTriggerSync = Math.min(
                ((View) swipeLayout.getParent()).getHeight() * 0.6f,
                120 * metrics.density);

        try {
            // Set the internal trigger distance using reflection.
            Field field = SwipeRefreshLayout.class.getDeclaredField("mDistanceToTriggerSync");
            field.setAccessible(true);
            field.setFloat(swipeLayout, mDistanceToTriggerSync);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Only needs to be done once so remove listener.
        ViewTreeObserver obs = swipeLayout.getViewTreeObserver();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            obs.removeOnGlobalLayoutListener(this);
        } else {
            obs.removeGlobalOnLayoutListener(this);
        }
    }
});

Настройка переменной должна выполняться только один раз, если я правильно понимаю базовый код, поскольку он устанавливает только mDistanceToTriggerSync, если он равен -1. Следовательно, это должно быть безопасно сделать это в глобальном приемнике макетов один раз.

SwipeRefreshLayout

Если вас интересует исходный код SwipeRefreshLayout, вы можете найти его здесь.

Ответ 2

Реверсия 21 библиотеки поддержки v4 предоставила API для установки расстояния.

public void setDistanceToTriggerSync (int distance)

Проверьте документ здесь.

Еще одно, rev. 21 изменил поведение индикатора выполнения, теперь это круговой образ. Не знаю, как вернуть старый путь.

Ответ 3

В настоящее время нет общедоступного метода или даже внутреннего для этого, который можно использовать для настройки расстояния триггера. Но вы можете скопировать три класса из библиотеки поддержки в свой проект, а затем изменить SwipeRefreshLayout по своему вкусу.

Вот классы, которые вам нужно скопировать:

Расстояние тигра вычисляется с использованием констант:

 private static final float MAX_SWIPE_DISTANCE_FACTOR = .6f;
 private static final int REFRESH_TRIGGER_DISTANCE = 120;

В вашем макете измените <android.support.v4.widget.SwipeRefreshLayout.../> на <your_path_to_SwipeRefreshLayout.../> и убедитесь, что вы изменили импорт, если вам нужно.