项目中开发日历功能,需求是可以连续滑动多页,有列表的流畅。又要保持当前页居中显示。

参考文献:  http://www.open-open.com/lib/view/open1435026935638.html

                    http://mp.weixin.qq.com/s/DMksgHOuGWhztESGfDgucA?utm_source=tuicool&utm_medium=referral

效果图:

1.  继承自RecyclerView的ViewPager:

/**
* Created by Administrator on 2017/6/9.
* 基于RecyclerView实现的ViewPager,支持类似于gallary的fling操作
* http://www.open-open.com/lib/view/open1435026935638.html
*/
public class RecyclerViewPager extends RecyclerView {
public static final boolean DEBUG = BuildConfig.DEBUG;

private RecyclerViewPagerAdapter<?> mViewPagerAdapter;
private float mTriggerOffset = 0.25f;
private float mFlingFactor = 0.15f;
private float mMillisecondsPerInch = 25f;
private float mTouchSpan;
private List<OnPageChangedListener> mOnPageChangedListeners;
private int mSmoothScrollTargetPosition = -1;
private int mPositionBeforeScroll = -1;

private boolean mSinglePageFling;
boolean isInertia; // inertia slide state
float minSlideDistance;
PointF touchStartPoint;

boolean mNeedAdjust;
int mFisrtLeftWhenDragging;
int mFirstTopWhenDragging;
View mCurView;
int mMaxLeftWhenDragging = Integer.MIN_VALUE;
int mMinLeftWhenDragging = Integer.MAX_VALUE;
int mMaxTopWhenDragging = Integer.MIN_VALUE;
int mMinTopWhenDragging = Integer.MAX_VALUE;
private int mPositionOnTouchDown = -1;
private boolean mHasCalledOnPageChanged = true;
private boolean reverseLayout = false;
private float mLastY;

public RecyclerViewPager(Context context) {
this(context, null);
}

public RecyclerViewPager(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public RecyclerViewPager(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initAttrs(context, attrs, defStyle);
setNestedScrollingEnabled(false);
ViewConfiguration viewConfiguration = ViewConfiguration.get(context);
minSlideDistance = viewConfiguration.getScaledTouchSlop();
}

private void initAttrs(Context context, AttributeSet attrs, int defStyle) {
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecyclerViewPager, defStyle,
0);
mFlingFactor = a.getFloat(R.styleable.RecyclerViewPager_rvp_flingFactor, 0.15f);
mTriggerOffset = a.getFloat(R.styleable.RecyclerViewPager_rvp_triggerOffset, 0.25f);
mSinglePageFling = a.getBoolean(R.styleable.RecyclerViewPager_rvp_singlePageFling, mSinglePageFling);
isInertia = a.getBoolean(R.styleable.RecyclerViewPager_rvp_inertia, false);
mMillisecondsPerInch = a.getFloat(R.styleable.RecyclerViewPager_rvp_millisecondsPerInch, 25f);
a.recycle();
}

public void setFlingFactor(float flingFactor) {
mFlingFactor = flingFactor;
}

public float getFlingFactor() {
return mFlingFactor;
}

public void setTriggerOffset(float triggerOffset) {
mTriggerOffset = triggerOffset;
}

public float getTriggerOffset() {
return mTriggerOffset;
}

public void setSinglePageFling(boolean singlePageFling) {
mSinglePageFling = singlePageFling;
}

public boolean isSinglePageFling() {
return mSinglePageFling;
}

public boolean isInertia() {
return isInertia;
}

public void setInertia(boolean inertia) {
isInertia = inertia;
}

@Override
protected void onRestoreInstanceState(Parcelable state) {
try {
Field fLayoutState = state.getClass().getDeclaredField("mLayoutState");
fLayoutState.setAccessible(true);
Object layoutState = fLayoutState.get(state);
Field fAnchorOffset = layoutState.getClass().getDeclaredField("mAnchorOffset");
Field fAnchorPosition = layoutState.getClass().getDeclaredField("mAnchorPosition");
fAnchorPosition.setAccessible(true);
fAnchorOffset.setAccessible(true);
if (fAnchorOffset.getInt(layoutState) > 0) {
fAnchorPosition.set(layoutState, fAnchorPosition.getInt(layoutState) - 1);
} else if (fAnchorOffset.getInt(layoutState) < 0) {
fAnchorPosition.set(layoutState, fAnchorPosition.getInt(layoutState) + 1);
}
fAnchorOffset.setInt(layoutState, 0);
} catch (Throwable e) {
e.printStackTrace();
}
super.onRestoreInstanceState(state);
}

@Override
public void setAdapter(Adapter adapter) {
mViewPagerAdapter = ensureRecyclerViewPagerAdapter(adapter);
super.setAdapter(mViewPagerAdapter);
}

@Override
public void swapAdapter(Adapter adapter, boolean removeAndRecycleExistingViews) {
mViewPagerAdapter = ensureRecyclerViewPagerAdapter(adapter);
super.swapAdapter(mViewPagerAdapter, removeAndRecycleExistingViews);
}

@Override
public Adapter getAdapter() {
if (mViewPagerAdapter != null) {
return mViewPagerAdapter.mAdapter;
}
return null;
}

public RecyclerViewPagerAdapter getWrapperAdapter() {
return mViewPagerAdapter;
}

@Override
public void setLayoutManager(LayoutManager layout) {
super.setLayoutManager(layout);

if (layout instanceof LinearLayoutManager) {
reverseLayout = ((LinearLayoutManager) layout).getReverseLayout();
}
}

@Override
public boolean fling(int velocityX, int velocityY) {
boolean flinging = super.fling((int) (velocityX * mFlingFactor), (int) (velocityY * mFlingFactor));
if (flinging) {
if (getLayoutManager().canScrollHorizontally()) {
adjustPositionX(velocityX);
} else {
adjustPositionY(velocityY);
}
}

if (DEBUG) {
Log.d("@", "velocityX:" + velocityX);
Log.d("@", "velocityY:" + velocityY);
}
return flinging;
}

@Override
public void smoothScrollToPosition(int position) {
if (DEBUG) {
Log.d("@", "smoothScrollToPosition:" + position);
}

if (mPositionBeforeScroll < 0) {
mPositionBeforeScroll = getCurrentPosition();
}
mSmoothScrollTargetPosition = position;
if (getLayoutManager() != null && getLayoutManager() instanceof LinearLayoutManager) {
// exclude item decoration
LinearSmoothScroller linearSmoothScroller =
new LinearSmoothScroller(getContext()) {
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
if (getLayoutManager() == null) {
return null;
}
return ((LinearLayoutManager) getLayoutManager())
.computeScrollVectorForPosition(targetPosition);
}

@Override
protected void onTargetFound(View targetView, RecyclerView.State state, Action action) {
if (getLayoutManager() == null) {
return;
}
int dx = calculateDxToMakeVisible(targetView,
getHorizontalSnapPreference());
int dy = calculateDyToMakeVisible(targetView,
getVerticalSnapPreference());
if (dx > 0) {
dx = dx - getLayoutManager()
.getLeftDecorationWidth(targetView);
} else {
dx = dx + getLayoutManager()
.getRightDecorationWidth(targetView);
}
if (dy > 0) {
dy = dy - getLayoutManager()
.getTopDecorationHeight(targetView);
} else {
dy = dy + getLayoutManager()
.getBottomDecorationHeight(targetView);
}
final int distance = (int) Math.sqrt(dx * dx + dy * dy);
final int time = calculateTimeForDeceleration(distance);
if (time > 0) {
action.update(-dx, -dy, time, mDecelerateInterpolator);
}
}

@Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
return mMillisecondsPerInch / displayMetrics.densityDpi;
}

@Override
protected void onStop() {
super.onStop();
if (mOnPageChangedListeners != null) {
for (OnPageChangedListener onPageChangedListener : mOnPageChangedListeners) {
if (onPageChangedListener != null) {
onPageChangedListener.OnPageChanged(mPositionBeforeScroll, mSmoothScrollTargetPosition);
}
}
}
mHasCalledOnPageChanged = true;
}
};

linearSmoothScroller.setTargetPosition(position);
if (position == RecyclerView.NO_POSITION) {
return;
}
getLayoutManager().startSmoothScroll(linearSmoothScroller);
} else {
super.smoothScrollToPosition(position);
}
}

