首先提下这些控件是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。(下面介绍几种滑动方式,本文参考的其他博客,若想查看详细例子可查看:)
<?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中使用,并添加菜单等!如想详细了解:
该偏文章还讲到了自定义主题、添加菜单、弹出PopupWindow使用方法。以及在标题栏中添加自定义控件,返回键,设置标题,子标题等。
3 tabLayout
关于tabLayout 这篇博客讲的很清楚:
tabLayout 和viewpager联合使用时,图标不显示的问题:可以看看这篇 ;主要原因是在先设定了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设定默认值的问题请查看:
其中有种简单的方法。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;
}
}