TabLayout+ViewPager+Fragment(懶加載)實現導航欄

之前,實現導航欄的效果有很多方法,使用第三方庫,比如ViewPagerIndicator中的TabPagerIndicator,谷歌可能發現,導航欄使用的挺普遍的,so,也搞了一個屬於自己的導航欄!就像側滑菜單一樣,也搞了一個屬於自己的側滑菜單DrawerLayout!

效果圖是這樣的:

這裏寫圖片描述

跟ViewPagerIndicator實現的效果是一樣的!

接下來看代碼:

首先呢!需要compile一下:

compile 'com.android.support:design:25.3.1'

然後TabLayout就跟普通控件使用一樣了!直接在xml裏設置即可,代碼如下:

<android.support.design.widget.TabLayout
            android:id="@+id/tabLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/white"
            app:tabIndicatorColor="#ff0000"
            app:tabSelectedTextColor="#ff0000"
            app:tabTextColor="#cccccc"
            app:tabMode="scrollable"/>

屬性說明:

app:tabIndicatorColor:指示器那條下劃線的顏色
app:tabTextColor:上面文本顏色
app:tabSelectedTextColor:文本被選中後的顏色
app:tabMode="scrollable" 適用於多文本的滑動

當然,還有一些別的屬性,比如設置指示器下劃線的粗細等等。

接下來就是HomeActivity的代碼:

public class HomeActivity extends FragmentActivity implements View.OnClickListener{
    private ViewPager viewpager;
    private TabLayout layout;
    private DrawerLayout leftMenu;
    private ImageView touxiang;
    private List<String> titles = new ArrayList<>();
    private List<Fragment> fragments = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        initView();
        initData();
        viewpager.setAdapter(new PagerAdapter(getSupportFragmentManager(),titles,fragments));
        layout.setupWithViewPager(viewpager);//將導航欄和viewpager進行關聯
        layout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewpager.setCurrentItem(tab.getPosition());//聯動
            }

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

            }

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

            }
        });
    }

    private void initData() {
        titles.add("推薦");
        titles.add("熱點");
        titles.add("美女");
        titles.add("軍事");
        titles.add("數碼");
        titles.add("體育");
        titles.add("汽車");
        fragments.add(new TuiJianFragment());
        fragments.add(new ReDianFragment());
        fragments.add(new BeautyFragment());
        fragments.add(new JunShiFragment());
        fragments.add(new ShuMaFragment());
        fragments.add(new SportFragment());
        fragments.add(new CarFragment());
    }

    private void initView() {
        viewpager = (ViewPager) findViewById(R.id.viewpager);
        touxiang = (ImageView) findViewById(R.id.touxiang);
        layout = (TabLayout) findViewById(R.id.title);
        leftMenu = (DrawerLayout) findViewById(R.id.left_menu);
        touxiang.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        leftMenu.openDrawer(GravityCompat.START);//打開側滑菜單
    }
}

適配器:

public class PagerAdapter extends FragmentPagerAdapter {
    private List<String> titles;
    private List<Fragment> fragments;

    public PagerAdapter(FragmentManager fm, List<String> titles,List<Fragment> fragments) {
        super(fm);
        this.titles = titles;
        this.fragments = fragments;
    }

    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

    @Override
    public int getCount() {
        return fragments.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return titles.get(position);
    }
}

搞定!
————————————————————————————————————————————————————————————————
更多屬性:

app:tabBackground="color"//整個TabLayout的顏色,這裏不能直接寫RGB,需要@color/xx

app:tabTextAppearance="@android:style/TextAppearance.Holo.Large"//設置文字的外貌大小

app:tabIndicatorHeight="2dp"//設置指示器下劃線粗細,如果設置成0dp,則不顯示指示器

app:tabMode="scrollable"//默認是fixed:固定的,標籤很多時候會被擠壓,不能滑動。

app:tabGravity="center"//居中,如果是fill,則是充滿

默認選中某項這樣設置:

tablayout.getTabAt(position).select();

