美文网首页Android开发
Android开发完整项目案例-Banner

Android开发完整项目案例-Banner

作者: 你的益达233 | 来源:发表于2021-11-12 14:38 被阅读0次

    网上的轮子已经很多了,也都很强大。

    背景:

    需要网上有很多轮子,但是如果项目就一个简单的banner,如果引入库,是不是有点杀鸡用牛刀了。

    需求:

    自动播放,循环

    效果图:

    banner.png

    思路:

    布局上用viewpager+linearLayout,然后再通过RxJava控制它循环轮播

    关键代码:

    custom_layout_banner.xml

    <?xml version="1.0" encoding="utf-8"?>
    
    <android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">
    <com.yiban1314.yiban.widget.ProportionViewPager
        android:id="@+id/vp_pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:proportion="0.52"
        tools:background="@color/c_ed"
        app:layout_constraintTop_toTopOf="parent"/>
    <LinearLayout
        android:id="@+id/ll_points"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginRight="@dimen/d24px"
        android:layout_marginBottom="@dimen/d30px"
        app:layout_constraintRight_toRightOf="@id/vp_pager"
        app:layout_constraintBottom_toBottomOf="@id/vp_pager"
        android:visibility="gone"/>
    <LinearLayout
        android:id="@+id/ll_center_points"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginBottom="@dimen/d14px"
         app:layout_constraintBottom_toBottomOf="@id/vp_pager"
        app:layout_constraintRight_toRightOf="@id/vp_pager"
        app:layout_constraintLeft_toLeftOf="@id/vp_pager"
        android:visibility="gone"/>
    <LinearLayout
        android:id="@+id/ll_out_bottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintTop_toBottomOf="@id/vp_pager"
        app:layout_constraintRight_toRightOf="@id/vp_pager"
        app:layout_constraintLeft_toLeftOf="@id/vp_pager"
        android:visibility="gone"/>
    </android.support.constraint.ConstraintLayout>
    

    注:ProportionViewPager可以直接用ViewPager代替

    自定义MyBanner.class

    public class MyBanner extends FrameLayout {
    
    private ProportionViewPager viewPager;
    private LinearLayout llPoint;
    private LinearLayout llCenterPoints;
    private LinearLayout llOutBottom;
    
    private Disposable subscription;
    private Context mContext;
    private int size;
    
    //是否循环
    private boolean isLoop;
    //宽高比
    private float proportionBanner;
    private CurrentPageClick currentPageClick;
    
    
    public MyBanner(@NonNull Context context) {
        this(context, null);
    }
    
    public MyBanner(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }
    
    public MyBanner(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        initAttrs(attrs);
        initView();
    }
    
    
    private void initAttrs(AttributeSet attrs) {
        if (null != attrs) {
            TypedArray t = mContext.obtainStyledAttributes(attrs, R.styleable.MyBanner);
            isLoop = t.getBoolean(R.styleable.MyBanner_isLoop, false);
            proportionBanner = t.getFloat(R.styleable.MyBanner_proportionBanner,0.52f);
            t.recycle();
        }
    
    }
    
    
    public void initView() {
        //会添加布局到自定义的view中
        View view = LayoutInflater.from(mContext).inflate(R.layout.custom_layout_banner, this, true);
        viewPager = view.findViewById(R.id.vp_pager);
        viewPager.setProportion(proportionBanner);
        llPoint = view.findViewById(R.id.ll_points);
        llCenterPoints = view.findViewById(R.id.ll_center_points);
        llOutBottom = view.findViewById(R.id.ll_out_bottom);
    }
    
    
    private void setGone(){
        llPoint.setVisibility(GONE);
        llCenterPoints.setVisibility(GONE);
        llOutBottom.setVisibility(GONE);
    }
    
    /**
     * @param datas 直接传view集合过来,这样不局限与ImageView
     *              desc:初始化数据
     *              position :指示器位置 0 在图片内的右下角; 1 在图片内底部居中; 2 在图片底部外面
     *              proportion ; 图片的比例设置
     **/
    public void setDatas(List<View> datas,int position,double proportion,int pointDrawableRes) {
        if (Utils.isNotNull(datas)) {
            size = datas.size();
            viewPager.setAdapter(new MyAdapter(datas));
            if(proportion != 0){
                viewPager.setProportion(proportion);
            }
            setGone();
            switch (position){
                case 0:
                    initPoint(datas.size(),llPoint,pointDrawableRes);
                    initEvent(llPoint);
                    break;
                case 1:
                    initPoint(datas.size(),llCenterPoints,pointDrawableRes);
                    initEvent(llCenterPoints);
                    break;
                case 2:
                    initPoint(datas.size(),llOutBottom,pointDrawableRes);
                    initEvent(llOutBottom);
                    break;
            }
            if (isLoop) {
                startLoop();
            }
        }
    }
    
    
    private void initPoint(int pointSize,LinearLayout ll,int pointDrawableRes) {
        if(pointSize == 1){
            ll.setVisibility(GONE);
        }else {
            ll.setVisibility(VISIBLE);
            ll.removeAllViews();
            for (int i = 0; i < pointSize; i++) {
                //小指标点
                View v_point = new View(mContext);
                v_point.setBackgroundResource(pointDrawableRes);
    
                v_point.setSelected(false);
                LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                        Utils.dip2px(mContext, 6),
                        Utils.dip2px(mContext, 6));
                if (i != 0) params.leftMargin = Utils.dip2px(mContext, 6);
                v_point.setLayoutParams(params);
    
                ll.addView(v_point);
            }
        }
    }
    
    
    private void initEvent(final LinearLayout ll) {
        if (ll.getChildCount() > 0) {
            ll.getChildAt(0).setSelected(true);
        }
        viewPager.clearOnPageChangeListeners();
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    
            }
    
            @Override
            public void onPageSelected(int position) {
                for (int i = 0; i < ll.getChildCount(); i++) {
                    ll.getChildAt(i).setSelected(false);
                }
                ll.getChildAt(position).setSelected(true);
    
            }
    
            @Override
            public void onPageScrollStateChanged(int state) {
    
            }
        });
    }
    
    
    //viewpager的适配器
    private class MyAdapter extends PagerAdapter {
    
        private List<View> imageViewList;
    
        public MyAdapter(List<View> imageViewList) {
            this.imageViewList = imageViewList;
        }
    
        @Override
        public int getCount() {
            // 返回数据的个数
            return imageViewList != null ? imageViewList.size() : 0;
        }
    
        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == arg1;
        }
    
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            //从viewpager中移除掉
            container.removeView((View) object);
        }
    
        @Override
        public Object instantiateItem(ViewGroup container, final int position) {
            //获取View
            View child = imageViewList.get(position);
            // 添加View
            container.addView(child);
    
            child.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (null != currentPageClick) {
                        currentPageClick.onClickCurrent(position);
                    }
                }
            });
    
            return child;
        }
    
    }
    
    
    public void startLoop() {
        if (subscription == null) {
            subscription = Observable.interval(3, TimeUnit.SECONDS)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Long>() {
                        @Override
                        public void accept(Long aLong) throws Exception {
                            int mCurrentItem = viewPager.getCurrentItem();
                            if (mCurrentItem == size - 1) {
                                mCurrentItem = 0;
                            } else {
                                mCurrentItem++;
                            }
                            viewPager.setCurrentItem(mCurrentItem);
                        }
    
                    });
        }
    
    
    }
    
    
    public void stopLoop() {
        if (null != subscription && !subscription.isDisposed()) {
            subscription.dispose();
        }
    }
    
    public void setCurrentPageClick(CurrentPageClick currentPageClick) {
        this.currentPageClick = currentPageClick;
    }
    
    public interface CurrentPageClick {
        void onClickCurrent(int position);
    }
    
    }  
    

    使用示例代码:

    public void onBannerResult(final BannerResult bannerResult) {
        if (myBanner == null) {
            myBanner = (MyBanner) Utils.inflate(MyApplication.getInstance(), R.layout.layout_discovery_banner, srrvDatas);
            getAdapter().addHeaderView(myBanner);
        }
        if(null != bannerResult && null != bannerResult.getData()){
            List<View> viewList = new ArrayList<>();
            for (int i = 0; i < bannerResult.getData().size(); i++) {
                ImageView iv = Utils.inflate(MyApplication.getInstance(), R.layout.item_banner).findViewById(R.id.iv_img);
                if(ModifySetUtils.isFourFormal()){
                    ImageLoaderUtils.loadCorner(iv, bannerResult.getData().get(i).getImg(),Utils.dp2px(mContext,8));
                }else {
                    ImageLoaderUtils.load(iv, bannerResult.getData().get(i).getImg());
                }
                viewList.add(iv);
            }
            //不管哪个版本都显示在中间
            myBanner.setDatas(viewList,1,0,R.drawable.point_background);
    
            myBanner.setCurrentPageClick(new MyBanner.CurrentPageClick() {
                @Override
                public void onClickCurrent(int position) {
                    //游客拦截掉
                    if (InfoCheckUtils.isTourist(mContext, true)) return;
                    //0不做处理,1跳转网页,2跳外部系统网页
                    BannerResult.DataBean dataBean = bannerResult.getData().get(position);
                    switch (dataBean.getType()){
                        case 0:
                            break;
                        case 1:
                            EventBusUtils.postSticky(new WebEevent(dataBean.getTitle(),dataBean.getUrl(), dataBean.getShareInfo()));
                            IntentUtils.startWebActivity(mContext);
                            break;
                        case 2:
                            IntentUtils.startSysWebActivity(mContext,dataBean.getUrl());
                            break;
                    }
                }
            });
            myBanner.setVisibility(View.VISIBLE);
        }else {
            removeBanner();
        }
    }

    相关文章

      网友评论

        本文标题:Android开发完整项目案例-Banner

        本文链接:https://www.haomeiwen.com/subject/cecozltx.html