筆記20170429--用FlycoTabLayout+Glide實現(xiàn)動態(tài)加載底部TAB圖標(Android)

需求:

管理后臺可以自由設(shè)置圖片,通過服務(wù)器返回給客戶端,客戶端根據(jù)管理后臺設(shè)置的內(nèi)容,去展示各個位置的圖或圖標(例如很多常用的app,有沒有觀察到有時候底部圖標會不一樣啊,不知道別人怎么實現(xiàn)的,但是我們的客戶要求就是需要可以動態(tài)設(shè)置這樣會比較靈活不用每次都找技術(shù)去換)

要達到的效果

美團app的bottomBar.png

上圖是我截圖美團的bottomBar,要達到的效果就是這些圖標他們自己可以換,我們只需要加載圖標url就可以了
碎碎念:其實這種需求就自己寫就可以了,干嘛還要用第三方的依賴,還要拿別人源碼然后再改多麻煩?因為當初項目開始的時候沒有這個需求啊,用本地資源的話這個FlycoTabLayout蜜汁方便??蛻簦阂銈冏屇銈儗懯娣?,就算我輸

相關(guān)代碼:

xml--用到FlycoTabLayout的布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clickable="true">

    <FrameLayout
        android:id="@+id/fragmentContent"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/bottomLayout" />


    <LinearLayout
        android:id="@+id/bottomLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="@android:color/white"
        android:orientation="vertical">

        <View
            android:layout_width="match_parent"
            android:layout_height="1px"
            android:background="?android:listDivider" />

        <com.flyco.tablayout.CommonTabLayout
            android:id="@+id/bottomBar"
            android:layout_width="match_parent"
            android:layout_height="49dp"
            android:layout_marginTop="2dp"
            android:background="#ffffff"
            app:tl_iconHeight="23dp"
            app:tl_iconWidth="25dp"
            app:tl_indicator_color="#ffcc02"
            app:tl_indicator_height="0dp"
            app:tl_textSelectColor="#ffcc02"
            app:tl_textUnselectColor="#666666"
            app:tl_textsize="10sp"
            app:tl_underline_color="#DDDDDD"
            app:tl_underline_height="1dp" />


    </LinearLayout>
</RelativeLayout>

代碼:存每個圖標和文字的對象
package com.xxx.xxx.xxx.bean;

import com.flyco.tablayout.listener.CustomTabEntity;

/**
 * Created by Hello我的World on 2017/3/12.
 */

public class ImageTabEntity implements CustomTabEntity {
    public String title;
    public int selectedIcon;
    public int unSelectedIcon;
    public String selectedIconStr;
    public String unSelectedIconStr;
    //直接用本地資源時候用的構(gòu)造方法
    public ImageTabEntity(String title, int selectedIcon, int unSelectedIcon) {
        this.title = title;
        this.selectedIcon = selectedIcon;
        this.unSelectedIcon = unSelectedIcon;
    }
    //用url時的構(gòu)造方法,這兩個構(gòu)造方法里的第一個參數(shù)就是選項的字,第二個參數(shù)是選項被選中時的圖,第三個參數(shù)是選項未被選中時的圖
    public ImageTabEntity(String title,String selectedIconStr,String unSelectedIconStr){
        this.title = title;
        this.selectedIconStr = selectedIconStr;
        this.unSelectedIconStr = unSelectedIconStr;
    }

    @Override
    public String getTabTitle() {
        return title;
    }

    @Override
    public int getTabSelectedIcon() {
        return selectedIcon;
    }

    @Override
    public int getTabUnselectedIcon() {
        return unSelectedIcon;
    }

    @Override
    public String getTabSelectedIconByString() {
        return selectedIconStr;
    }

