您的位置:首页 > 移动开发 > Android开发

自定义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

      
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息