Android实现Banner自动滑动,支持手动滑动以及滑动bug解决

不多哔哔,直接上代码,相信我你就复制下来直接用就好!

先上xml布局:

<RelativeLayout
    android :id= "@+id/container"
    android :layout_width= "wrap_content"
    android :layout_height= "wrap_content" >
    <android.support.v4.view.ViewPager
        android :id= "@+id/viewpager"
        android :layout_width= "match_parent"
        android :layout_height= "180dip" />
    <LinearLayout
    android :id= "@+id/dot_group"
    android :layout_width= "match_parent"
    android :layout_height= "wrap_content"
    android :layout_marginTop= "5dip"
    android :gravity= "center_horizontal"
    android :orientation= "horizontal"
    android :layout_alignParentBottom= "true"
    android :layout_marginBottom= "10dp" >
</LinearLayout>
</RelativeLayout>


其实也就是一个viewpager和LinearLayout的结合,可以复制代码然后用工具格式化一下


接下来是小圆圈:

<? xml version= "1.0" encoding= "utf-8" ?>
<selector xmlns: android = "http://schemas.android.com/apk/res/android" >
    <item
        android :state_enabled= "true"
        android :drawable= "@drawable/dot_on" />
    <item
        android :state_enabled= "false"
        android :drawable= "@drawable/dot_off" />
</selector>


里面的dot_on和dot_off是自己绘制的一个小圆,这里不再多少,如果你不是白痴,也会绘制简单的图形应该能理解

接下来是逻辑实现:

list = new ArrayList<>() ;
for ( int id:data()){
    SimpleDraweeView iv= new SimpleDraweeView( this .getActivity()) ;
    //iv.setBackgroundResource(id);
    iv.setController(Staticaadaptive. getDraweeController (iv , Staticaadaptive. getUri ( this .getActivity() , id))) ;
    list .add(iv);

    View dot= new View( this .getActivity()) ;
    dot.setBackgroundResource(R.drawable. dot_select ) ;
    LinearLayout.LayoutParams p= new LinearLayout.LayoutParams( 10 , 10 ) ;
    p. leftMargin = 10 ;
    dot.setEnabled( false ) ;
    dot.setLayoutParams(p) ;
    dot_group .addView(dot) ;
}

我解释一下里面的对象,不要让看官骂我:里面的list是你往adapter中设置的list,遍历就不用说了吧,你设置多少资源就设置多少然后遍历,里面的SimpleDraweeView是我以前用的Fresco加载图片用的控件,我现在已经不用这个了,你们可以用普通的Imageview就好,接下来就是小圆圈的设置,然后加到上面xml中的LinearLayout中就好了(大哥,能解释的都解释了,我尽力了)

接下来是adapter:

public class Banneradapter extends PagerAdapter {
    private List<SimpleDraweeView> list;
    private Activity activity;
    public Banneradapter(Activity activity,List<SimpleDraweeView> list){
        this.activity=activity;
        this.list=list;
    }
    @Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }


    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view==object;
    }


    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View)list.get(position%list.size()));
    }


    @Override
    public Object instantiateItem(ViewGroup container, final int position) {
        View view=list.get(position%list.size());
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if(position%list.size()==0||position%list.size()==1){
                        Intent intent=new Intent(activity, View_modelstate.class);
                        activity.startActivity(intent);
                    }
                }
            });
            container.addView(view);
        return view;
    }
}

别的就不说了,说一下里面的click我做的是Banner中item的点击事件,(偷懒)

接下来是pager的事件:

public class Pagelistener implements ViewPager.OnPageChangeListener {
    private int oldpositon;
    private List<SimpleDraweeView> list;
    private LinearLayout dot_group;
    public Pagelistener(List<SimpleDraweeView> list,LinearLayout dot_group){
        this.list=list;
        this.dot_group=dot_group;
    }
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {
        int newpositon=position%list.size();
        dot_group.getChildAt(oldpositon).setEnabled(false);
        dot_group.getChildAt(newpositon).setEnabled(true);
        oldpositon=newpositon;
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
}

这个就是监听现在显示的是那个,然后让小圆圈显示第几个,没啥说的吧!

接下来初始化设置:

dot_group .getChildAt( 0).setEnabled( true );
viewpager .setCurrentItem(0 ) ;

不说了,你至少应该告诉人家要先显示哪个吧!

接下来就是自动轮播了:

final Handler mHandler = new Handler() {
    @Override
    public void handleMessage (Message msg) {
        int pos= viewpager .getCurrentItem() ;
        switch (msg. what ){
            case b :
                viewpager .setCurrentItem(pos+ 1 ) ;
                break;
        }
        super .handleMessage(msg) ;
    }
} ;
Timer mtimer = new Timer() ;
TimerTask mTimerTask = new TimerTask() {

    @Override
    public void run () {
        // TODO Auto-generated method stub
        mHandler .sendEmptyMessage( b ) ;
    }
};

mtimer .schedule( mTimerTask , 3 * 1000 , 3 * 1000 ) ;

下面这个就是使用timer每隔3秒让他滚动一下

---------------------------------上面的就可以实现了,但是你使用的时候会有bug,不要骂我,接着看---------------------------------------------

将Handler替换Timer,使用Timer会引发线程问题

mHandler .postDelayed( autoRun 3000 ) ;
//banner 自动播放
Runnable  autoRun = new  Runnable() {
    @Override
    public void  run () {
        int  pos= viewpager .getCurrentItem()  ;
        viewpager .setCurrentItem(pos+  1 ) ;
        mHandler .postDelayed( autoRun 3000 ) ;
    }
} ;


在多个fragment中来回切换,fragment会重新创建(三个以及以上的fragment),所以,如果加入banner要将切换后移除Runable,否则会显示的越来越快!

@Override
public void  onDestroyView () {
    mHandler .removeCallbacks( autoRun ) ;
    mHandler .removeCallbacks( notifyRun ) ;
    mHandler .removeCallbacks( notifyExit ) ;
    super .onDestroyView() ;

}

不懂留言问吧,我说的很清楚了


----------------------------------------------轮播滑动崩溃问题解决-------------------------------------------------------------
@Override
    public void destroyItem(ViewGroup container, int position, Object object) {
         //container.removeView(list.get(position % list.size()).getIv());
    }

    @Override
    public Object instantiateItem(ViewGroup container, final int position) {
        View view = list.get(position % list.size()).getIv();
         try {
            container.addView(view,0);
        }catch(Exception e){
            //handler something
        }

        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (null != bannerItemCLick) {
                    bannerItemCLick.bannerItemClick(list.get(position % list.size()).getVideoId());
                }
            }
        });
        return view;
    }

使用过程中,如果你往左滑动没问题,你要是往右滑动直接爆炸,上面事解决方案,至于原理你和上面我的adapter比较一下就能明白了,至此完成了所有的实现以及bug解决方法

如果对您有帮助请继续以下程序:


QQ交流群:


打赏:

    










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值