SwipeToLoadLayout.setSwipeStyle方法 belw属性不起作用
tancolo opened this issue · 3 comments
问题描述:
版本: 1.0.4
不论是@Aspsine 提供的Demo, 还是自己实际使用时, 发现问题。
使用Recycleview 以及 ListView 将对应的SwipeToLoadLayout布局设置为 app:swipe_style="blew"
不起作用,使用的还是CLASSIC Style。
重现方法:
- 1.导入官方demo
- 2.进入app -> Twitter Style -> RECYCLEVIEW Tab
- 3.下拉刷新,默认是classic模式 (下拉刷新过程中,滑动recycleview可以进入刷新view之下)
- 4.修改fragment包目录下的 TwitterRecyclerFragment.java 对应的布局文件 fragment_twitter_recycler.xml 将
app:swipe_style="classic"
改为app:swipe_style="blew"
- 5.再次编译测试,发现还是跟
classic
一样的效果, 而改用其他的效果 style,[above, scale] 有效果。
奇怪点:
Demo提供了使用java代码修改样式的实例,菜单-> Set Header Footer Via Java -> Style选择 Blow, Header Style,Footer Style默认为 Twitter Style, 发现 blew效果是可以看到!
查看布局文件 fragment_nav_java_code.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="@+id/toolbar"
layout="@layout/layout_toolbar" />
<com.aspsine.swipetoloadlayout.SwipeToLoadLayout
android:id="@+id/swipeToLoadLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#e3e3e3"
tools:context="com.aspsine.swipetoloadlayout.demo.fragment.NavJavaCodeFragment">
<ListView
android:id="@id/swipe_target"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/white"/>
</com.aspsine.swipetoloadlayout.SwipeToLoadLayout>
</LinearLayout>
Demo,然后再代码中动态 添加Header, Footer, 以及设置对应的Style, 相关代码:
view = mInflater.inflate(R.layout.layout_classic_footer, swipeToLoadLayout, false); -> changeFooter
view = mInflater.inflate(R.layout.layout_twitter_header, swipeToLoadLayout, false); -> changeHeader
swipeToLoadLayout.setSwipeStyle(SwipeToLoadLayout.STYLE.BLEW); -> changeStyle
代码分析
不论是设置属性 app:swipe_style="classic"
还是代码控制 swipeToLoadLayout.setSwipeStyle(SwipeToLoadLayout.STYLE.BLEW)
都会执行到 SwipeToLoadLayout.java中的
public void setSwipeStyle(int style) {
this.mStyle = style;
requestLayout();
}
而mStyle在哪里使用,关键是在 layoutChildren
中使用,其中涉及到 Headerview,FooterView, targetView位置的确定。这段代码,没有搞清楚作者的实现逻辑。
疑惑的代码如下:
if (mHeaderView != null) {
...
switch (mStyle) {
case STYLE.CLASSIC:
// classic
headerTop = paddingTop + lp.topMargin - mHeaderHeight + mHeaderOffset;
break;
case STYLE.ABOVE:
// classic
headerTop = paddingTop + lp.topMargin - mHeaderHeight + mHeaderOffset;
break;
case STYLE.BLEW: //问题点???
// blew
headerTop = paddingTop + lp.topMargin;
break;
case STYLE.SCALE:
// scale
headerTop = paddingTop + lp.topMargin - mHeaderHeight / 2 + mHeaderOffset / 2;
break;
default:
// classic
headerTop = paddingTop + lp.topMargin - mHeaderHeight + mHeaderOffset;
break;
}
final int headerRight = headerLeft + headerView.getMeasuredWidth();
final int headerBottom = headerTop + headerView.getMeasuredHeight();
headerView.layout(headerLeft, headerTop, headerRight, headerBottom);
}
// layout target
if (mTargetView != null) {
...
switch (mStyle) {
case STYLE.CLASSIC:
// classic
targetTop = paddingTop + lp.topMargin + mTargetOffset;
break;
case STYLE.ABOVE:
// above
targetTop = paddingTop + lp.topMargin;
break;
case STYLE.BLEW: //问题点???
// classic
targetTop = paddingTop + lp.topMargin + mTargetOffset;
break;
case STYLE.SCALE:
// classic
targetTop = paddingTop + lp.topMargin + mTargetOffset;
break;
default:
// classic
targetTop = paddingTop + lp.topMargin + mTargetOffset;
break;
}
final int targetRight = targetLeft + targetView.getMeasuredWidth();
final int targetBottom = targetTop + targetView.getMeasuredHeight();
targetView.layout(targetLeft, targetTop, targetRight, targetBottom);
}
// layout footer
if (mFooterView != null) {
...
switch (mStyle) {
case STYLE.CLASSIC:
// classic
footerBottom = height - paddingBottom - lp.bottomMargin + mFooterHeight + mFooterOffset;
break;
case STYLE.ABOVE:
// classic
footerBottom = height - paddingBottom - lp.bottomMargin + mFooterHeight + mFooterOffset;
break;
case STYLE.BLEW: //问题点???
// blew
footerBottom = height - paddingBottom - lp.bottomMargin;
break;
case STYLE.SCALE:
// scale
footerBottom = height - paddingBottom - lp.bottomMargin + mFooterHeight / 2 + mFooterOffset / 2;
break;
default:
// classic
footerBottom = height - paddingBottom - lp.bottomMargin + mFooterHeight + mFooterOffset;
break;
}
final int footerTop = footerBottom - footerView.getMeasuredHeight();
final int footerRight = footerLeft + footerView.getMeasuredWidth();
footerView.layout(footerLeft, footerTop, footerRight, footerBottom);
}
总感觉 case BLEW: 的处理跟其他的差别很大
作者要是能看到,还请核实下代码,若有可能,可以简单介绍下 layoutChildren
考虑的逻辑。
谢谢!
你好,经过测试,修改fragment_twitter_recycler.xml
app:swipe_style="blew"
是有效果的。
请观察,classic的header是从上面拉出来的。而blew模式下,header是被盖在recyclerView下面的。
<com.aspsine.swipetoloadlayout.SwipeToLoadLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/swipeToLoadLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/style_window_background"
app:swipe_style="blew"
tools:context="com.aspsine.swipetoloadlayout.demo.fragment.TwitterRecyclerFragment">
<include
android:id="@id/swipe_refresh_header"
layout="@layout/layout_twitter_header" />
<android.support.v7.widget.RecyclerView
android:id="@id/swipe_target"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false" />
<include
android:id="@id/swipe_load_more_footer"
layout="@layout/layout_classic_footer" />
</com.aspsine.swipetoloadlayout.SwipeToLoadLayout>
// layout header
if (mHeaderView != null) {
final View headerView = mHeaderView;
MarginLayoutParams lp = (MarginLayoutParams) headerView.getLayoutParams();
final int headerLeft = paddingLeft + lp.leftMargin;
final int headerTop;
switch (mStyle) {
case STYLE.CLASSIC:
// classic
headerTop = paddingTop + lp.topMargin - mHeaderHeight + mHeaderOffset;
break;
case STYLE.ABOVE:
// classic
headerTop = paddingTop + lp.topMargin - mHeaderHeight + mHeaderOffset;
break;
case STYLE.BLEW:
// blew
headerTop = paddingTop + lp.topMargin; // blew 模式下,下拉过程中,header 的位置一直保持不变。
break;
case STYLE.SCALE:
// scale
headerTop = paddingTop + lp.topMargin - mHeaderHeight / 2 + mHeaderOffset / 2;
break;
default:
// classic
headerTop = paddingTop + lp.topMargin - mHeaderHeight + mHeaderOffset;
break;
}
final int headerRight = headerLeft + headerView.getMeasuredWidth();
final int headerBottom = headerTop + headerView.getMeasuredHeight();
headerView.layout(headerLeft, headerTop, headerRight, headerBottom);
}
// layout target
if (mTargetView != null) {
final View targetView = mTargetView;
MarginLayoutParams lp = (MarginLayoutParams) targetView.getLayoutParams();
final int targetLeft = paddingLeft + lp.leftMargin;
final int targetTop;
switch (mStyle) {
case STYLE.CLASSIC:
// classic
targetTop = paddingTop + lp.topMargin + mTargetOffset;
break;
case STYLE.ABOVE:
// above
targetTop = paddingTop + lp.topMargin;
break;
case STYLE.BLEW:
// classic
targetTop = paddingTop + lp.topMargin + mTargetOffset; // blew 模式下,下拉过程中,targetView 就像classic的模式一下一样,下拉需要增大顶部间距,这样就可以漏出header; 上拉过程中,target需要减少顶部间距为负值,这样就可以漏出footer
break;
case STYLE.SCALE:
// classic
targetTop = paddingTop + lp.topMargin + mTargetOffset;
break;
default:
// classic
targetTop = paddingTop + lp.topMargin + mTargetOffset;
break;
}
final int targetRight = targetLeft + targetView.getMeasuredWidth();
final int targetBottom = targetTop + targetView.getMeasuredHeight();
targetView.layout(targetLeft, targetTop, targetRight, targetBottom);
}
// layout footer
if (mFooterView != null) {
final View footerView = mFooterView;
MarginLayoutParams lp = (MarginLayoutParams) footerView.getLayoutParams();
final int footerLeft = paddingLeft + lp.leftMargin;
final int footerBottom;
switch (mStyle) {
case STYLE.CLASSIC:
// classic
footerBottom = height - paddingBottom - lp.bottomMargin + mFooterHeight + mFooterOffset;
break;
case STYLE.ABOVE:
// classic
footerBottom = height - paddingBottom - lp.bottomMargin + mFooterHeight + mFooterOffset;
break;
case STYLE.BLEW:
// blew
footerBottom = height - paddingBottom - lp.bottomMargin; // blew 模式下,下拉过程中,footer位置不变
break;
case STYLE.SCALE:
// scale
footerBottom = height - paddingBottom - lp.bottomMargin + mFooterHeight / 2 + mFooterOffset / 2;
break;
default:
// classic
footerBottom = height - paddingBottom - lp.bottomMargin + mFooterHeight + mFooterOffset;
break;
}
final int footerTop = footerBottom - footerView.getMeasuredHeight();
final int footerRight = footerLeft + footerView.getMeasuredWidth();
footerView.layout(footerLeft, footerTop, footerRight, footerBottom);
}
@Aspsine 将header view, footer view添加其他颜色,区别与整体颜色。
发现确实,如你所说, classic style, header & recycleview一起,blew style,header 在最上面,Recyclerview 在下拉的过程中会跟header分离。
为止,录制了 2个小视频,你可以看下! 一个是修改你的demo,一个是我自己的demo
http://pan.baidu.com/s/1i4LduxZ
http://pan.baidu.com/s/1qY8UbNY
所以,BELW 的含义,其实是在下拉的过程中,header view其实是在 recycleview的下面。
但是 从视频效果上看,你的比我的好看多了,我的还会闪烁一下! 这应该是我Recyclerview底部透明的缘故?
是的,recyclerview背景透明的缘故。