@Override
public void scrollToPosition(int position) {
if (DEBUG) {
Log.d("@", "scrollToPosition:" + position);
}
mPositionBeforeScroll = getCurrentPosition();
mSmoothScrollTargetPosition = position;
super.scrollToPosition(position);

getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < 16) {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}

if (mSmoothScrollTargetPosition >= 0 && mSmoothScrollTargetPosition < getItemCount()) {
if (mOnPageChangedListeners != null) {
for (OnPageChangedListener onPageChangedListener : mOnPageChangedListeners) {
if (onPageChangedListener != null) {
onPageChangedListener.OnPageChanged(mPositionBeforeScroll, getCurrentPosition());
}
}
}
}
}
});
}

private int getItemCount() {
return mViewPagerAdapter == null ? 0 : mViewPagerAdapter.getItemCount();
}

/**
* get item position in center of viewpager
*/
public int getCurrentPosition() {
int curPosition;
if (getLayoutManager().canScrollHorizontally()) {
curPosition = RecycleViewPagerUtils.getCenterXChildPosition(this);
} else {
curPosition = RecycleViewPagerUtils.getCenterYChildPosition(this);
}
if (curPosition < 0) {
curPosition = mSmoothScrollTargetPosition;
}
return curPosition;
}

/***
* adjust position before Touch event complete and fling action start.
*/
protected void adjustPositionX(int velocityX) {
if (reverseLayout) velocityX *= -1;

int childCount = getChildCount();
if (childCount > 0) {
int curPosition = RecycleViewPagerUtils.getCenterXChildPosition(this);
int childWidth = getWidth() - getPaddingLeft() - getPaddingRight();
int flingCount = getFlingCount(velocityX, childWidth);
int targetPosition = curPosition + flingCount;
if (mSinglePageFling) {
flingCount = Math.max(-1, Math.min(1, flingCount));
targetPosition = flingCount == 0 ? curPosition : mPositionOnTouchDown + flingCount;
if (DEBUG) {
Log.d("@", "flingCount:" + flingCount);
Log.d("@", "original targetPosition:" + targetPosition);
}
}
targetPosition = Math.max(targetPosition, 0);
targetPosition = Math.min(targetPosition, getItemCount() - 1);
if (targetPosition == curPosition
&& (!mSinglePageFling || mPositionOnTouchDown == curPosition)) {
View centerXChild = RecycleViewPagerUtils.getCenterXChild(this);
if (centerXChild != null) {
if (mTouchSpan > centerXChild.getWidth() * mTriggerOffset * mTriggerOffset && targetPosition != 0) {
if (!reverseLayout) targetPosition--;
else targetPosition++;
} else if (mTouchSpan < centerXChild.getWidth() * -mTriggerOffset && targetPosition != getItemCount() - 1) {
if (!reverseLayout) targetPosition++;
else targetPosition--;
}
}
}
if (DEBUG) {
Log.d("@", "mTouchSpan:" + mTouchSpan);
Log.d("@", "adjustPositionX:" + targetPosition);
}
smoothScrollToPosition(safeTargetPosition(targetPosition, getItemCount()));
}
}

