
我正在制作一个应用程序,我正在使用带有SnapHelper类的recyclervIEw来制作可滚动的水平cardstack我已经成功实现了但是我的问题是卡向右滑动方向并且我想在左方向上刷卡.
我做了一些关于SO的研究并发现了这一点
RecyclerView horizontal scroll snap in center
SnapHelper Item Position
但我仍然无法弄清楚如何将滚动位置设置为左侧而不是右侧
请任何帮助将不胜感激
更新:我仍然在努力解决这个问题,因为在recyclervIEw中改变滚动的方向仍然很难,所以任何人都想帮助我.
我还发现findsnapVIEw方法传递滚动位置和方向可能我错了但是beow code mght是解决方案
**@OverrIDe public VIEw findSnapVIEw(RecyclerVIEw.LayoutManager layoutManager) { if (layoutManager instanceof LadderLayoutManager) { int pos = ((LadderLayoutManager) layoutManager).getFixedScrollposition( mDirection, mDirection != 0 ? 0.8f : 0.5f); mDirection = 0; if (pos != RecyclerVIEw.NO_position) { return layoutManager.findVIEwByposition(pos); } } return null; }**我的主要课程
public class MainActivity extends AppCompatActivity { LadderLayoutManager llm; RecyclerVIEw rcv; HSAdapter adapter; int scrollToposition; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main); llm = new LadderLayoutManager(1.5f, 0.85f, LadderLayoutManager.HORIZONTAL). setChildDecorateHelper(new LadderLayoutManager .DefaultChildDecorateHelper(getResources().getDimension(R.dimen.item_max_elevation))); llm.setChildPeekSize((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, getResources().getdisplayMetrics())); llm.setMaxItemLayoutCount(5); rcv = (RecyclerVIEw) findVIEwByID(R.ID.rcv); rcv.setLayoutManager(llm); new LadderSimpleSnapHelper().attachToRecyclerVIEw(rcv); adapter = new HSAdapter(); rcv.setAdapter(adapter); final Seekbar sb = (Seekbar) findVIEwByID(R.ID.sb); }我自定义LayoutManager的代码
public class LadderLayoutManager extends RecyclerVIEw.LayoutManager implements RecyclerVIEw.SmoothScroller.ScrollVectorProvIDer { private static final int INVALIDATE_SCRolL_OFFSET = Integer.MAX_VALUE; private static final float DEFAulT_CHILD_LAYOUT_OFFSET = 0.2f; public static final int UNliMITED = 0; public static final int VERTICAL = 1; public static final int HORIZONTAL = 0; private boolean mCheckedChildSize; private int[] mChildSize; private int mChildPeekSize; private int mChildPeekSizeinput; private boolean mReverse; private int mScrollOffset = INVALIDATE_SCRolL_OFFSET; private float mItemHeightWIDthRatio; private float mScale; private int mChildCount; private float mVanishOffset = 0; private Interpolator mInterpolator; private int mOrIEntation; private ChildDecorateHelper mDecorateHelper; private int mMaxItemLayoutCount; public LadderLayoutManager(float itemHeightWIDthRatio) { this(itemHeightWIDthRatio, 0.9f, VERTICAL); } public LadderLayoutManager(float itemHeightWIDthRatio, float scale, int orIEntation) { this.mItemHeightWIDthRatio = itemHeightWIDthRatio; this.mOrIEntation = orIEntation; this.mScale = scale; this.mChildSize = new int[2]; this.mInterpolator = new DecelerateInterpolator(); } @OverrIDe public RecyclerVIEw.LayoutParams generateDefaultLayoutParams() { return new RecyclerVIEw.LayoutParams(mChildSize[0], mChildSize[1]); } public LadderLayoutManager setChildDecorateHelper(ChildDecorateHelper layoutHelper) { mDecorateHelper = layoutHelper; return this; } public voID setMaxItemLayoutCount(int count) { mMaxItemLayoutCount = Math.max(2, count); if (getChildCount() > 0) { requestLayout(); } } public voID setVanishOffset(float offset) { mVanishOffset = offset; if (getChildCount() > 0) { requestLayout(); } } public voID setChildPeekSize(int childPeekSize) { mChildPeekSizeinput = childPeekSize; mCheckedChildSize = false; if (getChildCount() > 0) { requestLayout(); } } public voID setItemHeightWIDthRatio(float itemHeightWIDthRatio) { mItemHeightWIDthRatio = itemHeightWIDthRatio; mCheckedChildSize = false; if (getChildCount() > 0) { requestLayout(); } } public voID setReverse(boolean reverse) { if (mReverse != reverse) { mReverse = reverse; if (getChildCount() > 0) { requestLayout(); } } } public boolean isReverse() { return mReverse; } public int getFixedScrollposition(int direction, float fixValue) { if (mCheckedChildSize) { if (mScrollOffset % mChildSize[mOrIEntation] == 0) { return RecyclerVIEw.NO_position; } float position = mScrollOffset * 1.0f / mChildSize[mOrIEntation]; return convert2Adapterposition((int) (direction > 0 ? position + fixValue : position + (1 - fixValue)) - 1); } return RecyclerVIEw.NO_position; } @OverrIDe public voID onMeasure(RecyclerVIEw.Recycler recycler, RecyclerVIEw.State state, int wIDthSpec, int heightSpec) { super.onMeasure(recycler, state, wIDthSpec, heightSpec); mCheckedChildSize = false; } @OverrIDe public voID onLayoutChildren(RecyclerVIEw.Recycler recycler, RecyclerVIEw.State state) { if (state.getItemCount() == 0) { removeAndRecycleAllVIEws(recycler); return; } if (!mCheckedChildSize) { if (mOrIEntation == VERTICAL) { mChildSize[0] = getHorizontalSpace(); mChildSize[1] = (int) (mItemHeightWIDthRatio * mChildSize[0]); } else { mChildSize[1] = getVerticalSpace(); mChildSize[0] = (int) (mChildSize[1] / mItemHeightWIDthRatio); } mChildPeekSize = mChildPeekSizeinput == 0 ? (int) (mChildSize[mOrIEntation] * DEFAulT_CHILD_LAYOUT_OFFSET) : mChildPeekSizeinput; mCheckedChildSize = true; } int itemCount = getItemCount(); if (mReverse) { mScrollOffset += (itemCount - mChildCount) * mChildSize[mOrIEntation]; } mChildCount = itemCount; mScrollOffset = makeScrollOffsetWithinRange(mScrollOffset); fill(recycler); } public voID fill(RecyclerVIEw.Recycler recycler) { int bottomItemposition = (int) Math.floor(mScrollOffset / mChildSize[mOrIEntation]);//>=1 int bottomItemVisibleSize = mScrollOffset % mChildSize[mOrIEntation]; final float offsetPercent = mInterpolator.getInterpolation( bottomItemVisibleSize * 1.0f / mChildSize[mOrIEntation]);//[0,1) final int space = mOrIEntation == VERTICAL ? getVerticalSpace() : getHorizontalSpace(); ArrayList<ItemLayoutInfo> layoutInfos = new ArrayList<>(); for (int i = bottomItemposition - 1, j = 1, remainSpace = space - mChildSize[mOrIEntation]; i >= 0; i--, j++) { double maxOffset = mChildPeekSize * Math.pow(mScale, j); int start = (int) (remainSpace - offsetPercent * maxOffset); ItemLayoutInfo info = new ItemLayoutInfo(start, (float) (Math.pow(mScale, j - 1) * (1 - offsetPercent * (1 - mScale))), offsetPercent, start * 1.0f / space ); layoutInfos.add(0, info); if (mMaxItemLayoutCount != UNliMITED && j == mMaxItemLayoutCount - 1) { if (offsetPercent != 0) { info.start = remainSpace; info.positionOffsetPercent = 0; info.layoutPercent = remainSpace / space; info.scaleXY = (float) Math.pow(mScale, j - 1); } break; } remainSpace -= maxOffset; if (remainSpace <= 0) { info.start = (int) (remainSpace + maxOffset); info.positionOffsetPercent = 0; info.layoutPercent = info.start / space; info.scaleXY = (float) Math.pow(mScale, j - 1); break; } } if (bottomItemposition < mChildCount) { final int start = space - bottomItemVisibleSize; layoutInfos.add(new ItemLayoutInfo(start, 1.0f, bottomItemVisibleSize * 1.0f / mChildSize[mOrIEntation], start * 1.0f / space). setIsBottom()); } else { bottomItemposition -= 1; } int layoutCount = layoutInfos.size(); final int startPos = bottomItemposition - (layoutCount - 1); final int endPos = bottomItemposition; final int childCount = getChildCount(); for (int i = childCount - 1; i >= 0; i--) { VIEw childVIEw = getChildAt(i); int pos = convert2Layoutposition(getposition(childVIEw)); if (pos > endPos || pos < startPos) { removeAndRecycleVIEw(childVIEw, recycler); } } detachAndScrapAttachedVIEws(recycler); for (int i = 0; i < layoutCount; i++) { fillChild(recycler.getVIEwForposition(convert2Adapterposition(startPos + i)), layoutInfos.get(i)); } } private voID fillChild(VIEw vIEw, ItemLayoutInfo layoutInfo) { addVIEw(vIEw); measureChilDWithExactlySize(vIEw); final int scaleFix = (int) (mChildSize[mOrIEntation] * (1 - layoutInfo.scaleXY) / 2); final float gap = (mOrIEntation == VERTICAL ? getHorizontalSpace() : getVerticalSpace()) - mChildSize[(mOrIEntation + 1) % 2] * layoutInfo.scaleXY; if (mOrIEntation == VERTICAL) { int left = (int) (getpaddingleft() + (gap * 0.5 * mVanishOffset)); layoutDecorateDWithmargins(vIEw, left, layoutInfo.start - scaleFix , left + mChildSize[0], layoutInfo.start + mChildSize[1] - scaleFix); } else { int top = (int) (getpaddingtop() + (gap * 0.5 * mVanishOffset)); layoutDecorateDWithmargins(vIEw, layoutInfo.start - scaleFix, top , layoutInfo.start + mChildSize[0] - scaleFix, top + mChildSize[1]); } VIEwCompat.setScaleX(vIEw, layoutInfo.scaleXY); VIEwCompat.setScaleY(vIEw, layoutInfo.scaleXY); if (mDecorateHelper != null) { mDecorateHelper.decorateChild(vIEw, layoutInfo.positionOffsetPercent, layoutInfo.layoutPercent, layoutInfo.isBottom); } } private voID measureChilDWithExactlySize(VIEw child) { RecyclerVIEw.LayoutParams lp = (RecyclerVIEw.LayoutParams) child.getLayoutParams(); final int wIDthSpec = VIEw.MeasureSpec.makeMeasureSpec( mChildSize[0] - lp.leftmargin - lp.rightmargin, VIEw.MeasureSpec.EXACTLY); final int heightSpec = VIEw.MeasureSpec.makeMeasureSpec( mChildSize[1] - lp.topmargin - lp.bottommargin, VIEw.MeasureSpec.EXACTLY); child.measure(wIDthSpec, heightSpec); } private int makeScrollOffsetWithinRange(int scrollOffset) { return Math.min(Math.max(mChildSize[mOrIEntation], scrollOffset), mChildCount * mChildSize[mOrIEntation]); } @OverrIDe public int scrollVerticallyBy(int dy, RecyclerVIEw.Recycler recycler, RecyclerVIEw.State state) { int pendingScrollOffset = mScrollOffset + dy; mScrollOffset = makeScrollOffsetWithinRange(pendingScrollOffset); fill(recycler); return mScrollOffset - pendingScrollOffset + dy; } @OverrIDe public int scrollHorizontallyBy(int dx, RecyclerVIEw.Recycler recycler, RecyclerVIEw.State state) { int pendingScrollOffset = mScrollOffset + dx; mScrollOffset = makeScrollOffsetWithinRange(pendingScrollOffset); fill(recycler); return mScrollOffset - pendingScrollOffset + dx; } @OverrIDe public voID smoothScrollToposition(RecyclerVIEw recyclerVIEw, RecyclerVIEw.State state, int position) { final linearSmoothScroller linearSmoothScroller = new linearSmoothScroller(recyclerVIEw.getContext()) { @OverrIDe public int calculateDyTomakeVisible(final VIEw vIEw, final int snapPreference) { if (mOrIEntation == VERTICAL) { return -calculatedistancetoposition(getposition(vIEw)); } return 0; } @OverrIDe public int calculateDxTomakeVisible(final VIEw vIEw, final int snapPreference) { if (mOrIEntation == HORIZONTAL) { return -calculatedistancetoposition(getposition(vIEw)); } return 0; } }; linearSmoothScroller.setTargetposition(position); startSmoothScroll(linearSmoothScroller); } public int calculatedistancetoposition(int targetPos) { int pendingScrollOffset = mChildSize[mOrIEntation] * (convert2Layoutposition(targetPos) + 1); return pendingScrollOffset - mScrollOffset; } @OverrIDe public voID scrollToposition(int position) { if (position > 0 && position < mChildCount) { mScrollOffset = mChildSize[mOrIEntation] * (convert2Layoutposition(position) + 1); requestLayout(); } } @OverrIDe public boolean canScrollVertically() { return mOrIEntation == VERTICAL; } @OverrIDe public boolean canScrollHorizontally() { return mOrIEntation == HORIZONTAL; } public int convert2Adapterposition(int layoutposition) { return mReverse ? mChildCount - 1 - layoutposition : layoutposition; } public int convert2Layoutposition(int adapterPostion) { return mReverse ? mChildCount - 1 - adapterPostion : adapterPostion; } public int getVerticalSpace() { return getHeight() - getpaddingtop() - getpaddingBottom(); } public int getHorizontalSpace() { return getWIDth() - getpaddingleft() - getpaddingRight(); } @OverrIDe public PointF computeScrollVectorForposition(int targetposition) { int pos = convert2Layoutposition(targetposition); int scrollOffset = (pos + 1) * mChildSize[mOrIEntation]; return mOrIEntation == VERTICAL ? new PointF(0, Math.signum(scrollOffset - mScrollOffset)) : new PointF(Math.signum(scrollOffset - mScrollOffset), 0); } private static class ItemLayoutInfo { float scaleXY; float layoutPercent; float positionOffsetPercent; int start; boolean isBottom; ItemLayoutInfo(int top, float scale, float positonOffset, float percent) { this.start = top; this.scaleXY = scale; this.positionOffsetPercent = positonOffset; this.layoutPercent = percent; } ItemLayoutInfo setIsBottom() { isBottom = true; return this; } } @OverrIDe public Parcelable onSaveInstanceState() { SavedState savedState = new SavedState(); savedState.scrollOffset = mScrollOffset; savedState.reverse = mReverse; savedState.vanishOffset = mVanishOffset; savedState.scale = mScale; savedState.childLayoutOffsetinput = mChildPeekSizeinput; savedState.itemHeightWIDthRatio = mItemHeightWIDthRatio; savedState.orIEntation = mOrIEntation; return savedState; } @OverrIDe public voID onRestoreInstanceState(Parcelable state) { if (state instanceof SavedState) { SavedState s = (SavedState) state; mScrollOffset = s.scrollOffset; mReverse = s.reverse; mVanishOffset = s.vanishOffset; mScale = s.scale; mChildPeekSizeinput = s.childLayoutOffsetinput; mItemHeightWIDthRatio = s.itemHeightWIDthRatio; mOrIEntation = s.orIEntation; requestLayout(); } } public static class SavedState implements Parcelable { int scrollOffset, childLayoutOffsetinput, orIEntation; float itemHeightWIDthRatio, scale, elevation, vanishOffset; boolean reverse; public SavedState() { } SavedState(LadderLayoutManager.SavedState other) { scrollOffset = other.scrollOffset; childLayoutOffsetinput = other.childLayoutOffsetinput; orIEntation = other.orIEntation; itemHeightWIDthRatio = other.itemHeightWIDthRatio; scale = other.scale; elevation = other.elevation; vanishOffset = other.vanishOffset; reverse = other.reverse; } SavedState(Parcel in) { scrollOffset = in.readInt(); childLayoutOffsetinput = in.readInt(); orIEntation = in.readInt(); itemHeightWIDthRatio = in.readfloat(); scale = in.readfloat(); elevation = in.readfloat(); vanishOffset = in.readfloat(); reverse = in.readInt() == 1; } @OverrIDe public voID writetoParcel(Parcel dest, int flags) { dest.writeInt(scrollOffset); dest.writeInt(childLayoutOffsetinput); dest.writeInt(orIEntation); dest.writefloat(itemHeightWIDthRatio); dest.writefloat(scale); dest.writefloat(elevation); dest.writefloat(vanishOffset); dest.writeInt(reverse ? 1 : 0); } @OverrIDe public int describeContents() { return 0; } public static final Creator<SavedState> CREATOR = new Creator<SavedState>() { @OverrIDe public LadderLayoutManager.SavedState createFromParcel(Parcel in) { return new LadderLayoutManager.SavedState(in); } @OverrIDe public LadderLayoutManager.SavedState[] newArray(int size) { return new LadderLayoutManager.SavedState[size]; } }; } public interface ChildDecorateHelper { voID decorateChild(VIEw child, float posOffsetPercent, float layoutPercent, boolean isBottom); } public static class DefaultChildDecorateHelper implements ChildDecorateHelper { private float mElevation; public DefaultChildDecorateHelper(float maxElevation) { mElevation = maxElevation; } @OverrIDe public voID decorateChild(VIEw child, float posOffsetPercent, float layoutPercent, boolean isBottom) { VIEwCompat.setElevation(child, (float) (layoutPercent * mElevation * 0.7 + mElevation * 0.3)); } }}这是我的SnapHelper代码
public class LadderSimpleSnapHelper extends SnapHelper { private int mDirection; //int position = layoutManager.getposition(centerVIEw); @OverrIDe public int[] calculatedistancetoFinalSnap( @NonNull RecyclerVIEw.LayoutManager layoutManager, @NonNull VIEw targetVIEw) { if (layoutManager instanceof LadderLayoutManager) { int[] out = new int[2]; if (layoutManager.canScrollHorizontally()) { out[0] = ((LadderLayoutManager) layoutManager).calculatedistancetoposition( layoutManager.getposition(targetVIEw)); out[1] = 0; } else { out[0] = 0; out[1] = ((LadderLayoutManager) layoutManager).calculatedistancetoposition( layoutManager.getposition(targetVIEw)); } return out; } return null; } @OverrIDe public int findTargetSnapposition(RecyclerVIEw.LayoutManager layoutManager, int veLocityX, int veLocityY) { if (layoutManager.canScrollHorizontally()) { mDirection = veLocityX; } else { mDirection = veLocityY; } return RecyclerVIEw.NO_position; } @OverrIDe public VIEw findSnapVIEw(RecyclerVIEw.LayoutManager layoutManager) { if (layoutManager instanceof LadderLayoutManager) { int pos = ((LadderLayoutManager) layoutManager).getFixedScrollposition( mDirection, mDirection != 0 ? 0.8f : 0.5f); mDirection = 0; if (pos != RecyclerVIEw.NO_position) { return layoutManager.findVIEwByposition(pos); } } return null; }}解决方法:
尝试以下代码:
mRecyclerVIEw.setLayoutManager(new linearlayoutmanager(this, linearlayoutmanager.HORIZONTAL, true));mRecyclerVIEw.setReverseLayout(true); 总结 以上是内存溢出为你收集整理的java – recyclelerview水平滚动到左边全部内容,希望文章能够帮你解决java – recyclelerview水平滚动到左边所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)