我有一个非常复杂的结构,FrameLayout
包含2 LinearLayout
s(一次只显示一个)。
其中一个LinearLayout
需要拉动刷新。
所以我的布局XML看起来像这样:
<FrameLayout>
[...]
<SwipeRefreshLayout>
<LinearLayout>
<TextView/>
<TextView/>
<ListView/>
<TextView/>
<ListView/>
</LinearLayout>
</SwipeRefreshLayout>
</FrameLayout>
我希望能够在整个Linearlayout
上进行快速刷新,这就是为什么我的想法是用SwipeRefreshLayout
来包装它。但是拉上TextView
s现在不起作用,有时行为真的很奇怪(我看到泡沫但它会立即消失)。
只有当我拉上其中一个ListView
时,事情就会按预期运作。
我甚至尝试导入MultiSwiperefreshLayout
(来自here)并设置:
swipeLayout.setSwipeableChildren(R.id.xxx); // Id of my linearlayout
您是否知道如何使Refreshlayout
包裹像我一样的复杂布局并在那里正常工作?
答案 0 :(得分:0)
我解决了! 我遇到了同样的问题,并解决了它。 我的问题如下:
<MultiSwipeRefreshLayout>
<LinearLayout>
<RelativeLayout>
<ListView @+id/list_1 />
<TextView @+id/list_1_empty_view />
</RelativeLayout>
<RelativeLayout>
<ListView @+id/list_2 />
<TextView @+id/list_2_empty_view />
</RelativeLayout>
</LinearLayout>
</MultiSwipeRefreshLayout>
我决定参考:https://developer.android.com/samples/SwipeRefreshMultipleViews/index.html
在这个例子的思想背后,我重写了SwipeRefreshLayout,点亮了差异。
1)首先,我新增了一个MultiSwipeRefreshLayout.java类,因为我的modificine,除了扩展SwipeRefreshLayout类之外,我必须这样做;
2)其次,我将SwipeRefreshLayout.java的所有内容复制到MultiSwipeRefreshLayout.java,并在下面添加以下代码:
private View[] mSwipeableChildren;
/**
* 记录子视图中是否有控件可以上滑的;该值在每次的ACTION_DOWN时计算一次。
*/
private boolean canChildScrollUp = true;
/**
* Set the children which can trigger a refresh by swiping down when they are visible. These
* views need to be a descendant of this view.
*/
public void setSwipeableChildren(final int... ids) {
assert ids != null;
// Iterate through the ids and find the Views
mSwipeableChildren = new View[ids.length];
for (int i = 0; i < ids.length; i++) {
mSwipeableChildren[i] = findViewById(ids[i]);
}
}
/**
* This method controls when the swipe-to-refresh gesture is triggered. By returning false here
* we are signifying that the view is in a state where a refresh gesture can start.
*
* <p>As {@link android.support.v4.widget.SwipeRefreshLayout} only supports one direct child by
* default, we need to manually iterate through our swipeable children to see if any are in a
* state to trigger the gesture. If so we return false to start the gesture.
*/
public boolean canChildScrollUp(MotionEvent ev) {
if (mSwipeableChildren != null && mSwipeableChildren.length > 0
&& ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
// Iterate through the scrollable children and check if any of them can not scroll up
// 找到那个能接受到 ev 的控件
View target = null;
for (View view : mSwipeableChildren) {
if (view != null && view.isShown() && isInViewRect(ev, view)) {
target = view;
}
}
// 当前接受滑动事件的ListView是否可以向上滑动
if (target != null && canViewScrollUp(target) ) {
canChildScrollUp = true;
}else{
canChildScrollUp = false;
}
}
return canChildScrollUp;
}
/**
* 判断点击事件是否在目标控件内
* @param ev
* @param view
* @return
*/
private static boolean isInViewRect(MotionEvent ev, View view){
//计算View的坐标
int location[] = new int[2];
view.getLocationOnScreen(location);
RectF viewRectF = new RectF(
location[0], location[1],
location[0]+view.getWidth(), location[1] + view.getHeight()
);
float xOnScreen = ev.getRawX();
float yOnScreen = ev.getRawY();
return viewRectF.contains(xOnScreen, yOnScreen);
}
/**
* Utility method to check whether a {@link View} can scroll up from it's current position.
* Handles platform version differences, providing backwards compatible functionality where
* needed.
*/
private static boolean canViewScrollUp(View view) {
if (android.os.Build.VERSION.SDK_INT >= 14) {
// For ICS and above we can call canScrollVertically() to determine this
return ViewCompat.canScrollVertically(view, -1);
} else {
if (view instanceof AbsListView) {
// Pre-ICS we need to manually check the first visible item and the child view's top
// value
final AbsListView listView = (AbsListView) view;
return listView.getChildCount() > 0 &&
(listView.getFirstVisiblePosition() > 0
|| listView.getChildAt(0).getTop() < listView.getPaddingTop());
} else {
// For all other view types we just check the getScrollY() value
return view.getScrollY() > 0;
}
}
}
更改原始方法:canChildScrollUp() - &gt;&gt; canChildScrollUp(MotionEvent ev), 并添加一个字段:canChildScrollUp。其余内容与上面的google sammple相同。
好的,然后我们可以添加多个ListView或ScrollView或TextView或其他widget.I意味着我们可以在SwipeRefreshLayout中包含多个ListView。
我是中国人,为了上帝的缘故,原谅我的英语水平。