1.CoordinatorLayout 简介
CoordinatorLayout遵循Material 风格,包含在 support Library中,结合AppbarLayout, CollapsingToolbarLayout等 可 产生各种炫酷的折叠悬浮效果
它作为最上层的View
它作为一个 容器与一个或者多个子View进行交互
2.AppBarLayout
它是继承与LinearLayout的,默认 的 方向 是Vertical,它就是一个继承自LinearLayout的自定义vew而已,它有很多的自定义属性,最常用的就是 滑动属性 app:layout_scrollFlags
AppBarLayout的直接子控件可以设置的属性:layout_scrollFlags(滚动模式)
1.scroll|exitUntilCollapsed: 如果AppBarLayout的直接子控件设置该属性,该子控件可以滚动,向上滚动NestedScrollView出父布局(一般为CoordinatorLayout)时,会折叠到顶端,向下滚动时NestedScrollView必须滚动到最上面的时候才能拉出该布局
2.scroll|enterAlways:只要向下滚动该布局就会显示出来,只要向上滑动该布局就会向上收缩
3.scroll|enterAlwaysCollapsed:向下滚动NestedScrollView到最底端时该布局才会显示出来
4.scroll|snap:表示一个吸附效果,可以确保childView不会滑动停止在中间的状态
5.如果不设置该属性,则该布局不能滑动
AppBarLayout 的这些自定义属性是直接作用在它的直接子view上的,怎么理解了?
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
</android.support.design.widget.AppBarLayout>
就是AppBarLayout作为父容器包裹子view Toolbar,并在Toolbar里面设置滑动属性值 app:layout_scrollFlags="scroll|enterAlways"
当然你也可以设置其它的滑动属性值看看效果
需要注意的是 AppBarLayout又必须作为CoordinatorLayout的直接子View,否则它的大部分功能将不会生效,要想产生滑动效果,则必须把屏幕填充满才可以,所以还需要用到RecyclerView才行,
并且 RecyclerView也有属性需要设置,这样才会有正常的效果
app:layout_behavior="@string/appbar_scrolling_view_behavior"
下面我们就把他们结合起来使用看看效果
布局文件
<android.support.design.widget.CoordinatorLayout
android:id="@+id/main_content"
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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
布局思路
Activity文件
public class CoordinatorLayoutActivity extends AppCompatActivity
{
private ArrayList<String> mData;
private RecyclerView recyclerView;
private NormalAdapter normalAdapter;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_coordinator_layout);
intData();
//如果不设置,则不会出现标题
Toolbar tbAtToolbar = findViewById(R.id.tb_at_toolbar);
//不设置会显示label的属性,也可以在清单文件中进行配置
//tbAtToolbar.setTitle("");
setSupportActionBar(tbAtToolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null)
{
//设置Toolbar home键可点击
actionBar.setDisplayHomeAsUpEnabled(true);
//设置Toolbar home键图标
//actionBar.setHomeAsUpIndicator(R.drawable.ic_drawer_am);
}
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(normalAdapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.toobalr, menu);
return true;
}
private void intData()
{
recyclerView=findViewById(R.id.recyclerView);
mData=new ArrayList<>();
for (int i=0;i<100;i++)
{
mData.add("我是第"+i+"数据");
}
normalAdapter=new NormalAdapter(mData,CoordinatorLayoutActivity.this);
}
}
注意 Toolbar 必须由 AppBarLayout 包裹才会产生滑动效果
当 滑动属性为 app:layout_scrollFlags="scroll|enterAlways"时,可以看到向上滑动 RecyclerView滑动多少距离,Toolbar就会滑动多少距离,向下滑动时,不管RecyclerView的数据是否滑动到第一行,Toolbar都会立马滑动出现
我们把滑动属性改为 scroll|snap 可以看到 RecyclerView滑动多少距离,Toolbar就会滑动多少距离,上下都是一样的
AppBarLayout 继承于LinearLayout 它可以包含任何控件,不仅仅只限于Toolbar
我们修改上面代码,让它包含一个ImageView看看效果,并为其设置滑动属性
app:layout_scrollFlags=“scroll|enterAlways”
注意必须设置滑动属性 不然ImageView它不会滑动的
修改我们的布局文件
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/tb_at_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:visibility="gone"// 隐藏Toolbar
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<TextView
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:gravity="center"
android:text="我是标题"
android:textColor="#FFFFFF" />
</android.support.v7.widget.Toolbar>
<ImageView android:layout_width="match_parent"
android:layout_height="200dp"
android:background="?attr/colorPrimary"
android:scaleType="fitXY"
android:src="@mipmap/tangyan"
app:layout_scrollFlags="scroll|enterAlways"/>
</android.support.design.widget.AppBarLayout>
那如果我们想要实现下面这种效果了?
其实相对于前 一个例子,只是把 摆放RecyclerView 的位置替换成ViewPager而已,为了有页面导航器的效果,再使用 TabLayout而已,而TabLayout 在我们滑动的时候最终会停靠在 最顶部,是因为我们没有设置其layout_scrollFlags,即TabLayout是静态的
贴上全部代码
主 布局文件
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/tb_at_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:visibility="gone"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<TextView
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:gravity="center"
android:text="我是标题"
android:textColor="#FFFFFF" />
</android.support.v7.widget.Toolbar>
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="?attr/colorPrimary"
android:scaleType="fitXY"
android:src="@mipmap/tangyan"
app:layout_scrollFlags="scroll|snap" />
<android.support.design.widget.TabLayout
android:id="@+id/toolbar_tab"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_gravity="bottom"
android:background="#ffffff"
android:fillViewport="false"
app:tabIndicatorColor="@color/colorAccent"
app:tabIndicatorHeight="2.0dp"
app:tabSelectedTextColor="@color/colorAccent"
app:tabTextColor="#151515">
<!--指示器颜色-->
<!-- app:tabIndicatorColor="#0835f8"-->
<!--tab条目中字体颜色-->
<!--app:tabSelectedTextColor="#0835f8"-->
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@mipmap/v5" />
<!--布局选择器-->
<!--android:icon="@drawable/tab_selector"-->
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="头条" />
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="社交" />
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="直播" />
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="嘿嘿" />
</android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/main_vp_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<!--在CoordinatorLayout中只要是能滑动控件的都需要设置layout_behavior-->
<!--app:layout_behavior="@string/appbar_scrolling_view_behavior"-->
</android.support.design.widget.CoordinatorLayout>
Activity
public class CoordinatorLayoutActivity extends AppCompatActivity
{
private ViewPager viewPager;
private TabLayout tabLayout;
private ArrayList<Fragment> fragments = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_coordinator_layout);
intData();
//如果不设置,则不会出现标题
Toolbar tbAtToolbar = findViewById(R.id.tb_at_toolbar);
//不设置会显示label的属性,也可以在清单文件中进行配置
//tbAtToolbar.setTitle("");
setSupportActionBar(tbAtToolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null)
{
//设置Toolbar home键可点击
actionBar.setDisplayHomeAsUpEnabled(true);
//设置Toolbar home键图标
//actionBar.setHomeAsUpIndicator(R.drawable.ic_drawer_am);
}
//相互绑定,这样可以防止图标被替换
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener
(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener
(viewPager));
initFragments();
viewPager.setAdapter(new FragmentsAdapter(getSupportFragmentManager(), fragments));
viewPager.setOffscreenPageLimit(5);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.toobalr, menu);
return true;
}
private void initFragments() {
fragments.add(new MovieFragment());
fragments.add(new MovieFragment());
fragments.add(new MovieFragment());
fragments.add(new MovieFragment());
fragments.add(new MovieFragment());
}
private void intData()
{
tabLayout = findViewById(R.id.toolbar_tab);
viewPager = findViewById(R.id.main_vp_container);
}
}
FragmentsAdapter
public class FragmentsAdapter extends FragmentPagerAdapter
{
private ArrayList<Fragment> fragments;
String[] titles=new String[]{"","头条","社交","直播","约吗"};
public FragmentsAdapter(FragmentManager fm, ArrayList<Fragment> fragments) {
super(fm);
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[position];
}
}
MovieFragment
public class MovieFragment extends Fragment
{
private RecyclerView recyclerView;
private NormalAdapter normalAdapter;
private ArrayList<String> mData;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_rv, container, false);
recyclerView=view.findViewById(R.id.rv_fr_list);
mData=new ArrayList<>();
for (int i=0;i<100;i++)
{
mData.add("我是第"+i+"数据");
}
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
normalAdapter=new NormalAdapter(mData,getActivity());
recyclerView.setAdapter(normalAdapter);
return view;
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/srl_fr_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_fr_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
NormalAdapter
public class NormalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
{
private Context mContext;
private ArrayList<String> mData;
public NormalAdapter(ArrayList<String> mData, Context context)
{
this.mData = mData;
this.mContext = context;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType)
{
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
return new RecyclerViewItemHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position)
{
RecyclerViewItemHolder recyclerViewHolder = (RecyclerViewItemHolder) viewHolder;
recyclerViewHolder.tv_name.setText(mData.get(position));
}
@Override
public int getItemCount()
{
return mData.size();
}
/**
* 正常条目的item的ViewHolder
*/
private class RecyclerViewItemHolder extends RecyclerView.ViewHolder
{
public TextView tv_name;
public RecyclerViewItemHolder(View itemView)
{
super(itemView);
tv_name = itemView.findViewById(R.id.tv_name);
}
}
}