    @Override
    public String getTabUnSelectedIconByString() {
        return unSelectedIconStr;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void setSelectedIcon(int selectedIcon) {
        this.selectedIcon = selectedIcon;
    }

    public void setUnSelectedIcon(int unSelectedIcon) {
        this.unSelectedIcon = unSelectedIcon;
    }

    public void setSelectedIconStr(String selectedIconStr) {
        this.selectedIconStr = selectedIconStr;
    }

    public void setUnSelectedIconStr(String unSelectedIconStr) {
        this.unSelectedIconStr = unSelectedIconStr;
    }
}

Activity中的使用(只記錄一下關(guān)鍵代碼):
public class MainActivity extends BaseActivity {
    @BindView(R.id.fragmentContent)
    FrameLayout fragmentContent;
    @BindView(R.id.bottomBar)
    CommonTabLayout bottomBar;

 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        manager = getSupportFragmentManager();
        currentTabIndex = 0;
        if (savedInstanceState != null) {
            currentTabIndex = savedInstanceState.getInt("CurrentIndex", 0);
        }
        setCurrentTab(currentTabIndex, manager);
        ImageTabEntity imageTabEntity1;
        ImageTabEntity imageTabEntity2;
        ImageTabEntity imageTabEntity3;
        ArrayList<CustomTabEntity> tabs = new ArrayList<>();
        //登錄獲取服務(wù)器返回的服務(wù)器圖標url數(shù)組如果不為空就加載圖標url和本地資源,如果為空就只加載本地資源
                if (pref.getBottomIcons() != null) {
                    imageTabEntity1 = new ImageTabEntity(getString(R.string.work),pref.getBottomIcons().getIcons().get(1).getUrl(),pref.getBottomIcons().getIcons().get(0).getUrl());
                    imageTabEntity1.setSelectedIcon( R.drawable.bottom_lh_hover_icon);
                    imageTabEntity1.setUnSelectedIcon(R.drawable.bottom_lh_icon);
                    imageTabEntity2 = new ImageTabEntity(getString(R.string.order),pref.getBottomIcons().getIcons().get(3).getUrl(),pref.getBottomIcons().getIcons().get(2).getUrl());
                    imageTabEntity2.setSelectedIcon(R.drawable.bottom_order_hover_icon);
                    imageTabEntity2.setUnSelectedIcon(R.drawable.bottom_order_icon);
                    imageTabEntity3 = new ImageTabEntity(getString(R.string.mine),pref.getBottomIcons().getIcons().get(5).getUrl(),pref.getBottomIcons().getIcons().get(4).getUrl());
                    imageTabEntity3.setSelectedIcon(R.drawable.bottom_my_hover_icon);
                    imageTabEntity3.setUnSelectedIcon(R.drawable.bottom_icon);
                    tabs.add(imageTabEntity1);
                    tabs.add(imageTabEntity2);
                    tabs.add(imageTabEntity3);
                } else {
                    imageTabEntity1 = new ImageTabEntity(getString(R.string.work), R.drawable.bottom_lh_hover_icon, R.drawable.bottom_lh_icon);
                    imageTabEntity2 = new ImageTabEntity(getString(R.string.order), R.drawable.bottom_order_hover_icon, R.drawable.bottom_order_icon);
                    imageTabEntity3 = new ImageTabEntity(getString(R.string.mine), R.drawable.bottom_my_hover_icon, R.drawable.bottom_icon);
                    tabs.add(imageTabEntity1);
                    tabs.add(imageTabEntity2);
                    tabs.add(imageTabEntity3);
                }
        //將數(shù)據(jù)設(shè)置到這個bottomBar中
        bottomBar.setTabData(tabs);
        bottomBar.setOnTabSelectListener(new OnTabSelectListener() {
            @Override
            public void onTabSelect(int position) {
                //這個方法是選中了哪個圖標的監(jiān)聽,position是選中的位置
                setCurrentTab(position, manager);
            }

            @Override
            public void onTabReselect(int position) {

            }
        });
}
CommonTabLayout源碼中要改的方法(代碼片段):
//首先要在FlycoTabLayout庫的build文件中,添加最新的glide依賴
//我當時加的時候還是最新的  compile 'com.github.bumptech.glide:glide:3.7.0'
//在這個控件的類中聲明兩個變量兩個常量
private RequestManager glide;//glide
private List<HashMap> bitmapResource ;//glide加載了圖片后的緩存bitmap集合,選中和非選中的兩個圖為1個map
private final String TAB_SELECTED="tabSelected";//和下邊這個變量是用到的hashmap的key
private final String TAB_UNSELECTED="tabUnselected";

//setDate方法 設(shè)置數(shù)據(jù),在這個方法里就要用glide把圖片都加載一邊并存好緩存的bitmap
public void setTabData(ArrayList<CustomTabEntity> tabEntities) {
        if (tabEntities == null || tabEntities.size() == 0) {
            throw new IllegalStateException("TabEntitys can not be NULL or EMPTY !");
        }
        this.mTabEntitys.clear();
        this.mTabEntitys.addAll(tabEntities);
        //先判斷glide加載的緩存數(shù)組有沒有
        if(bitmapResource==null||bitmapResource.size()==0){
            bitmapResource = new ArrayList<>();
        }else{
            bitmapResource.clear();
        }
        //遍歷傳來的tab對象
        for(final CustomTabEntity tabEntity:tabEntities){
            //如果圖標url不是空的,就用glide加載選中的和未選中的圖片,緩存下來的bitmap存進map中,然后將map放入list里
            if(!TextUtils.isEmpty(tabEntity.getTabSelectedIconByString())||!TextUtils.isEmpty(tabEntity.getTabUnSelectedIconByString())){
                final HashMap<String,Bitmap> hashMap = new HashMap<>();
                glide.load(tabEntity.getTabUnSelectedIconByString()).asBitmap().into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                        hashMap.put(TAB_UNSELECTED,resource);
                    }
                });
                glide.load(tabEntity.getTabSelectedIconByString()).asBitmap().into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                        hashMap.put(TAB_SELECTED,resource);
                    }
                });
                bitmapResource.add(hashMap);
            }
        }
        notifyDataSetChanged();
    }