public void addOnPageChangedListener(OnPageChangedListener listener) {
if (mOnPageChangedListeners == null) {
mOnPageChangedListeners = new ArrayList<>();
}
mOnPageChangedListeners.add(listener);
}

public void removeOnPageChangedListener(OnPageChangedListener listener) {
if (mOnPageChangedListeners != null) {
mOnPageChangedListeners.remove(listener);
}
}

public void clearOnPageChangedListeners() {
if (mOnPageChangedListeners != null) {
mOnPageChangedListeners.clear();
}
}

/***
* adjust position before Touch event complete and fling action start.
*/
protected void adjustPositionY(int velocityY) {
if (reverseLayout) velocityY *= -1;

int childCount = getChildCount();
if (childCount > 0) {
int curPosition = RecycleViewPagerUtils.getCenterYChildPosition(this);
int childHeight = getHeight() - getPaddingTop() - getPaddingBottom();
int flingCount = getFlingCount(velocityY, childHeight);
int targetPosition = curPosition + flingCount;
if (mSinglePageFling) {
flingCount = Math.max(-1, Math.min(1, flingCount));
targetPosition = flingCount == 0 ? curPosition : mPositionOnTouchDown + flingCount;
}

targetPosition = Math.max(targetPosition, 0);
targetPosition = Math.min(targetPosition, getItemCount() - 1);
if (targetPosition == curPosition
&& (!mSinglePageFling || mPositionOnTouchDown == curPosition)) {
View centerYChild = RecycleViewPagerUtils.getCenterYChild(this);
if (centerYChild != null) {
if (mTouchSpan > centerYChild.getHeight() * mTriggerOffset && targetPosition != 0) {
if (!reverseLayout) targetPosition--;
else targetPosition++;
} else if (mTouchSpan < centerYChild.getHeight() * -mTriggerOffset && targetPosition != getItemCount() - 1) {
if (!reverseLayout) targetPosition++;
else targetPosition--;
}
}
}
if (DEBUG) {
Log.d("@", "mTouchSpan:" + mTouchSpan);
Log.d("@", "adjustPositionY:" + targetPosition);
}
smoothScrollToPosition(safeTargetPosition(targetPosition, getItemCount()));
}
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN && getLayoutManager() != null) {
mPositionOnTouchDown = getLayoutManager().canScrollHorizontally()
? RecycleViewPagerUtils.getCenterXChildPosition(this)
: RecycleViewPagerUtils.getCenterYChildPosition(this);
if (DEBUG) {
Log.d("@", "mPositionOnTouchDown:" + mPositionOnTouchDown);
}
mLastY = ev.getRawY();
}
return super.dispatchTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent e) {
// recording the max/min value in touch track
if (e.getAction() == MotionEvent.ACTION_MOVE) {
if (mCurView != null) {
mMaxLeftWhenDragging = Math.max(mCurView.getLeft(), mMaxLeftWhenDragging);
mMaxTopWhenDragging = Math.max(mCurView.getTop(), mMaxTopWhenDragging);
mMinLeftWhenDragging = Math.min(mCurView.getLeft(), mMinLeftWhenDragging);
mMinTopWhenDragging = Math.min(mCurView.getTop(), mMinTopWhenDragging);
}
}
return super.onTouchEvent(e);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
if (isInertia) {
final float x = e.getRawX();
final float y = e.getRawY();
if (touchStartPoint == null)
touchStartPoint = new PointF();
switch (MotionEvent.ACTION_MASK & e.getAction()) {
case MotionEvent.ACTION_DOWN:
touchStartPoint.set(x, y);
break;
case MotionEvent.ACTION_MOVE:
float tempDistance = (float) Math.sqrt(x*x+ y*y);
float lastDistance = (float) Math.sqrt(touchStartPoint.x*touchStartPoint.x + touchStartPoint.y*touchStartPoint.y);

if (Math.abs(lastDistance - tempDistance) > minSlideDistance) {
float k = Math.abs((touchStartPoint.y - y) / (touchStartPoint.x - x));
// prevent tan 90° calc
if (Math.abs(touchStartPoint.y - y) < 1)
return getLayoutManager().canScrollHorizontally();
if (Math.abs(touchStartPoint.x - x) < 1)
return !getLayoutManager().canScrollHorizontally();
return k < Math.tan(Math.toRadians(30F));
}
break;
}
}
return super.onInterceptTouchEvent(e);
}

