Android戰(zhàn)紀(jì)之基于上篇單Activity+多Fragment框架怒见,開發(fā)電商式導(dǎo)航欄锌半,多Fragment切換

電商式導(dǎo)航欄禽车,多Fragment切換


  • 本文默認(rèn)在已經(jīng)搭建好的框架上進(jìn)行開發(fā)

點(diǎn)此鏈接到上一篇基礎(chǔ)框架的搭建

  • 界面構(gòu)思示意圖
    這里寫圖片描述
  • 設(shè)計(jì)思路
    在底部的LinearLayout中添加相應(yīng)的圖標(biāo),然后設(shè)置tag綁定相應(yīng)的 Fragment數(shù)組對(duì)應(yīng)的下標(biāo)值刊殉,再點(diǎn)擊切換的時(shí)候殉摔,根據(jù)獲取到的tag值,取出數(shù)組中對(duì)應(yīng)下標(biāo)的Fragment记焊,在通過相關(guān)方法顯示逸月。
    封裝目標(biāo):只需添加相應(yīng)的按鈕對(duì)象和相應(yīng)的視圖即可,然后在Activity中顯示即可遍膜。

  • 先創(chuàng)建可切換的Fragment的基類BottomItemFragment(實(shí)現(xiàn)一個(gè)雙擊退出功能)
// 定義為抽象類即每個(gè)itemfragment的基類
public abstract class BottomItemFragment extends MyFragment implements View.OnKeyListener{
    // 當(dāng)前按下返回按鈕的時(shí)間
    private long mExitTime = 0;
    // 雙擊返回鍵之間的延遲
    private static final int EXIT_TIME = 2000;
    
    @Override
    public void onResume(){
        super.onResume();
        View rootView = getView();
        // 防止雙擊退出失效
        if (rootView!=null){
            rootView.setFocusableInTouchMode(true);
            rootView.requestFocus();
            rootView.setOnKeyListener(this);
        }
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event){
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){
            if ((System.currentTimeMillis() - mExitTime) > EXIT_TIME) {
                Toast.makeText(getContext(), "雙擊退出", Toast.LENGTH_SHORT).show();
                mExitTime = System.currentTimeMillis();
            } else {
                _mActivity.finish();
                if (mExitTime != 0) {
                    mExitTime = 0;
                }
            }
            return true;
        }
    }
}
public final class BottomTabBean {
    private final CharSequence ICON;
    private final CharSequence TITLE;

    public BottomTabBean(CharSequence ICON, CharSequence TITLE){
        this.ICON = ICON;
        this.TITLE = TITLE;
    }

    public CharSequence getICON(){
        return ICON;
    }
    public CharSequence getTITLE(){
        return TITLE;
    }
}
  • 新建一個(gè)ItemBuilder瓤湘,目的是用來把每一個(gè)Fragment和底部的按鈕對(duì)象進(jìn)行綁定組裝進(jìn)一個(gè)LinkedHashMap的集合
public final class ItemBuilder{
    private final LinkedHashMap<BottomTabBean,BottomItemDelegate> ITEMS = new LinkedHashMap<>();
    
    static ItemBuilder builder(){
        return new ItemBuilder();
    }

    public final ItemBuilder addItem(BottomTabBean bean, BottomItemDelegate delegate){
        ITEMS.put(bean, delegate);
        return this;
    }
    
    public final ItemBuilder addItems(LinkedHashMap<BottomTabBean, BottomItemDelegate> items){
        ITEMS.putAll(items);
        return this;
    }

    public final LinkedHashMap<BottomTabBean, BottomItemDelegate> build(){
        return ITEMS;
    }
}
  • 接下來貼兩個(gè)布局文件,一個(gè)是根Fragment的布局恩尾,其實(shí)就是一個(gè)FrameLayout加上一個(gè)底部按鈕的LinearLayout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.ContentFrameLayout
        android:id="@+id/bottom_bar_delegate_container"
        android:layout_above="@+id/bottom_bar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <android.support.v7.widget.LinearLayoutCompat
        android:id="@+id/bottom_bar"
        android:layout_width="match_parent"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal"
        android:layout_height="60dp"/>

</RelativeLayout>
  • 然后是底部按鈕的item布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:paddingBottom="6dp"
    android:paddingTop="6dp">

    <com.joanzapata.iconify.widget.IconTextView
        android:id="@+id/icon_bottom_item"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:gravity="center"
        android:textSize="25sp" />

    <android.support.v7.widget.AppCompatTextView
        android:id="@+id/tv_bottom_item"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:gravity="center" />

</RelativeLayout>
  • 萬事俱備弛说,接下來就是新建一個(gè)BaseBottomFragment,將頁面進(jìn)行組裝