//更新數(shù)據(jù)的方法
public void notifyDataSetChanged() {
        mTabsContainer.removeAllViews();
        this.mTabCount = mTabEntitys.size();
        View tabView;
        for (int i = 0; i < mTabCount; i++) {
            if (mIconGravity == Gravity.LEFT) {
                tabView = View.inflate(mContext, R.layout.layout_tab_left, null);
            } else if (mIconGravity == Gravity.RIGHT) {
                tabView = View.inflate(mContext, R.layout.layout_tab_right, null);
            } else if (mIconGravity == Gravity.BOTTOM) {
                tabView = View.inflate(mContext, R.layout.layout_tab_bottom, null);
            } else {
                tabView = View.inflate(mContext, R.layout.layout_tab_top, null);
            }
            tabView.setTag(i);
            addTab(i, tabView);
        }
        updateTabStyles();
    }

//添加tab
private void addTab(final int position, View tabView) {
        TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
        tv_tab_title.setText(mTabEntitys.get(position).getTabTitle());
        final ImageView iv_tab_icon = (ImageView) tabView.findViewById(R.id.iv_tab_icon);
        int resourceImg = mTabEntitys.get(position).getTabUnselectedIcon();
      //還是先判斷是加載本地資源還是加載url 
      if(TextUtils.isEmpty(mTabEntitys.get(position).getTabSelectedIconByString())||TextUtils.isEmpty(mTabEntitys.get(position).getTabUnSelectedIconByString())){
            iv_tab_icon.setImageResource(resourceImg);
        }else{
            //如果執(zhí)行到這一步的時候圖片還未加載完成,就先設(shè)置未加載本地資源的圖標
            Bitmap bitmap = (Bitmap) bitmapResource.get(position).get(TAB_UNSELECTED);
            if(bitmap!=null){
                iv_tab_icon.setImageBitmap(bitmap);
            }else{
                iv_tab_icon.setImageResource(resourceImg);
            }
        }
        tabView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = (Integer) v.getTag();
                if (mCurrentTab != position) {
                    setCurrentTab(position);
                    if (mListener != null) {
                        mListener.onTabSelect(position);
                    }
                } else {
                    if (mListener != null) {
                        mListener.onTabReselect(position);
                    }
                }
            }
        });

        /** 每一個Tab的布局參數(shù) */
        LinearLayout.LayoutParams lp_tab = mTabSpaceEqual ?
                new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f) :
                new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        if (mTabWidth > 0) {
            lp_tab = new LinearLayout.LayoutParams((int) mTabWidth, LayoutParams.MATCH_PARENT);
        }
        mTabsContainer.addView(tabView, position, lp_tab);
    }