@Override
public void onScrollStateChanged(int state) {
super.onScrollStateChanged(state);
if (state == SCROLL_STATE_DRAGGING) {
mNeedAdjust = true;
mCurView = getLayoutManager().canScrollHorizontally() ? RecycleViewPagerUtils.getCenterXChild(this) :
RecycleViewPagerUtils.getCenterYChild(this);
if (mCurView != null) {
if (mHasCalledOnPageChanged) {
// While rvp is scrolling, mPositionBeforeScroll will be previous value.
mPositionBeforeScroll = getChildLayoutPosition(mCurView);
mHasCalledOnPageChanged = false;
}
if (DEBUG) {
Log.d("@", "mPositionBeforeScroll:" + mPositionBeforeScroll);
}
mFisrtLeftWhenDragging = mCurView.getLeft();
mFirstTopWhenDragging = mCurView.getTop();
} else {
mPositionBeforeScroll = -1;
}
mTouchSpan = 0;
} else if (state == SCROLL_STATE_SETTLING) {
mNeedAdjust = false;
if (mCurView != null) {
if (getLayoutManager().canScrollHorizontally()) {
mTouchSpan = mCurView.getLeft() - mFisrtLeftWhenDragging;
} else {
mTouchSpan = mCurView.getTop() - mFirstTopWhenDragging;
}
} else {
mTouchSpan = 0;
}
mCurView = null;
} else if (state == SCROLL_STATE_IDLE) {
if (mNeedAdjust) {
int targetPosition = getLayoutManager().canScrollHorizontally() ? RecycleViewPagerUtils.getCenterXChildPosition(this) :
RecycleViewPagerUtils.getCenterYChildPosition(this);
if (mCurView != null) {
targetPosition = getChildAdapterPosition(mCurView);
if (getLayoutManager().canScrollHorizontally()) {
int spanX = mCurView.getLeft() - mFisrtLeftWhenDragging;
// if user is tending to cancel paging action, don't perform position changing
if (spanX > mCurView.getWidth() * mTriggerOffset && mCurView.getLeft() >= mMaxLeftWhenDragging) {
if (!reverseLayout) targetPosition--;
else targetPosition++;
} else if (spanX < mCurView.getWidth() * -mTriggerOffset && mCurView.getLeft() <= mMinLeftWhenDragging) {
if (!reverseLayout) targetPosition++;
else targetPosition--;
}
} else {
int spanY = mCurView.getTop() - mFirstTopWhenDragging;
if (spanY > mCurView.getHeight() * mTriggerOffset && mCurView.getTop() >= mMaxTopWhenDragging) {
if (!reverseLayout) targetPosition--;
else targetPosition++;
} else if (spanY < mCurView.getHeight() * -mTriggerOffset && mCurView.getTop() <= mMinTopWhenDragging) {
if (!reverseLayout) targetPosition++;
else targetPosition--;
}
}
}
smoothScrollToPosition(safeTargetPosition(targetPosition, getItemCount()));
mCurView = null;
} else if (mSmoothScrollTargetPosition != mPositionBeforeScroll) {
if (DEBUG) {
Log.d("@", "onPageChanged:" + mSmoothScrollTargetPosition);
}
mPositionBeforeScroll = mSmoothScrollTargetPosition;
}
// reset
mMaxLeftWhenDragging = Integer.MIN_VALUE;
mMinLeftWhenDragging = Integer.MAX_VALUE;
mMaxTopWhenDragging = Integer.MIN_VALUE;
mMinTopWhenDragging = Integer.MAX_VALUE;
}
}

