如何在 Android SlidingTab 加入 Icon 圖示

SlidingTab with icon

這篇文章從 [Android] SlidingTab 的使用 延伸而來,在原本的 Tab 中加入圖示(icon)。這裡稍為紀錄修改的內容,可能不是那麼完整。

步驟 1. 修改 TabFragment.java

SlidingTabLayout 有提供一個 setCustomTabView() 方法,可以使用它來自定 Tab view,將它加在 tabs.setViewPager(pager); 前面:
tabs.setCustomTabView(R.layout.tab_title, R.id.txtTabTitle, R.id.imgTabIcon);

修改 getFragments() 方法中的內容:
fragments.add(BookFragment.newInstance("Book", indicatorColor, dividerColor, android.R.drawable.ic_dialog_info));
fragments.add(CookFragment.newInstance("Cook", indicatorColor, dividerColor, android.R.drawable.ic_dialog_map));
fragments.add(FoodFragment.newInstance("Food", indicatorColor, dividerColor, android.R.drawable.ic_dialog_email));
fragments.add(GoodFragment.newInstance("Good", Color.BLUE, dividerColor, android.R.drawable.ic_lock_power_off));
fragments.add(LookFragment.newInstance("Look", Color.CYAN, dividerColor, android.R.drawable.ic_dialog_dialer));
fragments.add(WoodFragment.newInstance("Wood", Color.MAGENTA, dividerColor, android.R.drawable.ic_media_play));
主要是後面多了 icon 的值,這裡直接拿內建的圖示來用。

步驟 2. 新增 tab_title.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/RelativeLayout1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingBottom="8dp"
    android:paddingLeft="16dp"
    android:paddingRight="16dp" >

    <ImageView
        android:id="@+id/imgTabIcon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/txtTabTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/imgTabIcon"
        android:layout_centerHorizontal="true"
        android:text="Tab" />

</RelativeLayout>
可自行修改設計。

步驟 3. 修改 SlidingTabLayout.java

//加入 
private int mTabViewIconId;

//修改
public void setCustomTabView(int layoutResId, int textViewId, int iconViewId) {
        mTabViewLayoutId = layoutResId;
        mTabViewTextViewId = textViewId;
        mTabViewIconId = iconViewId;
    }

//最後在 populateTabStrip() 改成這樣
if (mTabViewLayoutId != 0) {
    // If there is a custom tab view layout id set, try and inflate it
    tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip, false);
    tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
    tabIcon = (ImageView) tabView.findViewById(mTabViewIconId);
}
            
if (tabIcon != null) {
 tabIcon.setImageResource(adapter.getIconResId(i));
}

步驟 4. 修改 TabFragmentPagerAdapter.java

加入
public int getIconResId(int position) {
 return fragments.get(position).getIconResId();
}

步驟 5. 修改 BaseFragment.java

加入
private int iconResId = 0;

public int getIconResId() {
 return iconResId;
}
public void setIconResId(int iconResId) {
 this.iconResId = iconResId;
}

步驟 6. 修改每個頁面的 Fragment

這裡修改 BookFragment.java ,其他的都相同:
public static BookFragment newInstance(String title, int indicatorColor, int dividerColor, int iconResId) {
//略
f.setIconResId(iconResId);
程式碼已經 push 到 GitHub (SlidingTabDemo),執行的結果如下:
本文網址:https://blog.tonycube.com/2015/08/android-slidingtab-with-icon.html
Tony Blog 撰寫,請勿全文複製,轉載時請註明出處及連結,謝謝 😀

12 則留言

  1. 作者已經移除這則留言。

    回覆刪除
  2. 不好意思想請問:
    我在Android Studio 試著練習 但是logcat 會跑出 This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead 的錯誤 能否請您指點我的錯誤 謝謝

    回覆刪除
    回覆
    1. 它已經告訴你怎麼做了,「Do not request Window.FEATURE_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead」
      不要請求 Window.FEATURE_ACTION_BAR 這佪功能,
      還要把 windowActionBar 設定 false
      最後改為使用 Toolbar

      Toolbar 的使用可以參考這篇 http://blog.tonycube.com/2015/06/toolbar-demo-toolbar-actionbar-android-5.html

      刪除
  3. 你好,不好意思想請問一下
    我想在您之前的側選單範例中的分頁加入這個SlidingTab
    語法大概要怎麼修改呢? 請大大做個指點

    回覆刪除
    回覆
    1. 先看這篇
      [Android] Navigation Drawer 轉換到 Toolbar (http://blog.tonycube.com/2015/06/android-navigation-drawer-toolbar.html)
      之後再看這篇 [Android] SlidingTab 的使用 (http://blog.tonycube.com/2015/06/android-slidingtab.html)

      刪除
    2. 您好感謝你的回應! 我這兩天嘗試將兩個範例做整合,測試後開啟app能執行,sliding tab能運作唯獨點了側選單無法展開也沒有出現錯誤訊息所以目前仍找不到錯在哪,想請問出現這種錯誤通常是否是順序上的問題還是哪邊的參數或類似的程式碼功能有重疊到,還請您指教,謝謝

      刪除
    3. 可能要檢查一下 Layout,有可能順序錯了,被前面的View蓋到,它在後面開啟可是看不到。這只是猜測。

      刪除
  4. 您好,想要請問一下有辦法做到選到的tab可以改上面的圖片嗎?
    例如:BOOK 被選到 BOOK的圖片從 i 變成書的 icon

    回覆刪除
    回覆
    1. 沒試過,可能可以從 FragmentPagerAdapter 裡面去得知哪個頁面被選到吧,然後再看看怎麼去換 Tab 上的圖片。

      刪除
    2. 好的,謝謝您,我會去試看看!

      刪除
  5. 你好,我跟著你的範例做了一個程式。
    在一個tab的頁面中,我有一個listView項目,
    我想在按了上面的項目之後,就會使白色的内文部分轉到某個的畫面中。

    我上網查了一些做法,例如beginTransaction 的辦法雖然能夠做到轉換頁面的效果,
    但是搞得連上面的Tabs 都不見了。

    所以我想請問一下,我應該怎麽做才能夠讓白色的部分能夠轉換,
    但又不影響tabs的顯示呢?

    我算是個新手... 請多多指教,謝謝!

    回覆刪除
    回覆
    1. beginTransaction 是用來轉換兩個 Fragment,
      你的listview 是在 tab 這個 fragment,
      當然轉到另一個 fragment 就不見了。
      如果你只是要把 listview 所佔用的部份換成另一個畫面,
      可以在它的上面預先加一個 view,初始化時隱藏,
      等 listview 中的項目被點選時再把內容載入這個 view ,
      然後把它顯示,返回時就再把它隱藏就好了。

      刪除

留言小提醒:
1.回覆時間通常在晚上,如果太忙可能要等幾天。
2.請先瀏覽一下其他人的留言,也許有人問過同樣的問題。
3.程式碼請先將它編碼後再貼上。(線上編碼:http://bit.ly/1DL6yog)
4.文字請加上標點符號及斷行,難以閱讀者恕難回覆。
5.感謝您的留言,您的問題也可能幫助到其他有相同問題的人。