public abstract class BaseBottomFragment extends MyFragment implements View.OnClickListener {
    // 將傳過來的LinkedHashMap集合里面的鍵值對(duì)拆分之后,分別存入兩個(gè)ArrayList
    private final ArrayList<BottomTabBean> TAB_BEAN = new ArrayList<>();
    private final ArrayList<BottomItemFragment> ITEM_FRAGMENT = new ArrayList<>();

    // 定義一個(gè)LinkedHashMap接受傳過來的頁面數(shù)據(jù)
    private final LinkedHashMap<BottomTabBean, BottomItemFragment> ITEMS = new LinkedHashMap<>();
    
    // 當(dāng)前顯示fragment的頁面標(biāo)記
    private int mCurrentFragment = 0;
    // 首次加載頁面時(shí)顯示的主頁標(biāo)記 = 0
    private int mIndexFragment = 0;
    
    // 點(diǎn)擊之后按鈕顯示的顏色
    private int mClickColor = Color.RED;
    
    //對(duì)子類提供的設(shè)置的抽象方法
    // 讓子類傳入布局所需要的按鈕和布局
    public abstract LinkedHashMap<BottomTabBean, BottomItemDelegate> setItems(ItemBuilder itemBuilder);
    // 讓子類傳入設(shè)置首次加載的主頁
    public abstract int setIndexDelegate();
    // 讓子類傳入設(shè)置點(diǎn)擊之后按鈕的顏色
    @ColorInt
    public abstract int setClickColor();
    
    @Override
    public Object setLayout() {
        return R.layout.delegate_bottom;
    }
    // ButterKnife綁定特笋,自己去Github上看使用的方法剃浇,我這邊是在Android Library里面使用的,所以是R2文件
    @BindView(R2.id.bottom_bar)
    LinearLayoutCompat mBottomBar = null;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mIndexDelegate = setIndexDelegate();
        if (setClickColor()!=0){
            mClickColor = setClickColor();
        }

        final ItemBuilder builder = ItemBuilder.builder();
        final LinkedHashMap<BottomTabBean, BottomItemDelegate> items = setItems(builder);

        ITEMS.putAll(items);
        // for 循環(huán)取出ITEMS中的鍵值對(duì)的值
        for(Map.Entry<BottomTabBean, BottomItemDelegate> item:ITEMS.entrySet()){
            final BottomTabBean key = item.getKey();
            final BottomItemDelegate value = item.getValue();
            TAB_BEANS.add(key);
            ITEM_DELEGATES.add(value);
        }
    }

    @Override
    public void onBindView(@Nullable Bundle saveInstanceState, View rootView){
        final size = ITEMS.size();
        // for循環(huán)填充底部布局,比較核心的內(nèi)容
        for(int i = 0 ;i < size; i++){
            LayoutInflater.from(getContext()).inflate(R.layout.bottom_item_icon_text_layout, mBottomBar);
            final RelativeLayout item = mBottomBar.getChildAt(i);
            // 設(shè)置tag
            item.setTag(i);
            item.setOnClickListener(this);
            final IconTextView itemIcon = (IconTextView)item.getChildAt(0);
            final AppCompatTextView itemTitle = (AppCompatTextView)item.getChildAt(1);
            final BottomTabBean bean = TAB_BEAN.get(i);
            itemIcon.setText(bean.getICON());
            itemTitle.setText(bean.getTITLE());
            if (i == mIndexFragment){
                itemIcon.setTextColor(mClickColor);
                itemTitle.setTextColor(mClickColor);
            }
        }
        // 將fragments的ArrayList轉(zhuǎn)化為SupportFragment的數(shù)組猎物,框架需要
        final SupportFragment[] fragmentArray = ITEM_FRAGMENTS.toArray(new SupportFragment[size]);
        // Fragmentation提供的設(shè)置方法
        loadMultipleRootFragment(R.id.bottom_bar_delegate_container, mIndexFragment, fragmentArray);
    }

    // 重置按鈕的顏色
    private void resetColor() {
        final int count = mBottomBar.getChildCount();
        for (int i = 0; i < count; i++) {
            final RelativeLayout item = (RelativeLayout) mBottomBar.getChildAt(i);
            final IconTextView itemIcon = (IconTextView) item.getChildAt(0);
            itemIcon.setTextColor(Color.GRAY);
            final AppCompatTextView itemTitle = (AppCompatTextView) item.getChildAt(1);
            itemTitle.setTextColor(Color.GRAY);
        }
    }
    
    // 點(diǎn)擊之后重新導(dǎo)入delegate虎囚,設(shè)置按鈕的顏色
    @Override
    public void onClick(View view) {
        final int tag = (int) view.getTag();
        resetColor();
        final RelativeLayout item = (RelativeLayout) view;
        final IconTextView itemIcon = (IconTextView) item.getChildAt(0);
        itemIcon.setTextColor(mClickColor);
        final AppCompatTextView itemTitle = (AppCompatTextView) item.getChildAt(1);
        itemTitle.setTextColor(mClickColor);
        // Fragmentation提供的方法
        showHideFragment(ITEM_DELEGATES.get(tag), ITEM_DELEGATES.get(mCurrentDelegate));
        mCurrentDelegate = tag;
    }
}

  • 至此,封裝完成蔫磨,底部帶導(dǎo)航欄的多Fragment界面已經(jīng)ok了淘讥,接下來就是新建一個(gè)底部導(dǎo)航欄的實(shí)例,將數(shù)據(jù)填充進(jìn)去就OK了
