Android自定义View 实现图片轮播

第一次写博客 大家多多交流

最近项目需要图片论播,本来可以使用ViewPager实现 但是ViewPager没有循环播放的效果,而且日后项目当中还会有很大的机会用到这样的功能,自己造一下轮子,对自己的锻炼也有好处,所以自己实现了一个。对于代码当中的问题,欢迎大家指出

效果

device-2016-04-11-192359.gif

源码


源码上传到了github 欢迎大家在github上和我交流 地址
使用方法 直接把library 当中的ImageSwitch 放进你的项目当中就可以了

关键代码展示:

//layout child view
// 这里使用了3个子view 来展示内容,其中第二个子view放置在中间,作为正在显示的内容.
//第1和第3的子view 分别表示正在显示的子view 的左边 右边第一个.
@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

super.onLayout(changed, l, t, r, b);

System.out.println("l "+l+" r "+r);

ViewGroup parent= (ViewGroup) getParent();

this.l=0+getPaddingLeft();

this.t=0+getPaddingTop();

this.r=r-l-getPaddingRight();

this.b=b-getPaddingBottom();

int ll=this.l;

width=this.r-this.l;

for(int i=0;i

子view 之间的切换处理

主要有三个步骤
1.计算子view的移动距离
2.使用属性动画(不同与补间动画,这里可以实际上的改变对象的属性)对view进行移动处理
3.移动完成(等同于动画完成)之后,更新当前的位置,绑定下一个位置的数据

//这里是向左移动子view
private void changeToNext(){

if(isAnimation ||isTouching){

return;

}

isAnimation =true;

//计算第二个view 需要移动的距离
int translation0=childs[1].getRight();
//计算第三个view 需要移动的距离
int translation1=childs[2].getLeft()-childs[1].getLeft();

// System.out.println(childs[1].hashCode()+": left "+childs[1].getLeft()+" right "+childs[1].getRight()+" tx "+childs[1].getTranslationX());

// System.out.println(childs[2].hashCode()+": left "+childs[2].getLeft()+" right "+childs[2].getRight()+" tx "+childs[2].getTranslationX());

// System.out.println("================== before =======================");
//使用属性动画对子view 进行切换
PropertyValuesHolder translationHolder=PropertyValuesHolder.ofFloat("translationX",-translation0);

PropertyValuesHolder alphaHolder=PropertyValuesHolder.ofFloat("alpha",0.6f);

ObjectAnimator dismissAnimator=ObjectAnimator.ofPropertyValuesHolder(childs[1],translationHolder,alphaHolder);

dismissAnimator.setDuration(animationDuration).start();

ObjectAnimator occurAnimator=ObjectAnimator.ofFloat(childs[2],"translationX",-translation1);

occurAnimator.setDuration(animationDuration);

occurAnimator.addListener(new Animator.AnimatorListener() {

@Override

public void onAnimationStart(Animator animation) {

}

@Override

public void onAnimationEnd(Animator animation) {

// System.out.println("*************** after *************");

// System.out.println(childs[1].hashCode()+": left "+childs[1].getLeft()+" right "+childs[1].getRight()+" tx "+childs[1].getTranslationX());

// System.out.println(childs[2].hashCode()+": left "+childs[2].getLeft()+" right "+childs[2].getRight()+" tx "+childs[2].getTranslationX());

// System.out.println("$$$$$$$$$$$$$$$$ after $$$$$$$$$$$$$$");

reLayoutRight();

++curentPosition;

curentPosition=curentPosition% adapter.getCount();

adapter.onItemChanged(curentPosition);

int np=(curentPosition+1)% adapter.getCount();

adapter.bindData(childs[2],np);

// np=curentPosition-1;

// np=np<0? adapter.getCount()-1:np;

// adapter.bindData(childs[0],np);

isAnimation =false;

}

@Override

public void onAnimationCancel(Animator animation) {

}

@Override

public void onAnimationRepeat(Animator animation) {

}

});

occurAnimator.start();

}

向右移动的原理和向左移动的原理相同,这里就不详述了,具体可以刀github 上看我详细的代码

Adapter 的设计

public interface Adapter {

/*

 * use to create the item

 * return : return the item it created

 * */

View createItem();

/*

 * bindData for the view

 * @param

 * view :target

 * position: position of the view

 * */

void bindData(View view, int position);

/*

 * get the count of child

 * return :

 * return the count for the child;

 * */

int getCount();

void onItemChanged(int currentItem);

}

Adpater 只有3个方法
1.createItem 是一个工厂方法,负责创建child view
2.bindData 负责绑定数据
3.onItemChanged 是一个回调方法,传入的参数是当前显示的item 的位置

使用方法

ImageSwitcher iser;
...
...

Adapter adapter =new Adapter(){
    //实现Adapter 里面的方法
}
//设置Adapter
iser.setAdapter(adapter);
//可以在Activity onResume 当中使用该方法
void onResume(){
iser.start(1000//传入的是子view 之间的动画切换间隔)
}
void onStop(){
//在activity onStop 的时候 调用这个方法可以放置内存泄露
iser.stop()
}

项目特点


1.内容分离:不关心具体内容如何实现,这个由程序员控制。只要显示的内容继承自View即可
2.View重用:只会创建3个View用来显示内容,不会因为轮播的内容过多而创建过多的View 从而影响性能
3.支持滑动:支持用户滑动操作

项目结构简要说明


项目架构主要由三个类(接口)架设起来:
1.ImageSwitch :负责Layout 内容,内容切换,过渡动画
2.Timer:负责控制内容切换的时间间隔
3.Adapter:负责创建内容 动态绑定内容数据

遇到的一些问题


1.View.setTranslationX() 方法设置View的移动位置,但是View 的left right 并没有改变 。setTranslationY() 同样如此
2.View.layout() 方法可以改变View 的left right top bottom的位置。
3 View 当中的left right top bottom 的位置是相对与 View 当前parent 来计算的 不是绝对位置

最后


谢谢大家阅读,有问题和我交流

你可能感兴趣的:(Android自定义View 实现图片轮播)