————————————————————————————————————————————————————
PS:通常遇到這種組合,也需要實現Fragment懶加載,因爲涉及到ViewPager的預加載特性,會預加載當前Fragment的前一個和後一個Fragment的數據。我們要實現的效果就是隻有當點擊該Fragment的時候,再去請求網絡數據,禁用掉ViewPager的預加載特性,這樣就節省很多開銷。
可以讓Fragment繼承如下的BaseFragment:

public abstract class BaseFragment extends Fragment {
    protected boolean isInit;
    protected boolean isReallyLazy;//是否完全懶加載

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(setLayoutResourceID(), container, false);
        init();
        isInit = true;
        isCanLoadData();
        return view;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        isCanLoadData();
    }

    private void isCanLoadData() {
        //isReallyLazy爲true實現完全懶加載,Fragment只會加載一次,再切回來的時候,不會加載,去掉該屬性的話,再切回來的時候會重新加載
        if (getUserVisibleHint() && isInit && !isReallyLazy) {
            getData();
            isReallyLazy = true;
        }
    }

    protected abstract int setLayoutResourceID();

    protected abstract void init();

    protected abstract void getData();

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        isInit = false;
    }
}

這樣就可以將一進入該Fragment加載網絡數據的方法,或者是切換回該Fragment需要刷新數據的方法都放在上面的方法裏了。
————————————————————————————————————————————————————————————
下面再實現一種案例。項目中有時會用到,就是Tab選項添加圖片,可以隨意控制圖片在Tab中的位置。效果圖大概如下:
這裏寫圖片描述
左右滑動,可以改變字體顏色和圖片。
核心代碼:適配器getPageTitle返回null即可,然後增加一個自定義樣式的方法:

public View getTabView(int position) {
        View view = LayoutInflater.from(context).inflate(R.layout.tab_item, null);
        TextView tab_title = view.findViewById(R.id.tab_title);
        tab_title.setText(titles.get(position));
        ImageView img = view.findViewById(R.id.tab_icon);
        if (position == 0) {
            tab_title.setTextColor(Color.RED);
            img.setImageResource(R.drawable.icon_selected);
        }
        if (position == 1) {
            tab_title.setTextColor(Color.GRAY);
            img.setImageResource(R.drawable.flower_unselected);
        }
        if (position == 2) {
            tab_title.setTextColor(Color.GRAY);
            img.setImageResource(R.drawable.coin_unselected);
        }
        return view;
    }

其中的tab_item佈局就是隨便定義文字和圖片的擺放位置。這裏我是將圖片放在文字的右側:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:orientation="horizontal"
        android:gravity="center">
        <TextView
            android:id="@+id/tab_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <ImageView
            android:id="@+id/tab_icon"
            android:layout_width="18dp"
            android:layout_height="18dp"
            android:layout_marginLeft="4dp" />
    </LinearLayout>
</LinearLayout>

最後Activity中進行設置:
在tabLayout.setupWithViewPager(viewPager)之後添加動態Tab內容

for (int i = 0; i < tabLayout.getTabCount(); i++) {
            TabLayout.Tab tab = tabLayout.getTabAt(i);
            tab.setCustomView(pagerAdapter.getTabView(i));
        }

然後TabLayout的滑動監聽,動態改變文字顏色和圖片即可:

tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition());
                View view = tab.getCustomView();
                ((TextView)(view.findViewById(R.id.tab_title))).setTextColor(Color.RED);
                ImageView imageView = view.findViewById(R.id.tab_icon);
                switch (tab.getPosition()){
                    case 0:
                        imageView.setImageResource(R.drawable.icon_selected);
                        break;
                    case 1:
                        imageView.setImageResource(R.drawable.flower_selected);
                        break;
                    case 2:
                        imageView.setImageResource(R.drawable.coin_selected);
                        break;
                }
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                View view = tab.getCustomView();
                ((TextView)(view.findViewById(R.id.tab_title))).setTextColor(Color.GRAY);
                ImageView imageView = view.findViewById(R.id.tab_icon);
                switch (tab.getPosition()){
                    case 0:
                        imageView.setImageResource(R.drawable.icon_unselected);
                        break;
                    case 1:
                        imageView.setImageResource(R.drawable.flower_unselected);
                        break;
                    case 2:
                        imageView.setImageResource(R.drawable.coin_unselected);
                        break;
                }
            }

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

            }
        });
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章