public class MyBottomFragment extends BaseBottomFragment{
    @Override
    public LinkedHashMap<BottomTabBean, BottomItemFragment> setItems(ItemBuilder itemBuilder) {
        final LinkedHashMap<BottomTabBean, BottomItemFragment> items = new LinkedHashMap<>();
        items.put(new BottomTabBean("{fa-home}","主頁"),new IndexFragment());
        items.put(new BottomTabBean("{fa-sort}","分類"),new SortFragment());
        items.put(new BottomTabBean("{fa-compass}","發(fā)現(xiàn)"),new IndexFragment());
        items.put(new BottomTabBean("{fa-shopping-cart}","購物車"),new IndexFragment());
        items.put(new BottomTabBean("{fa-user}","我的"),new IndexFragment());

        return itemBuilder.addItems(items).build();
    }

    @Override
    public int setIndexDelegate() {
        return 0;
    }

    @Override
    public int setClickColor() {
        return Color.parseColor("#FF0000");
    }
}
  • 最后在單一的Activity中的setRootFragment方法中設(shè)置MyBottomFragment頁面堤如,顯示即可蒲列。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市搀罢,隨后出現(xiàn)的幾起案子蝗岖,更是在濱河造成了極大的恐慌,老刑警劉巖榔至,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抵赢,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡唧取,警方通過查閱死者的電腦和手機(jī)铅鲤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來枫弟,“玉大人邢享,你說我怎么就攤上這事〉” “怎么了骇塘?”我有些...
    開封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)韩容。 經(jīng)常有香客問我绪爸,道長(zhǎng),這世上最難降的妖魔是什么宙攻? 我笑而不...
    開封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮介褥,結(jié)果婚禮上座掘,老公的妹妹穿的比我還像新娘递惋。我一直安慰自己,他們只是感情好溢陪,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開白布萍虽。 她就那樣靜靜地躺著,像睡著了一般形真。 火紅的嫁衣襯著肌膚如雪杉编。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天咆霜,我揣著相機(jī)與錄音邓馒,去河邊找鬼。 笑死蛾坯,一個(gè)胖子當(dāng)著我的面吹牛光酣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播脉课,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼救军,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了倘零?” 一聲冷哼從身側(cè)響起唱遭,我...
    開封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎呈驶,沒想到半個(gè)月后拷泽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俐东,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年跌穗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虏辫。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蚌吸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出砌庄,到底是詐尸還是另有隱情羹唠,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布娄昆,位于F島的核電站佩微,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏萌焰。R本人自食惡果不足惜哺眯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望扒俯。 院中可真熱鬧奶卓,春花似錦一疯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至盏浙,卻和暖如春眉睹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背废膘。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工竹海, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人殖卑。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓站削,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親孵稽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子许起,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,789評(píng)論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件菩鲜、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,065評(píng)論 4 62
  • 我很久不點(diǎn)開留言板园细,看到這個(gè)陌生人,很驚訝接校,這是誰猛频,什么時(shí)候,什么意思蛛勉。點(diǎn)開頭像鹿寻,才看到原來是他。四十多小時(shí)無眠不...
    冷康康閱讀 212評(píng)論 0 1
  • “你好……诽凌?” “……你好毡熏。”沈墨時(shí)回了一句后才朝著聲音方向看去侣诵,是一個(gè)騎著匹馬的天策痢法。 “啊,時(shí)間快到了杜顺,我先走...
    依次天嵐閱讀 363評(píng)論 0 0
  • 諺云:禍從口出。 古往今來,因言壞事者比比皆是提茁。 想做個(gè)會(huì)說好話仗嗦,少說錯(cuò)話的有心人, “三愆”的學(xué)問甘凭,便不可不知。...
    老斯基醬閱讀 218評(píng)論 0 0