Android App之底部tab導航常用實現方案總結

snzzj 8年前發布 | 20K 次閱讀 安卓開發 Android開發 移動開發

前言:

開發中遇到的大多數APP底部都有tab, 但是其實現方式各有不同,各有各的優點,今天,小生就帶大家總結總結,如有更好的,還望指教...

先看看效果圖

AppBottomTab.gif

先來看看項目的目錄截圖,因為代碼比較稍多了點,截圖的目的是為了貼出的分布代碼看起來更清楚。

AppBottomTab項目目錄.png

說明:

這個目錄相信大家看見就很明白了,關于第一種方式,大多數開發者應該都使用過了,這里就不貼代碼了。下面看FragmentTabHost方式實現的代碼。

frtabhost—>FrTabHostStyleAct.java中的布局代碼

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="

<FrameLayout
    android:id="@+id/realtabcontent"
    android:layout_width="match_parent"
    android:layout_height="0dip"
    android:layout_weight="1" />

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="@android:color/darker_gray" />

    <myapp.com.mjj.appbottomtab.frtabhost.MyFragmentTabHost
        android:id="@+id/mytabhost"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical" />

</FrameLayout>

</LinearLayout></code></pre>

FrTabHostStyleAct.java

public class FrTabHostStyleAct extends AppCompatActivity implements TabHost.OnTabChangeListener, View.OnTouchListener {

private MyFragmentTabHost mTabHost;
private CharSequence mTitle; // tab的底部文字
private String[] mTitles;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_frtabhoststyleact);
    initView();
}

private void initView() {
    mTitle = getResources().getString(R.string.main_tab_name_explore);
    mTitles = getResources().getStringArray(R.array.main_titles_arrays);
    mTabHost = (MyFragmentTabHost) findViewById(R.id.mytabhost);
    mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
    if (android.os.Build.VERSION.SDK_INT > 10) {
        mTabHost.getTabWidget().setShowDividers(0);
    }

    initTabs();

    mTabHost.setCurrentTab(0);
    mTabHost.setOnTabChangedListener(this);
}

private void initTabs() {
    MainTab[] tabs = MainTab.values();
    int size = tabs.length;
    for (int i = 0; i < size; i++) {
        MainTab mainTab = tabs[i];
        TabHost.TabSpec tab = mTabHost.newTabSpec(getString(mainTab.getResName()) + this.toString());
        View indicator = View.inflate(this, R.layout.tab_indicator, null);
        TextView title = (TextView) indicator.findViewById(R.id.tab_title);
        ImageView icon = (ImageView) indicator.findViewById(R.id.iv_user_flow_icon);

        Drawable drawable = this.getResources().getDrawable(mainTab.getResIcon());
        icon.setImageDrawable(drawable);

        title.setText(getString(mainTab.getResName()));
        tab.setIndicator(indicator);
        mTabHost.addTab(tab, mainTab.getClz(), null);
        mTabHost.getTabWidget().getChildAt(i).setOnTouchListener(this);
    }
}

@Override
public void onTabChanged(String s) {
    final int size = mTabHost.getTabWidget().getTabCount();
    for (int i = 0; i < size; i++) {
        View v = mTabHost.getTabWidget().getChildAt(i);
        if (i == mTabHost.getCurrentTab()) {
            v.setSelected(true);
            mTitle = mTitles[i == 3 ? i - 1 : i];
        } else {
            v.setSelected(false);
        }
    }
    supportInvalidateOptionsMenu();
}

@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
    super.onTouchEvent(motionEvent);
    boolean consumed = false;
    if (motionEvent.getAction() == MotionEvent.ACTION_DOWN
            && view.equals(mTabHost.getCurrentTabView())) {
        Fragment currentFragment = getCurrentFragment();
        if (currentFragment != null
                && currentFragment instanceof OnTabReselectListener) {
            OnTabReselectListener listener = (OnTabReselectListener) currentFragment;
            listener.onTabReselect();
            consumed = true;
        }
    }
    return consumed;
}

private Fragment getCurrentFragment() {
    return getSupportFragmentManager().findFragmentByTag(
            mTabHost.getCurrentTabTag());
}

}</code></pre>

frtabhost—>MainTab .java

