mom*_*oja 11 android android-recyclerview android-collapsingtoolbarlayout
我实现了一个带有recyclerview的collapsingtoolbar布局,如附带的示例代码所示.我的问题是,当我向下推送列表时,它不会一直到顶部.
会发生什么,滚动停止在AppBarLayout应该结束的点.
我想要的效果是向下推送列表,列表将一直到顶部并显示/扩展AppBarLayout
我的minSdk是14.非常感谢任何帮助或建议.
<?xml version="1.0" encoding="utf-8"?>
Run Code Online (Sandbox Code Playgroud)
<android.support.design.widget.AppBarLayout>
<android.support.design.widget.CollapsingToolbarLayout
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<LinearLayout
app:layout_collapseMode="parallax">
//some elements
</LinearLayout>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
app:layout_behavior="@string/appbar_scrolling_view_behavior"/> //value android.support.design.widget.AppBarLayout$ScrollingViewBehavior
<android.support.v7.widget.Toolbar
app:popupTheme="@style/AppTheme.PopupOverlay"
app:layout_collapseMode="parallax" />
Run Code Online (Sandbox Code Playgroud)
kaz*_*hiu 12
我遇到了类似的问题,当RecyclerView投入到顶部时,我使用了一个简单的技巧来扩展AppBarLayout(你需要支持库> = 23.xx)
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
int firstVisiblePosition = linearLayoutManager.findFirstCompletelyVisibleItemPosition();
if (firstVisiblePosition == 0) {
mAppBarLayout.setExpanded(true, true);
}
}
}
});
Run Code Online (Sandbox Code Playgroud)
您可以使用该setExpanded()方法完全展开或折叠App Bar .一个实现可能涉及覆盖dispatchTouchEvent()您的Activity类,并根据它是否在中途点折叠自动折叠/扩展您的App Bar:
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
float per = Math.abs(mAppBarLayout.getY()) / mAppBarLayout.getTotalScrollRange();
boolean setExpanded = (per <= 0.5F);
mAppBarLayout.setExpanded(setExpanded, true);
}
return super.dispatchTouchEvent(event);
}
Run Code Online (Sandbox Code Playgroud)
关于在fling上自动滚动到最后一个位置,我在GitHub上放了一些代码,显示了如何以编程方式平滑滚动到可能有用的特定位置.调用滚动到list.size() - 1上一个fling例如可以复制的行为.顺便说一下,这段代码的部分内容改编自StylingAndroid和Novoda博客:
public class RecyclerLayoutManager extends LinearLayoutManager {
private AppBarManager mAppBarManager;
private int visibleHeightForRecyclerView;
public RecyclerLayoutManager(Context context) {
super(context);
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
View firstVisibleChild = recyclerView.getChildAt(0);
final int childHeight = firstVisibleChild.getHeight();
int distanceInPixels = ((findFirstVisibleItemPosition() - position) * childHeight);
if (distanceInPixels == 0) {
distanceInPixels = (int) Math.abs(firstVisibleChild.getY());
}
//Called Once
if (visibleHeightForRecyclerView == 0) {
visibleHeightForRecyclerView = mAppBarManager.getVisibleHeightForRecyclerViewInPx();
}
//Subtract one as adapter position 0 based
final int visibleChildCount = visibleHeightForRecyclerView/childHeight - 1;
if (position <= visibleChildCount) {
//Scroll to the very top and expand the app bar
position = 0;
mAppBarManager.expandAppBar();
} else {
mAppBarManager.collapseAppBar();
}
SmoothScroller smoothScroller = new SmoothScroller(recyclerView.getContext(), Math.abs(distanceInPixels), 1000);
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
public void setAppBarManager(AppBarManager appBarManager) {
mAppBarManager = appBarManager;
}
private class SmoothScroller extends LinearSmoothScroller {
private static final int TARGET_SEEK_SCROLL_DISTANCE_PX = 10000;
private final float distanceInPixels;
private final float duration;
public SmoothScroller(Context context, int distanceInPixels, int duration) {
super(context);
this.distanceInPixels = distanceInPixels;
float millisecondsPerPx = calculateSpeedPerPixel(context.getResources().getDisplayMetrics());
this.duration = distanceInPixels < TARGET_SEEK_SCROLL_DISTANCE_PX ?
(int) (Math.abs(distanceInPixels) * millisecondsPerPx) : duration;
}
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return RecyclerLayoutManager.this
.computeScrollVectorForPosition(targetPosition);
}
@Override
protected int calculateTimeForScrolling(int dx) {
float proportion = (float) dx / distanceInPixels;
return (int) (duration * proportion);
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
AppBarManager在上面的代码段指的是interface用于与通信AppBarLayout中的Activity.使用动画折叠/展开应用栏方法即可.最后一个方法用于计算RecyclerView屏幕上可见的行数:
public interface AppBarManager {
void collapseAppBar();
void expandAppBar();
int getVisibleHeightForRecyclerViewInPx();
}
Run Code Online (Sandbox Code Playgroud)
public class MainActivity extends AppCompatActivity implements AppBarManager{
@Override
public void collapseAppBar() {
mAppBarLayout.setExpanded(false, true);
}
@Override
public void expandAppBar() {
mAppBarLayout.setExpanded(true, true);
}
@Override
public int getVisibleHeightForRecyclerViewInPx() {
if (mRecyclerFragment == null) mRecyclerFragment =
(RecyclerFragment) getSupportFragmentManager().findFragmentByTag(RecyclerFragment.TAG);
int windowHeight, appBarHeight, headerViewHeight;
windowHeight = getWindow().getDecorView().getHeight();
appBarHeight = mAppBarLayout.getHeight();
headerViewHeight = mRecyclerFragment.getHeaderView().getHeight();
return windowHeight - (appBarHeight + headerViewHeight);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8344 次 |
| 最近记录: |