@SuppressWarnings("unchecked")
@NonNull
protected RecyclerViewPagerAdapter ensureRecyclerViewPagerAdapter(Adapter adapter) {
return (adapter instanceof RecyclerViewPagerAdapter)
? (RecyclerViewPagerAdapter) adapter
: new RecyclerViewPagerAdapter(this, adapter);

}

private int getFlingCount(int velocity, int cellSize) {
if (velocity == 0) {
return 0;
}
int sign = velocity > 0 ? 1 : -1;
return (int) (sign * Math.ceil((velocity * sign * mFlingFactor / cellSize)
- mTriggerOffset));
}

private int safeTargetPosition(int position, int count) {
if (position < 0) {
return 0;
}
if (position >= count) {
return count - 1;
}
return position;
}

public interface OnPageChangedListener {
/**
* Fires when viewpager changes it's page
* @param oldPosition old position
* @param newPosition new position
*/
void OnPageChanged(int oldPosition, int newPosition);
}

public float getlLastY() {
return mLastY;
}
}

2.xml文件调用:

<你的包名.calender.activity.RecyclerViewPager
android:id="@+id/calender_pager"
android:layout_marginTop="10dp"
android:layout_marginBottom="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="50dp"
android:paddingRight="50dp"
android:paddingStart="40dp"
android:paddingEnd="40dp"
app:rvp_triggerOffset="0.1"
app:rvp_singlePageFling="false"
android:clipToPadding="false"/>
3.代码调用:
RecyclerViewPager calenderPager= (RecyclerViewPager) head.findViewById(R.id.calender_pager);