//更新tab風(fēng)格
 private void updateTabStyles() {
        for (int i = 0; i < mTabCount; i++) {
            View tabView = mTabsContainer.getChildAt(i);
            tabView.setPadding((int) mTabPadding, 0, (int) mTabPadding, 0);
            TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
            tv_tab_title.setTextColor(i == mCurrentTab ? mTextSelectColor : mTextUnselectColor);
            tv_tab_title.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextsize);
//            tv_tab_title.setPadding((int) mTabPadding, 0, (int) mTabPadding, 0);
            if (mTextAllCaps) {
                tv_tab_title.setText(tv_tab_title.getText().toString().toUpperCase());
            }

            if (mTextBold == TEXT_BOLD_BOTH) {
                tv_tab_title.getPaint().setFakeBoldText(true);
            } else if (mTextBold == TEXT_BOLD_NONE) {
                tv_tab_title.getPaint().setFakeBoldText(false);
            }

            final ImageView iv_tab_icon = (ImageView) tabView.findViewById(R.id.iv_tab_icon);
            if (mIconVisible) {
                iv_tab_icon.setVisibility(View.VISIBLE);
                CustomTabEntity tabEntity = mTabEntitys.get(i);
            //跟上邊的方法一樣都是如果不是bitmap不為空就加載bitmap如果為空就加載本地資源    
            if(TextUtils.isEmpty(tabEntity.getTabSelectedIconByString())||TextUtils.isEmpty(tabEntity.getTabUnSelectedIconByString())){
                    iv_tab_icon.setImageResource(i == mCurrentTab ? tabEntity.getTabSelectedIcon() : tabEntity.getTabUnselectedIcon());
                }else{
                    Bitmap sBitmap,uBitmap;
                    sBitmap = (Bitmap) bitmapResource.get(i).get(TAB_SELECTED);
                    uBitmap = (Bitmap) bitmapResource.get(i).get(TAB_UNSELECTED);
                    if(sBitmap!=null&&uBitmap!=null){
                        iv_tab_icon.setImageBitmap(i==mCurrentTab?sBitmap:uBitmap);
                    }else{
                        iv_tab_icon.setImageResource(i==mCurrentTab?tabEntity.getTabSelectedIcon():tabEntity.getTabUnselectedIcon());
                    }

                }
                LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                        mIconWidth <= 0 ? LinearLayout.LayoutParams.WRAP_CONTENT : (int) mIconWidth,
                        mIconHeight <= 0 ? LinearLayout.LayoutParams.WRAP_CONTENT : (int) mIconHeight);
                if (mIconGravity == Gravity.LEFT) {
                    lp.rightMargin = (int) mIconMargin;
                } else if (mIconGravity == Gravity.RIGHT) {
                    lp.leftMargin = (int) mIconMargin;
                } else if (mIconGravity == Gravity.BOTTOM) {
                    lp.topMargin = (int) mIconMargin;
                } else {
                    lp.bottomMargin = (int) mIconMargin;
                }

                iv_tab_icon.setLayoutParams(lp);
            } else {
                iv_tab_icon.setVisibility(View.GONE);
            }
        }
    }

實現(xiàn)思路:

  • 本身項目都是需要加載url展示圖片的,鬼知道客戶會不會要加載gif圖什么的,所以用了glide,那么剛好用glide加載圖標吧(glide看這里
  • FlycoTabLayout:因為要用glide所以要把庫下下來引入,在庫的build文件里引入glide
  • 在自定義圖標對象繼承 CustomEntity時候,加自定義的參數(shù),是自己需要的url,String類型就行了
  • 然后第一次將數(shù)據(jù)設(shè)置到tabLayout的時候,在setData的方法里就要判斷是否需要加載url,如果是的話,就用glide在這個方法里加載,循環(huán)加載,每循環(huán)一次將緩存下來的bitmap存入list中(總共bottom中也用不了幾個圖標,所以循環(huán)也不會耗時,并且glide load的時候應(yīng)該也是異步的)
  • 每次不管點擊也好,還是別的操作觸發(fā)tabLayout的更新方法,在這個更新方法里設(shè)置setImageBitmap即可

以上是關(guān)于這個需求的筆記,最重要的是項目開始時候一定要做好未來擴展的準備,不要像這次突然提一個需求,只能現(xiàn)想辦法改!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,716評論 25 709
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,502評論 19 139
  • 內(nèi)容抽屜菜單ListViewWebViewSwitchButton按鈕點贊按鈕進度條TabLayout圖標下拉刷新...
    皇小弟閱讀 47,133評論 22 665
  • 一、簡介 在泰國舉行的谷歌開發(fā)者論壇上,谷歌為我們介紹了一個名叫Glide的圖片加載庫,作者是bumptech。這...
    天天大保建閱讀 7,753評論 2 28
  • 老子云:禍莫大于不知足,咎莫大于欲得,故知足之足長足矣。控制住自己的欲望,堅定自己的信心,不斷完善自己,終會獲得內(nèi)...
    翠翠美閱讀 273評論 0 1

友情鏈接更多精彩內(nèi)容