Ответ 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
, вы можете найти его здесь.