Android中使用ViewPager实现一屏多页面的功能
来源:互联网 发布:网店美工培训 编辑:程序博客网 时间:2024/05/22 01:28
效果图【录制后使用扣扣秀视频制作的gif,看见水印请别见怪】:
实现的主要注意点【关于view pager的使用就忽略了】
1、
Adapter需要重写函数——
@Override
public float getPageWidth(int position);
2、clipChildren属性的使用—-决定了一屏三页还是一屏两页,三页的就比如爱奇艺的横向滑动的左右两边有相互接壤的页面一部分,两页的就是效果图展示。
当前页所占屏幕宽度,不可以设置ViewPager属性clipToPadding=”false”
* 或者clipChildren=”false”,否则不起作用,设置clipToPadding=”false”同一屏幕将会出现三个页,true时仅有一个页。
3、
ShadowTransformer的使用。
下面上做过简要封装后的代码(代码中因为需要有三个部分的页面样式,故而有做过一个分组,具体可见Adapter抽象基类):
1) 定义接口:
public interface ICardViewPagerAdapter { /* 用于计算阴影 */ int MAX_ELEVATION_FACTOR = 8; /* CardView阴影 */ float getBaseElevation(); View getCardViewAt(int position); int getCount(); /** 是否使用阴影效果【主要针对CardView言】 false: app:cardElevation="0px" //阴影大小 app:cardMaxElevation="2px"//最大阴影大小,该值最小2px app:cardUseCompatPadding="false"//不显示阴影 app:contentPaddingBottom="-20dp" app:contentPaddingTop="-20dp" */ boolean elevatieUsable();}
2) Adapter基类实现
public abstract class CardPagerAdapter<T> extends PagerAdapter implements ICardViewPagerAdapter { private List<View> mViews; /** * 数据源 */ private List<T> mResourceData; private float mBaseElevation; protected boolean isUsableEleVation = true; protected TypeInflateView mTypeInflateView; /** * 子控件-亨元. */ private SparseArray<View> viewWidgets = new SparseArray<>(); /** * 缓存-避免多次新建对象 */ private SparseArray<View> rootViews = new SparseArray<>(); public boolean isUsableEleVation() { return isUsableEleVation; } public void setUsableEleVation(boolean usableEleVation) { isUsableEleVation = usableEleVation; } public CardPagerAdapter() { mResourceData = new ArrayList<>(); mViews = new ArrayList<>(); } public void addCardItem(T item) { mViews.add(null); mResourceData.add(item); } public void addAllCardItem(List<T> allData){ mResourceData.addAll(allData); int i = 0; while (i < allData.size()){ mViews.add(null); i++; } } public View findWidgetViewById(View view , int resId){ View viewWidget = viewWidgets.get(resId); if (viewWidget == null){ viewWidget = view.findViewById(resId); viewWidgets.put(resId, viewWidget); } return viewWidget; } public float getBaseElevation() { return mBaseElevation; } public enum TypeInflateView{ FirstPageType, CenterPageType, LastPageType } /** * 当前页所占屏幕宽度,不可以设置ViewPager属性clipToPadding="false" * 或者clipChildren="false",否则不起作用,设置clipToPadding="false"同一屏幕将会出现三个页,true时仅有一个页。 * @param position * @return */ @Override public float getPageWidth(int position) { return (float) 0.63; } @Override public View getCardViewAt(int position) { return mViews.get(position); } @Override public int getCount() { return mResourceData.size(); } @Override public boolean elevatieUsable() { return isUsableEleVation(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { View view = rootViews.get(position); if (view == null) { if (position == 0) { mTypeInflateView = TypeInflateView.FirstPageType; view = LayoutInflater.from(container.getContext()) .inflate(onObtainLayoutR(mTypeInflateView, position), container, false); } else if (getCount() - 1 == position) { mTypeInflateView = TypeInflateView.LastPageType; view = LayoutInflater.from(container.getContext()) .inflate(onObtainLayoutR(mTypeInflateView, position), container, false); } else { mTypeInflateView = TypeInflateView.CenterPageType; view = LayoutInflater.from(container.getContext()) .inflate(onObtainLayoutR(mTypeInflateView, position), container, false); } rootViews.put(position, view); } container.addView(view); bind(position, view); View cardView = view.findViewById(onObtainCardViewRAtLayout()); if (mBaseElevation==0 && cardView!=null && cardView instanceof CardView) { mBaseElevation = ((CardView)cardView).getCardElevation(); ((CardView)cardView).setMaxCardElevation(mBaseElevation * MAX_ELEVATION_FACTOR); } if (mViews.get(position) == null) { if (cardView != null) mViews.set(position, cardView); else mViews.set(position, view); } return view; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); mViews.set(position, null); } public View getRootView(int realPosition){ return rootViews.get(realPosition); } /** * 此方法用于绑定数据到控件上面,以及设置事件监听等. * @param position * @param view */ public abstract void bind(int position, View view) ; /** * 此方法返回一个布局xml的id,eg:R.layout. * @return */ protected abstract int onObtainLayoutR(TypeInflateView mTypeInflateView, int position); /** * 此方法用于获取CardView,必须在onObtainLayoutR()的layout中定义过CardView的id * @return */ protected abstract int onObtainCardViewRAtLayout();}
3)ShadowTransformer的实现类:
public class ShadowTransformer implements ViewPager.OnPageChangeListener, ViewPager.PageTransformer { private ViewPager mViewPager; private ICardViewPagerAdapter mAdapter; private float mLastOffset; private boolean mScalingEnabled; // 是否使用缩放效果,默认使用 private OnViewPageChangedListener mOnViewPageChangedListener; public void setOnViewPageChangedListener(OnViewPageChangedListener zOnViewPageChangedListener){ this.mOnViewPageChangedListener = zOnViewPageChangedListener; } public ShadowTransformer(ViewPager viewPager, ICardViewPagerAdapter adapter) { mViewPager = viewPager; mViewPager.addOnPageChangeListener(this); mAdapter = adapter; } public void enableScaling(boolean enable) { if (mScalingEnabled && !enable) { // shrink main card View currentCard = mAdapter.getCardViewAt(mViewPager.getCurrentItem()); if (currentCard != null) { currentCard.animate().scaleY(1); currentCard.animate().scaleX(1); } }else if(!mScalingEnabled && enable){ // grow main card View currentCard = mAdapter.getCardViewAt(mViewPager.getCurrentItem()); if (currentCard != null) { currentCard.animate().scaleY(1.1f); currentCard.animate().scaleX(1.1f); } } mScalingEnabled = enable; } @Override public void transformPage(View page, float position) { } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { int realCurrentPosition; int nextPosition; float baseElevation = mAdapter.getBaseElevation(); float realOffset; boolean goingLeft = mLastOffset > positionOffset; // If we're going backwards, onPageScrolled receives the last position // instead of the current one if (goingLeft) { realCurrentPosition = position + 1; nextPosition = position; realOffset = 1 - positionOffset; } else { nextPosition = position + 1; realCurrentPosition = position; realOffset = positionOffset; } // Avoid crash on overscroll if (nextPosition > mAdapter.getCount() - 1 || realCurrentPosition > mAdapter.getCount() - 1) { return; }// ((CardPagerAdapter)mAdapter).bind(realCurrentPosition,// ((CardPagerAdapter)mAdapter).getRootView(realCurrentPosition));// ((CardPagerAdapter)mAdapter).bind(nextPosition,// ((CardPagerAdapter)mAdapter).getRootView(nextPosition)); View currentCard = mAdapter.getCardViewAt(realCurrentPosition); // This might be null if a fragment is being used // and the views weren't created yet if (currentCard != null) { if (mScalingEnabled) { currentCard.setScaleX((float) (1 + 0.1 * (1 - realOffset))); currentCard.setScaleY((float) (1 + 0.1 * (1 - realOffset))); } if (currentCard instanceof CardView) { if (mAdapter.elevatieUsable()) { ((CardView)currentCard).setCardElevation((baseElevation + baseElevation * (ICardViewPagerAdapter.MAX_ELEVATION_FACTOR - 1) * (1 - realOffset))); } else { ((CardView)currentCard).setCardElevation(0.0f); } } } View nextCard = mAdapter.getCardViewAt(nextPosition); // We might be scrolling fast enough so that the next (or previous) card // was already destroyed or a fragment might not have been created yet if (nextCard != null) { if (mScalingEnabled) { nextCard.setScaleX((float) (1 + 0.1 * (realOffset))); nextCard.setScaleY((float) (1 + 0.1 * (realOffset))); } if (currentCard instanceof CardView) { if (mAdapter.elevatieUsable()) { ((CardView)nextCard).setCardElevation((baseElevation + baseElevation * (ICardViewPagerAdapter.MAX_ELEVATION_FACTOR - 1) * (realOffset))); } else { ((CardView)currentCard).setCardElevation(0.0f); } } } mLastOffset = positionOffset; if (mOnViewPageChangedListener != null) mOnViewPageChangedListener.onPageScrolled(position, positionOffset, positionOffsetPixels); } @Override public void onPageSelected(int position) { if (mOnViewPageChangedListener != null){ mOnViewPageChangedListener.onPageSelected(position); } } @Override public void onPageScrollStateChanged(int state) { if (mOnViewPageChangedListener != null){ mOnViewPageChangedListener.onPageScrollStateChanged(state); } } public interface OnViewPageChangedListener{ void onPageSelected(int position); void onPageScrollStateChanged(int state); void onPageScrolled(int position, float positionOffset, int positionOffsetPixels); }}
使用例子eg:
mCardActShopAdapter = new CardActShopAdapter(); mCardActShopAdapter.addCardItem(""); mCardActShopAdapter.addCardItem(""); mCardActShopAdapter.addCardItem(""); mCardActShopAdapter.addCardItem(""); mCardActShopAdapter.addCardItem(""); mCardShadowTransformer = new ShadowTransformer(viewPager, mCardActShopAdapter); /** * 是否启用滑动动画 */ mCardShadowTransformer.enableScaling(true); viewPager.setPageTransformer(false, mCardShadowTransformer); /** * 页面之间的间距 */ viewPager.setPageMargin(getResources().getDimensionPixelOffset(R.dimen.dp_35)); //viewPager.setAllowSlidingToLastPosition(true); viewPager.setOffscreenPageLimit(3); viewPager.setAdapter(mCardActShopAdapter);
CardActShopAdapter是抽象基类的子类.根据需求自行进行扩展:
上一个简单例子:
public class CardActShopAdapter extends CardPagerAdapter { public SparseArray<ViewHolder> mCenterViewHolder = new SparseArray<>(); private void bindDataForFirstView(View varView){ TextView tvTitleActivityCard = (TextView) findWidgetViewById(varView, R.id.tv_title_activity_card); TextView tvDescActivityCard = (TextView) findWidgetViewById(varView, R.id.tv_desc_activity_card); RelativeLayout rlBuyCare = (RelativeLayout) findWidgetViewById(varView, R.id.rl_buy_care); tvDescActivityCard.setMovementMethod(ScrollingMovementMethod.getInstance()); rlBuyCare.setOnClickListener(new OnForbidDoubleClick() { @Override public void onClickSuccess(View varView) { final ShoppingIntroductionDialog mShoppingIntroductionDialog = new ShoppingIntroductionDialog .IntroductionBuilder(CardActShopActivity.this) .create() .showDialog(); mShoppingIntroductionDialog.findWidgetByResId(R.id.btn_back_page) .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mShoppingIntroductionDialog.isShowing()){ mShoppingIntroductionDialog.dismiss(); } } }); } @Override public void onClickForbid(View varView) { } }); } private void bindDataForCenterView(int position, View varView){ if (mCenterViewHolder.get(position) == null) { ViewHolder viewHolder = new ViewHolder(); viewHolder.ivActivityCardHeader = (ImageView) findWidgetViewById(varView, R.id.iv_activity_card_header); viewHolder.tvTitleActivityCard = (TextView) findWidgetViewById(varView, R.id.tv_title_activity_card); viewHolder.tvDescActivityCard = (TextView) findWidgetViewById(varView, R.id.tv_desc_activity_card); viewHolder.rlBuyCare = (TextView) findWidgetViewById(varView, R.id.tv_right_now_buy); viewHolder.rlBuyCare.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ToastUtils.showLong("立即购买"); } }); mCenterViewHolder.put(position, viewHolder); } } private void bindDataForLastView(View varView){ TextView tvRightNowCall = (TextView) findWidgetViewById(varView, R.id.tv_right_now_call); tvRightNowCall.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ToastUtils.showLong("客服电话:0871-xxx-xXXX"); } }); } @Override public void bind(int position, View view) { if (position == 0){ bindDataForFirstView(view); } else if (position == getCount()-1){ bindDataForLastView(view); } else { bindDataForCenterView(position, view); } } @Override protected int onObtainLayoutR(TypeInflateView mTypeInflateView, int position) { if (mTypeInflateView == TypeInflateView.FirstPageType){ return R.layout.pager_act_first; } else if (mTypeInflateView == TypeInflateView.LastPageType){ return R.layout.pager_act_last; } else { return R.layout.pager_act_center; } } @Override protected int onObtainCardViewRAtLayout() { return 0; } }
阅读全文
0 0
- Android中使用ViewPager实现一屏多页面的功能
- Android中使用ViewPager和PagerTabStrip实现页面滑动效果
- Android中使用ViewPager和PagerTabStrip实现页面滑动效果
- 在Android中使用ViewPager实现左右滑动页面
- android之ViewPager的使用实现应用的导航功能
- Android 实现ViewPager中页面的手动切换
- Android 滑动页面的实现,ViewPager使用详解
- Android中点击ViewPager实现跳转页面
- android中使用viewpager延迟加载页面
- Android LRecyclerView实现类似viewpager的功能
- Android中使用ViewPager实现屏幕页面切换和引导页效果实现
- ViewPager的详解(使用viewPager实现导航页面)
- Android中ViewPager的使用
- Android中ViewPager的使用
- Android中使用ViewPager实现图片的切换
- Android 中使用ViewPager实现画廊效果
- android中使用ViewPager实现无限轮播图
- Android学习笔记(二)--ViewPager的使用(轮播功能的实现)
- Visual Studio 2010/2013/2015 UTF8编码调试时显示中文
- PHP报错:遇到Can't use method return value in write context
- 剑指offer面试题目:不用加减乘除做加法
- 接口和抽象类有什么区别
- Lambda表达式
- Android中使用ViewPager实现一屏多页面的功能
- collectgarbage
- 智能停车正成为智能交通中的主要应用场景
- Android Asset Studio的使用(图标在线生成工具)
- npm添加淘宝镜像
- 深入理解Java的接口和抽象类
- requests模块的安装与应用
- java 接口
- 解决Mac上adb: command not found问题