public enum MainTab {

NEWS(0, R.string.main_tab_name_explore, R.drawable.radio_homepage,
        FirstFragment.class),

TWEET(1, R.string.main_tab_name_tweet, R.drawable.radio_ordersearch,
        SecondFragment.class),

QUICK(2, R.string.main_tab_name_quick, R.drawable.radio_personal,
        ThirdFragment.class),

EXPLORE(3, R.string.main_tab_name_my, R.drawable.radio_my,
        FourthFragment.class);

private int idx;
private int resName;
private int resIcon;
private Class<?> clz;

private MainTab(int idx, int resName, int resIcon, Class<?> clz) {
    this.idx = idx;
    this.resName = resName;
    this.resIcon = resIcon;
    this.clz = clz;
}

public int getIdx() {
    return idx;
}

public void setIdx(int idx) {
    this.idx = idx;
}

public int getResName() {
    return resName;
}

public void setResName(int resName) {
    this.resName = resName;
}

public int getResIcon() {
    return resIcon;
}

public void setResIcon(int resIcon) {
    this.resIcon = resIcon;
}

public Class<?> getClz() {
    return clz;
}

public void setClz(Class<?> clz) {
    this.clz = clz;
}

}</code></pre>

frtabhost—>MyFragmentTabHost .java

public class MyFragmentTabHost extends FragmentTabHost {

private String mCurrentTag;

private String mNoTabChangedTag;

public MyFragmentTabHost(Context context, AttributeSet attrs) {
    super(context, attrs);
}

@Override
public void onTabChanged(String tag) {
    if (tag.equals(mNoTabChangedTag)) {
        setCurrentTabByTag(mCurrentTag);
    } else {
        super.onTabChanged(tag);
        mCurrentTag = tag;
    }
}

public void setNoTabChangedTag(String tag) {
    this.mNoTabChangedTag = tag;
}

}</code></pre>

至此,我們的第二中方式就已經實現了。

下面介紹第三種實現方式,使用TabLayout實現。

tablayout—>TabLayoutStyleAct.java代碼

public class TabLayoutStyleAct extends FragmentActivity {

private TabLayout mTabLayout;
private int[] tabNames = {R.string.main_tab_name_explore, R.string.main_tab_name_tweet, R.string.main_tab_name_quick, R.string.main_tab_name_my};
private int[] tabIcons = {R.drawable.radio_homepage, R.drawable.radio_ordersearch, R.drawable.radio_personal, R.drawable.radio_my};

private FrameLayout container;
private MyFragmentPagerAdaper adapter;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    View view = inflate(this, R.layout.activity_tablayout, null);
    setContentView(view);

    mTabLayout = (TabLayout) findViewById(R.id.tab_tablayout);

    for (int i = 0; i < tabNames.length; i++) {
        View tabView = view.inflate(this, R.layout.tab_indicator, null);
        TextView textView = (TextView) tabView.findViewById(R.id.tab_title);
        textView.setText(tabNames[i]);
        // 利用這種辦法設置圖標是為了解決默認設置圖標和文字出現的距離較大問題
        textView.setCompoundDrawablesWithIntrinsicBounds(0, tabIcons[i], 0, 0);
        mTabLayout.addTab(mTabLayout.newTab().setCustomView(textView));
    }

    container = (FrameLayout) findViewById(R.id.fl_contains);
    adapter = new MyFragmentPagerAdaper(getSupportFragmentManager());

    // 初始化默認顯示的fragment
    Fragment fragment = (Fragment) adapter.instantiateItem(container, 0);
    adapter.setPrimaryItem(container, 0, fragment);
    adapter.finishUpdate(container);
    adapter.destroyItem(container, 0, fragment);

    // Tablayout選擇tab監聽
    mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            int position = mTabLayout.getSelectedTabPosition();//tab.getPosition();
            Fragment fragment = (Fragment) adapter.instantiateItem(container, position);
            adapter.setPrimaryItem(container, position, fragment);
            adapter.finishUpdate(container);
            adapter.destroyItem(container, position, fragment);
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });
}

}</code></pre>

說明: 如果會使用TabLayout的朋友知道,一般我們會將TabLayout結合fragment使用時,不是TabLayout在底部的。這里就把TabLayou巧用了,放在了APP的底部,作為切換tab使用,很靈活。

不知道大家有沒有注意到,現在實現的這個有沒有很眼熟呢?

AppBottomTab項目底部截圖.png

沒錯,就是我們的簡書底部tab,關于APP底部tab添加item會在我的個人微信公眾號上面發出,還沒有關注的朋友,不放關注一下,歡迎隨時溝通。

 

 

 

來自:http://www.jianshu.com/p/a691f39e70d3

 

 本文由用戶 snzzj 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!