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

参考文献:  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. 一些关于STL的笔记

    c++ std中set与unordered_set区别及map与unordered_map区别: map/set基于红黑树实现,红黑树具有自动排序的功能,因此map/set内部所有的数据,在任何时候, ...

  2. Python 常用小例子

    作者原文 https://mp.weixin.qq.com/s/eFYDW20YPynjsW_jcp-QWw 内置函数(63个) 1 abs() 绝对值或复数的模 In [1]: abs(-6) Ou ...

  3. Win10中找回曾复制过的东西

    按Win+V,如果弹出的"剪贴板历史"设置已经打开,那么就可以找回.建议大家打开这项设置以防万一.

  4. 新的学习历程-python1 Hello World

    1 print('hello world!') 2 if 2 > 0: 3 print('ok') 4 print('yes') 5 6 x = 3; y = 4 7 print(x + y) ...

  5. 一次eureka的事故

    本地起了一个微服务(不知道怎么起的),导致注册到微服务上了,不知所措.. 想了下,杀死对应微服务的进程id就可以了(记不住啊!!)

  6. Mac下MySQL下载及安装

    ​ 1在浏览器当中输入地址: https://downloads.mysql.com/archives/community/​ 1. 1.1,选择mysql版本,它会自动对应某个版本macOS,1.2 ...

  7. iOS开发之将GIF存储本地相册

    #import <AssetsLibrary/AssetsLibrary.h> 1.引用库 2.将GIF图片转为NSData类型 3.存储代码 ALAssetsLibrary *libra ...

  8. 【Linux】ArchLinux 使用之旅

    主要参考以下两个链接进行,安装系统和安装桌面环境. 以官方Wiki的方式安装ArchLinux | viseator's blog ArchLinux安装后的必须配置与图形界面安装教程 | visea ...

  9. js 加密和解密

    // aes对称加密 const CryptoJS = require('crypto-js'); //引用AES源码js const key = CryptoJS.enc.Utf8.parse(&q ...

  10. MobaXterm汉化版教程

    MobaXterm中文版是一款非常好用的远程连接.远程控制软件,它堪称全能终端神器,支持非常多的远程协议 ,如SSH,Telnet,Rsh,Xdmc,RDP,VNC,FTP,SFTP,串口(Seria ...