Android开发

Android开发完整项目案例-Banner

2021-11-12  本文已影响0人  你的益达233

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

背景:

需要网上有很多轮子,但是如果项目就一个简单的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();
    }
}
上一篇下一篇

猜你喜欢

热点阅读