欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-03-23 23:29:28
...

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

先上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(autoRun3000);
//banner自动播放
Runnable autoRun=new Runnable() {
    @Override
    public void run() {
        int pos=viewpager.getCurrentItem() ;
        viewpager.setCurrentItem(pos+ 1);
        mHandler.postDelayed(autoRun3000);
    }
};


在多个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交流群:

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

打赏:

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