AppBarLayout、Toolbar、TabLayout

  首先提下这些控件是android 5.0后引入的包:​ Android Design Support Library 其实就是一个AAR包,里面包含了navigation drawer view, TextInputEditText,FloatingActionButton, Snackbar, TabLayout, CoordinatorLayout 等,要想使用得像前面介绍CoordinatorLayout所说的那样在gradle里引入:compile 'com.android.support:design:23.3.0'

1、AppBarLayout  

​   AppBarLayout 继承自LinearLayout,子控件默认为竖直方向显示,可以用它实现Material Design 的Toolbar;它支持滑动手势;它的子控件可以通过在代码里调用setScrollFlags(int)或者在XML里app:layout_scrollFlags来设置它的滑动手势。当然实现这些的前提是它的根布局必须是 CoordinatorLayout。这里的滑动手势可以理解为:当某个可滚动View的滚动手势发生变化时,AppBarLayout内部的子View实现某种动作。

​ AppBarLayout的子控件不仅仅可以设置为Toolbar,也可以包含其他的View。(下面介绍几种滑动方式,本文参考的其他博客,若想查看详细例子可查看:http://blog.csdn.net/litengit/article/details/52948574

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    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.support.design.widget.AppBarLayout
        android:id="@+id/appbar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            app:title="标题"
            app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"/>
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="10dp"
            android:minHeight="?android:attr/actionBarSize"
            android:background="@android:color/holo_red_light"
            app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
            />
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/nested_scrollview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        >
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="zpzpzpz“ />
  </android.support.v4.widget.NestedScrollView> </android.support.design.widget.CoordinatorLayout>

  Toolbar上添加了一个app:layout_scrollFlags ,并为该属性设置不同的值就会有不同的效果:

  • scroll:设置这个flag之后 Toolbar会滚出屏幕外部,如果不设置这个Toolbar 会固定在顶部不动。

  • enterAlways:这个flag跟scroll一块使用时,向上滑动时ToolBar移出屏幕,我们向下滑动时Toolbar进入屏幕。scroll|enterAlways这个的效果。

  • enterAlwaysCollapsed:enterAlways的附加值。这里涉及到Child View的高度和最小高度。下滑时候首先下滑动最小距离(补充的背景色)+AppBarLayout的内容,再才会滑动下面的nestedScrollView内的控件。

  • exitUntilCollapsed:这个跟上面的enterAlwaysCollapsed相反;它也涉及到minHeight,当发生向上滚动事件时,AppLayout向上滚动,直到我们设置的minHeight,然后我们的滑动View才开始滚动。就算我们滑动的view完全上滑完毕,我们的AppBarLayout也会一直保留我们设置的民Height显示在屏幕的上方

  • snap:与scroll一起使用时,我们只需要滑动一小段距离,AppBarLayout就会随着我们滑动的View向上滑出屏幕。AppBarLayout会跟随着我们滑动View的滑动,当AppBarLayout滑出屏幕的部分大于显示区域,我们松开手指,AppBarLayout就会自动滑出屏幕;当AppBarLayout滑出屏幕的部分小于显示区域,我们松开手指,AppBarLayout就会自动滑进屏幕。

下面给出动态效果图:

2 toolbar

它主要是在AppBar中使用,并添加菜单等!如想详细了解:http://blog.csdn.net/mchenys/article/details/51533689

该偏文章还讲到了自定义主题添加菜单弹出PopupWindow使用方法。以及在标题栏中添加自定义控件,返回键,设置标题,子标题等。

3 tabLayout

关于tabLayout 这篇博客讲的很清楚:http://blog.csdn.net/mchenys/article/details/51531760

tabLayout 和viewpager联合使用时,图标不显示的问题:可以看看这篇 http://blog.csdn.net/sundy_tu/article/details/52682246;主要原因是在先设定了tab后,在setupWithViewPager内部调用setPagerAdapter 然后setPagerAdapter内部调用populateFromPagerAdapter,该方法内部一开始就removeAllTabs();移除了设定的标签,好让viewpagerAdapter与标签一一对应。

因此,我们tabLayout 和viewpager联合使用时,一般不先设定tab,当我们实现了adpater的时候,在设置标签和图标

  1、一般是初始化viewList或者标签对应的fragment

  2、再实现viewPager的adapter ,在实现adapter时候public CharSequence getPageTitle(int position)会默认为每个pager设定一个空的tab 重写的时候返回字符串则会赋值字符串的tab.

  3、设定相关

  4、获得每个标签,然后设定它的view或者相应的layout布局文件获得view。 使用mTabLayout.getTabAt(i).setCustomView(tabView);

若想了解关于tabLayout设定默认值的问题请查看:http://blog.csdn.net/aigestudio/article/details/47155769

其中有种简单的方法。mTabLayout.getTabAt(2).select(); 该方法就是设定默认的标签值为2;

下面给出我的demo:2种adapter来实现的:第一种是FramentPagerAdapter,第二种则是直接实现 PagerAdapter,其中注意的地方见注视

public class MainActivity extends AppCompatActivity {


    String[] mTitle = new String[20];
    String[] mData = new String[20];
    TabLayout mTabLayout;
    ViewPager mViewPager;
    View []myViewList = new View[20];
    private int startPosition = 2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tablayout);
        mTabLayout = (TabLayout) findViewById(R.id.tl_tab);
        mViewPager = (ViewPager) findViewById(R.id.vp_pager);
        initData();
        mViewPager.setAdapter(new MyFramentPagerAdapter()) ;
        //将ViewPager关联到TabLayout上
        mTabLayout.setupWithViewPager(mViewPager);//一旦与viewpager联合了就会设定 MyFramentPagerAdapter 的pager的title为标签

        setTabOnTabSelectedListener();
        addIcon();
        mTabLayout.getTabAt(2).select();

        //第二种方式
//        mTabLayout = (TabLayout) findViewById(R.id.tl_tab);
//        mViewPager = (ViewPager) findViewById(R.id.vp_pager);
//        initView();
//        initData();
//        mViewPager.setAdapter(new MyViewpagerAdapter());
//        //将ViewPager关联到TabLayout上
//
//        mTabLayout.setupWithViewPager(mViewPager);//一旦与viewpager联合了就会设定 MyFramentPagerAdapter 的pager的title为标签
//        setTabOnTabSelectedListener();
//        addIcon();

    }

    private void initData() {
        for (int i = 0; i < 20; i++) {
            mTitle[i] = "wc" + (i + 1);
            mData[i] = "当前选中的是第" + (i + 1) + "Fragment";
        }
    }
    private void addIcon()
    {
        for (int i = 0; i < 20; i++) {
            //1.支持添加字符串文本tab
            //tabLayout.addTab(tabLayout.newTab().setText("TAB" + i));

            //2.支持添加图片tab
            //tabLayout.addTab(tabLayout.newTab().setIcon(R.mipmap.ic_launcher));

            //3.支持添加View
            View tabView = View.inflate(MainActivity.this, R.layout.tab_item, null);
            ((TextView)tabView.findViewById(R.id.tx)).setText("TAB" + i);
            mTabLayout.getTabAt(i).setCustomView(tabView);
//            mTabLayout.addTab(mTabLayout.newTab().setCustomView(tabView));
        }
    }

    private void setTabOnTabSelectedListener() {
//        设置监听,注意:如果设置了setOnTabSelectedListener,则setupWithViewPager不会生效
//        因为setupWithViewPager内部也是通过设置该监听来触发ViewPager的切换的.
//        那我们如果真的需要监听tab的点击或者ViewPager的切换,则需要手动配置ViewPager的切换,例如:
        mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {

            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                //切换ViewPager
                mViewPager.setCurrentItem(tab.getPosition());
                //将默认位置选中为false
            }

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

            }

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

            }
        });
    }

    class MyFramentPagerAdapter extends FragmentPagerAdapter
    {

        public MyFramentPagerAdapter() {
            super(getSupportFragmentManager());
        }
        @Override
        public Fragment getItem(int position) {
            TabFragment fragment = new TabFragment();
            fragment.setTitle(mData[position % mTitle.length]);
            return fragment;
        }

        @Override
        public int getCount() {
            return mTitle.length;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return mTitle[position % mTitle.length];
        }
    }

    class MyViewpagerAdapter extends PagerAdapter
    {

        @Override
        public int getCount() {
            return mTitle.length;
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            ImageView imageView = new ImageView(MainActivity.this);
            imageView.setBackgroundResource(R.mipmap.ic_launcher);
            container.addView(imageView);
            return imageView;
        }

        //先没覆写这个方法滑动viewpager几次就报错了,不清楚原因
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View)object);
        }

    }

}

TabFrament.java

public class TabFragment extends Fragment {

    private String mTitle;

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        TextView textView = new TextView(getContext());
        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP,30);
        textView.setGravity(Gravity.CENTER);
        textView.setText(mTitle);
        return textView;
    }


}
原文地址:https://www.cnblogs.com/bokeofzp/p/6813341.html