自定义View-轮播图
2018-03-29 20:49
281 查看
一.自动循环滚动的实现 要图片一直滚动,那么可以在原有的图片数量上加2,例如有三张图片,可在adapter的getCount中数量加2,变成有5张图片,那么当滑到第0页时,其实是滑到最后一张图片,在滑到第4页时,是滑到第一张图片,至于返回图片数组的正确位置则通过一个运算((当前位置-1)%图片数量),如果是第0个位置就返回(图片数量-1)。
二.自定义view其中用到的指示点dian.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="true"> <shape android:shape="oval"> <solid android:color="@color/colorAccent" /> <size android:height="5dp" /> <size android:width="5dp" /> </shape> </item> <item android:state_enabled="false"> <shape android:shape="oval"> <solid android:color="#ffffff" /> <size android:width="5dp" /> <size android:height="5dp" /> </shape> </item> </selector>在这里可以设置自己想要的圆点颜色和背景色
三.自定义属性的实现和获取
<!--Carousel的自定义属性--> <declare-styleable name="Carousel"> <attr name="points_visibility" format="boolean" /> <attr name="points_position" format="enum"> <enum name="left" value="0" /> <enum name="center" value="1" /> <enum name="right" value="2" /> </attr> <attr name="points_background" format="reference|color" /> </declare-styleable>
private void init(Context context, AttributeSet attrs) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.Carousel); mPointsPosition = typedArray.getInt(R.styleable.Carousel_points_position, CENTER); mPointsVisible = typedArray.getBoolean(R.styleable.Carousel_points_visibility, true); mPointsBackground = typedArray.getDrawable(R.styleable.Carousel_points_background); typedArray.recycle();//资源回收 setLayout(context);//设置布局控件 }用完typeArrary记得调用回收,因为他是用了单例模式,以便在其他地方复用。
四.画指示点和当滚到某一页时指示点改亮的位置
private void addPoints() { LayoutParams layoutParams = new LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(5, 5, 5, 5); pointsLinearLayout.removeAllViews(); int size = isUrlImage ? urlImages.size() : localImages.size(); for (int i = 0; i < size; i++) { ImageView imageView = new ImageView(getContext()); imageView.setImageResource(dian); imageView.setLayoutParams(layoutParams); pointsLinearLayout.addView(imageView);//把点加进布局中 } switchPoints(0); }
private void switchPoints(int position) { for (int i = 0; i < pointsLinearLayout.getChildCount(); i++) {//先把指示点颜色去掉 pointsLinearLayout.getChildAt(i).setEnabled(false); } pointsLinearLayout.getChildAt(position).setEnabled(true); }五.viewpager的adapter实现
private class CarouselAdapter extends PagerAdapter { @Override public int getCount() { if (isUrlImage) { return urlImages.size() + 2; } else { return localImages.size() + 2; } } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, final int position) { ImageView imageView = new ImageView(getContext()); imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);//设置图片样式 imageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (onImageClickListaner != null) { onImageClickListaner.onImageClick(getPosition(position)); } } }); if (isUrlImage) { Glide.with(getContext()).load(urlImages.get(getPosition(position))).into(imageView); } else { imageView.setImageResource(localImages.get(getPosition(position))); } container.addView(imageView);//把imageview放进容器 return imageView; } @Override public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { container.removeView((View) object); } }这里的PagerAdapter要重写四个方法,其中第三个方法是在adapter容器中加入图片ImageView,在加载网络图片时我用Glide这个图片框架加载,在最后别忘了container.addView(imageview)把ImageView加进去。
至于这个PagerAdapter他会预加载相邻的页面,当滑到某一页面时,不相邻的页面会调用第四个重写方法销毁之前加载的页面。
六.在滑动viewpager时的监听类
private ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { //正在滑动时调用 } @Override public void onPageSelected(int position) { //滑动结束后调用 currentPosition = position; switchPoints(getPosition(position)); } @Override public void onPageScrollStateChanged(int state) { //滑动时状态的监听 state=0什么也没做 1正在滑动 2滑动完毕 if (state == ViewPager.SCROLL_STATE_IDLE) { int current = viewPager.getCurrentItem(); int lastPage = carouselAdapter.getCount() - 1;//adapter多加两页后的最后一页 if (current == 0) { viewPager.setCurrentItem(lastPage - 1, false);//false表示立即滑到页面,true表示平滑到页面 } else if (current == lastPage) { viewPager.setCurrentItem(1, false); } } } };七.在开头写到的根据滑到某一页时要返回的对应图片数组中位置方法(getPosition())
private int getPosition(int position) { int truePosition; if (isUrlImage) { truePosition = (position - 1) % urlImages.size(); if (truePosition < 0) { truePosition = truePosition + urlImages.size(); } } else { truePosition = (position - 1) % localImages.size(); if (truePosition < 0) { truePosition = truePosition + localImages.size(); } } return truePosition; }所有的要点差不多都贴上了,源码地址在我的github:https://github.com/JyingLee/MyCarousel
相关文章推荐
- CycleRotationView:自定义控件之轮播图
- EasySwift/YXJCycleView 任意视图的无限循环轮播图,可以是本地图片,可以是任意的view,可以是远程图片,再加文字描述岂不更好,pageController也支持高度自定义。
- Android开发之ViewPager实现轮播图(轮播广告)效果的自定义View
- ViewPager自动轮播,自定义小圆点的改变
- 自定义ViewGroup实现循环轮播ViewPager
- 自定义view轮播
- Android开发之ViewPager实现轮播图(轮播广告)效果的自定义View
- 安卓实现汉字轮播(自定义view)
- 自定义ViewPager轮播,设置切换过渡时间
- Android自定义View使用canvas实现轮播图效果
- 自定义view实现无限轮播
- 自定义ViewPager实现轮播效果
- 手把手教你用ViewPager自定义实现Banner轮播
- 自定义view实现轮播图效果一
- Android开发之ViewPager实现轮播图(轮播广告)效果的自定义View
- 自定义view 自动轮播图+GridView
- android 自定义轮播banner,包括手动轮播 CycleViewPager
- 仿百度壁纸客户端(二)——主页自定义ViewPager广告定时轮播图
- 自定义广告轮播控件(基于ViewPager),带指示器,一键引用
- [置顶] 自定义View 轮播