LinearLayoutManager layout = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL,
false);
calenderPager.setLayoutManager(layout);
pagerAdapter = new LayoutAdapter(this,calenderDataList);
calenderPager.setAdapter(pagerAdapter);
calenderPager.setHasFixedSize(true);
calenderPager.setLongClickable(true);
calenderPager.setSinglePageFling(false);
calenderPager.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int scrollState) {
// updateState(scrollState);
}

@Override
public void onScrolled(RecyclerView recyclerView, int i, int i2) {
int childCount = calenderPager.getChildCount();
int width = calenderPager.getChildAt(0).getWidth();
int padding = (calenderPager.getWidth() - width) / 2;
for (int j = 0; j < childCount; j++) {
View v = recyclerView.getChildAt(j);
//往左 从 padding 到 -(v.getWidth()-padding) 的过程中,由大到小
float rate = 0;
;
if (v.getLeft() <= padding) {
if (v.getLeft() >= padding - v.getWidth()) {
rate = (padding - v.getLeft()) * 1f / v.getWidth();
} else {
rate = 1;
}
v.setScaleY(1 - rate * 0.1f);
v.setScaleX(1 - rate * 0.1f);

} else {
//往右 从 padding 到 recyclerView.getWidth()-padding 的过程中,由大到小
if (v.getLeft() <= recyclerView.getWidth() - padding) {
rate = (recyclerView.getWidth() - padding - v.getLeft()) * 1f / v.getWidth();
}
v.setScaleY(0.9f + rate * 0.1f);
v.setScaleX(0.9f + rate * 0.1f);
}
}
}
});
calenderPager.addOnPageChangedListener(new RecyclerViewPager.OnPageChangedListener() {
@Override
public void OnPageChanged(int oldPosition, int newPosition) {
if (currentMonth==newPosition){//第一次进入,
return;
}
if (oldPosition==newPosition){//没有滑动出当前item
return;
}
currentMonth=newPosition;
//刷新绑定状态
updatMarkerButton();
//刷新事件列表
//旧数据清除
List list= adapter.getData();
if (list.size()>0) {
for (int i = 0; i < calenderDataList.get(oldPosition).getData().size(); i++) {
adapter.notifyItemRemoved(i+1);
}
list.clear();
adapter.notifyItemRangeRemoved(1, calenderDataList.get(oldPosition).getData().size() - 2);
}

//新数据插入
List<CalenderDayBean> newList=calenderDataList.get(newPosition).getData();
for (int i = 0; i < newList.size(); i++) {
dayList.add(newList.get(i));
adapter.notifyItemInserted(1);
adapter.notifyItemRangeChanged(1, newList.size()-2);
}

}
});

calenderPager.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
if (calenderPager.getChildCount() < 3) {
if (calenderPager.getChildAt(1) != null) {
if (calenderPager.getCurrentPosition() == 0) {
View v1 = calenderPager.getChildAt(1);
v1.setScaleY(0.9f);
v1.setScaleX(0.9f);
} else {
View v1 = calenderPager.getChildAt(0);
v1.setScaleY(0.9f);
v1.setScaleX(0.9f);
}
}
} else {
if (calenderPager.getChildAt(0) != null) {
View v0 = calenderPager.getChildAt(0);
v0.setScaleY(0.9f);
v0.setScaleX(0.9f);
}
if (calenderPager.getChildAt(2) != null) {
View v2 = calenderPager.getChildAt(2);
v2.setScaleY(0.9f);
v2.setScaleX(0.9f);
}
}

}
});

calenderPager.scrollToPosition(currentMonth);
}

