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; } }