如果您使用的是支持库的 API 21,请参考并请在此处支持 Han He 的答案。存在一种设置触发距离的方法,称为setDistanceToTriggerSync
。
在 API 21 之前,正如 adneal 所提到的,没有公共或内部方法可以修改触发距离。
但是,如果您不想保留类的副本来修改常量,则可以使用反射手动设置触发距离。
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) 是类中的私有常量,您无法修改。
您可以使用上述计算触发距离,并使用您自己的常数作为滑动距离因子。
全局布局监听器
可以在全局布局侦听器中进行设置,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
可以在这里找到。