支援橫向、豎向無限滾動和自定義指示器的廣告條BannerView和淘寶頭條效果
前言:有那麼多的Banner框架,為什麼還要重新寫呢?其實不是由於第三方的太重、不好維護等原因,最致命的問題是第三方banner框架大多使用ViewPager實現,而使用這種方式一般會伴隨兩個問題:
return Integer.MAX_VALUE
替換banner實現方式前:公司專案使用了ViewPager 實現的無限滾動廣告BannerANR異常統計 :到目前為止竟然有10幾頁之多,每一頁15條,一條可能包含了上百次的ANR,這是多麼恐怖的一個數字(假設15頁,每頁15條,每條100次,那麼1515 100=22500次),實際上可能更多,下圖中第一條就有836次ARN
產生ANR 的原因:開篇已經大致介紹,就是呼叫ViewPager.setCurrentItem(),底層會去測量滾動的偏移量,由於實現無線滾動的方式是將介面卡中間的getItemCount()方法返回一個無窮大的數,所以在測量偏移量時會特別耗時,這樣就導致了ANR異常。
解決方案:使用RecyclerView 實現的無限滾動Banner,徹底解決呼叫ViewPager.setCurrentItem()
導致的ANR 異常
,並做到頁面切換絲滑順暢
先來一波效果圖展示(demo偏醜,無關緊要,注意效果)
屬性介紹
<!--廣告條--> <declare-styleable name="BannerView"> <!--時間--> <attr name="interval" /> <!--方向--> <attr name="orientation" format="enum"> <enum name="horizontal" value="0" /> <enum name="vertical" value="1" /> </attr> <!--自動播放--> <attr name="autoPlaying" format="boolean"/> <!--item間的間距--> <attr name="itemSpace" format="integer"/> <!--中間的item大小和設定item大小的比例--> <attr name="centerScale" format="float"/> <!--手指滑動時,banner移動的的速度--> <attr name="moveSpeed" format="float"/> <!--資料為空時,展示的view--> <attr name="empty_layout" format="reference" /> </declare-styleable>
接入並使用框架
新增依賴
<code lang="bash">//在工程的gradle中新增jitpack倉庫 allprojects { repositories { ... maven { url 'https://jitpack.io' } } } </code> <code lang="bash">dependencies { //在module的gradle中新增依賴 implementation 'com.github.93Laer:BannerView_master:v1.0.1' } </code>
重新同步一下
使用步驟:3+2
第一步:佈局
<com.example.laitianbing.bannerview_master.banner_view.BannerView android:id="@+id/banner" android:layout_width="match_parent" android:layout_height="100dp" android:background="@color/bannerBackground" app:autoPlaying="true" app:empty_layout="@layout/empty_view" app:interval="3000" />
第二步:找到控制元件mBanner = findViewById(R.id.banner);
第三部:繫結介面卡,並放入初始化資料來源
mAdapter = new BannerAdapter<Item>(this, itemLayout, items) { @Override public void convert(ViewHolder holder, final Item item) { //書寫自己的處理邏輯 holder.setImage(R.id.iv_image, item.imgRes); holder.setText(R.id.tv_name, item.url); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { WebActivity.start(BannerActivity.this, item.url); } }); } }; mBanner.setAdapter(mAdapter);
第四部:新增指示器(不顯示指示器就沒有此步驟)
//建立指示器 mCircleIndicator = new RectIndicator(this, RectIndicator.SHAPE_CIRCLE); //設定指示器長和寬. mCircleIndicator.setIndicatorSize(10, 10); //設定指示器之間的間距 mCircleIndicator.setItemMargin(20); //設定指示器顯示在banner的底部的中間 mCircleIndicator.setRules(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.CENTER_HORIZONTAL); //設定指示器顯示距離banner底部10dp mCircleIndicator.setMargins(0, 0, 0, 10); //新增指示器 mBanner.addIndicator(mCircleIndicator);
第五部:重新整理資料(不重新整理資料就沒有此步驟)mAdapter.setDatas(DataHelper.getItems());
使用進階提示:
-
1、在出廠前已將指示器分為圖形指示器和文字指示器兩類,如果想自定義圖形指示器則直接繼承
BaseIndicator
即可 - 2、在新增指示器的時候,你可以像在RelativeLayout中設定子view的位置一樣設定指示器的位置,換句話說你可以指定指示器顯示在banner中的任意位置
-
3、可以自定義指示器,但是必須繼承view且實現Indicator介面
,換句話說任意View,只要實現Indicator介面,它就可以成為指示器,如果還不懂,那就看
TextIndicator
實現 - 4、如果專案中要實現想淘寶,京東的頭條那種垂直滾動,使用該框架就可以輕鬆完成
專案連結:BannerView_master