实现ViewPager一次滑动多页(保持居中)的更多相关文章

  1. Android Viewpager+Fragment实现滑动标签页

    ViewPager 结合Fragment实现一个Activity里包含多个可滑动的标签页,每个标签页可以有独立的布局及响应. 主页布局 <?xml version="1.0" ...

  2. ViewPager + Fragment实现滑动标签页

    http://blog.csdn.net/lizhenmingdirk/article/details/13631813; tab与frg的区别: http://www.cnblogs.com/tia ...

  3. 【解决ViewPager在大屏上滑动不流畅】 设置ViewPager滑动翻页距离

    在项目中做了一个ViewPager+Fragment滑动翻页的效果,在模拟器和小米手机上测试也比较正常.但是换到4.7以上屏幕测试的时候发现老是滑动失效. 因为系统默认的滑动策略是当用户滑动超过半屏之 ...

  4. ViewPagerWithImageDemo【ViewPager如何判断滑动到第一页和最后一页以及弹出对话框功能】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 记录viewpager滑动的时候弹出对话框的功能(关键功能是滑动弹出对话框后,隐藏对话框的时候当前页可以还原到原位置),顺便判断首页 ...

  5. ViewPager实现滑动翻页效果

    实现ViewPager的滑动翻页效果可以使用ViewPager的setPageTransformer方法,如下: import android.content.Context; import andr ...

  6. 使用自定义RadioButton和ViewPager实现TabHost效果和带滑动的页卡效果

    在工作中又很多需求都不是android系统自带的控件可以达到效果的,内置的TabHost就是,只能达到简单的效果 ,所以这个时候就要自定义控件来达到效果:这个效果就是: 使用自定义RadioButto ...

  7. ViewPager 可左右滑动和缩放的图片浏览

    最近因为要做一个项目,需要使用到图片的浏览.我就自己在网上找了些资料,然后加以修改整理后出来一个demo,希望可以帮助到需要的人.同时这也是我第一个技术博客. 在做之前首先需要了解一下什么是ViewP ...

  8. Android 中 DrawerLayout + ViewPager 怎么解决滑动冲突?

    DrawerLayout 是 Android 官方的侧滑菜单控件,而 ViewPager 相信大家都很熟悉了.今天这里就讲一下当在 DrawerLayout 中嵌套 ViewPager 时,要如何解决 ...

  9. Gallery滑动一页(一个Item)效果

    本文主要介绍如何使用Gallery只滑动一页以及其实现原理. Demo APK 可以方便的查看效果,在各大应用商店搜索 trinea android 下载即可,如:Google Play. 可运行代码 ...

  10. ViewPager取消左右滑动切换功能

    ViewPager取消左右滑动切换功能 最近做项目要求某种情况下ViewPager不能滑动,那么我们只需要重写这个方法就可以禁止ViewPager滑动 IndexViewPager.java: imp ...

随机推荐

  1. 在github上如何克隆带子模块的项目?

    使用命令git clone --recursive xxxx(项目地址).

  2. windows10 远程桌面黑屏

    [计算机配置]-[管理模板]-[Windows组件]-[远程桌面服务]-[远程桌面会话主机]-[远程会话环境]-{为远程桌面连接使用WDDM图形显示驱动程序-设置禁用}

  3. Socket:由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作

    https://blog.csdn.net/weixin_45932157/article/details/113999801 最近服务器的Socket代理软件经常报这个错误:log:Error On ...

  4. Note Taking App Comparison: Notesnook vs Joplin

    I have used many note-taking apps, including Notion, oneNotes, Obsidian, Sublime Text, etc. Here I w ...

  5. python判断文件后缀名

    endswith()方法 利用文件名或路径名对文件后缀进行判断,例如对文件名后缀是否为.jpg的文件进行判断. path = "file.jpg" bool = path.ends ...

  6. Go指南:方法和接口

    方法与指针重定向 带指针参数的函数必须接受一个指针: func ScaleFunc(v *Vertex, f float64) { v.X = v.X * f v.Y = v.Y * f} 以指针为接 ...

  7. 使用Java API操作Neo4j

    使用IntelliJ IDEA (Jet Brains) 创建java工程 把下载好的neo4j包中的lib文件下的所有jar文件复制到工程Neo4j_Project的lib文件夹下(若无lib文件夹 ...

  8. PHP中的超级变量

    超级变量,又名超级全局变量,是PHP内置的变量,这些变量在代码的任意位置都能正常使用 PHP中的超级变量 9种超级变量 $GLOBALS $_SERVER 9种超级变量 目前,PHP提供了9种超级变量 ...

  9. HttpClient线程池&重试机制

    HttpClientUtils package com.example.http_thread.util; import org.apache.http.HttpEntityEnclosingRequ ...

  10. Ansible 实记

    自动化运维工具 Ansible ansible是基于模块工作的,本身没有批量部署的能力.真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架.主要包括: (1).连接插件co ...