android自定义view拉扯图片,Android自定义View 实现图片轮播

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

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

效果

2a8d77b147e4

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

//layout the child in right position

View child=getChildAt(i);

if(childs[0].equals(child)){

//The child should be put int left;

child.layout(-width,this.t,0,this.b);

}

if(childs[1].equals(child)){

//The child should be put int middle

child.layout(this.l,this.t,this.r,this.b);

}

if(childs[2].equals(child)){

child.layout(getWidth(),this.t,getWidth()+width,this.b);

}

}

}

子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 来计算的 不是绝对位置

最后

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值