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();
}
}