MaterialDesign系列文章(九)AppBarLayou
这个控件要是讲解的话我真不知道该写点什么,就直接参考依然范特稀西的文章直接实现个简书首页的效果,然后简单的讲一下就好了...
简书首页的效果今天就带大家实现一下这个效果(也算是一个实践吧)!!!
首先分析一下这个页面效果:
- 顶部是一个Banner
- 中间是一个RecycleView实现的列表(横向的那个)
- 一个搜索的条目
- 底部是一个RecycleView实现的列表
主要知识点:(如果你对此知识点了解的话可以掠过这篇文章了):
- app:layout_scrollFlags这个标签的使用;
- app:layout_behavior 这个标签的使用;
实现过程:
1.布局实现
首先是页面的实现过程(这里因为主要是讲MaterialDesign所以这些不是本文讲述的重点,所以贴上代码,兄弟们自己看看就行了,不懂得可以给我留言...)
布局文件
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.hejin.materialdesign.JianShuActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white">
<android.support.v4.view.ViewPager
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="200dp"
app:layout_scrollFlags="scroll"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll"/>
<EditText
android:id="@+id/et_search"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_margin="10dp"
android:background="@drawable/edti_text_shape"
android:gravity="center"
android:hint="搜索简述的内容和朋友"
android:textColor="#334455"/>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_bottom"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
这里主要用到的控件在上面都写了,但是在这里又包含本文的重点,所以这里得着重讲一下
app:layout_scrollFlags="scroll"这个标签得作用
可选内容:
- scroll View会跟随滚动时间一起发生移动(想滚动就必须设置这个)
- enterAlways 当向下移动时,立即显示View(比如Toolbar)。
- exitUntilCollapsed 向上滚动时收缩View,但可以固定Toolbar一直在上面。
- enterAlwaysCollapsed 当你的View已经设置minHeight属性又使用此标志时,你的View只能以最小高度进入,只有当滚动视图到达顶部时才扩大到完整高度。
上面这些内容你们会觉得很晦涩难懂,所以我决定花些时间说明一下
scroll 如果你想让这个控件滚动得话就必须设置得一个属性,比如那上面这个布局来说吧,当你在ViewPager中设置这个属性得时候说明这个控件会随着你得手势进行滑动,否则它不会进行滑动,只有RecycleView能进行滑动(但是我发下一个问题,就是在AppBarLayout中如果第一个控件没有设置这个属性的时候,不管后面的控件是否设置这个属性都会导致后面的控件不能进行滑动,所以这里大家注意一下!!!)
enterAlways 如果你向下滑动的时候,会先把设置这个Flag的控件先跟随滑动显示出来,然后在慢慢显是底部的滑动控件,还是那上面的例子说明下:当你的ViewPager同时设置scroll和enterAlways两个属性的话(用|分割,可以进行多个设置)每次当你向上滑动的时候会先滑动顶部的ViewPager然后在响应底部的RecycleView的滑动事件,但是当你向下滑动的时候,会先把ViewPager滑动出来,然后在响应RecycleView的滑动事件.
enterAlwaysCollapsed ** 这个属性类似于一种折叠效果,这个属性要enterAlways和android:minHeight**一起配合使用才有效果的,还是拿上面的例子说明:当你向上滑动的时候先会在设置minHeight这段区域响应滑动,然后响应RecycleView的滑动,当向下滑动的时候,也是会先响应minHeight的滑动,然后在响应RecyceView的滑动
exitUntilCollapsed 这个属性和上面的类似,也要设置minHeight,还是拿上面的页面举例,当你上滑的是偶ViewPager会先响应滑动事件,但是会停在minHeight的高度,然后RecycleView响应滑动,当你向下滑动的时候RecycleView会先响应滑动,然后ViewPager从minHeight的高度开始响应滑动.说简单了就是屏幕上方会留一块区域.
这里提供几种供你尝试一下看一下效果你就理解了:
- app:layout_scrollFlags="scroll"
- app:layout_scrollFlags="scroll|enterAlways"
- app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
- app:layout_scrollFlags="scroll|exitUntilCollapsed"
基本上就是上面这几种方式,试一下看一下效果就明白了!
app:layout_behavior="@string/appbar_scrolling_view_behavior"至于这个我准备后续单独些一片文章去讲解,这里只要记住只要设置了这个属性的话,会使设置这个属性的控件在AppBarLayout的下面,而不是在它上面(因为CoordinatorLayout是继承ViewGroup的而不是继承LinearLayout的)
2.一些相应的类的实现
适配器(3个):
ViewPager的适配器
lass JianShuVPAdapter extends PagerAdapter {
private Context mContext;
public JianShuVPAdapter(Context context) {
mContext = context;
}
@Override
public int getCount() {
return 5;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView mIv = new ImageView(mContext);
if (position % 2 == 0) {
mIv.setImageResource(R.mipmap.meizhi);
} else {
mIv.setImageResource(R.mipmap.photo);
}
mIv.setScaleType(ImageView.ScaleType.CENTER_CROP);
container.addView(mIv);
return mIv;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
RecycleView的两个适配器
class JianShuTabRVAdapter extends RecyclerView.Adapter<JianShuTabRVAdapter.TabHolder> {
private Context mContext;
private LayoutInflater mInflater;
public JianShuTabRVAdapter(Context context) {
mContext = context;
mInflater = LayoutInflater.from(context);
}
@Override
public TabHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = mInflater.inflate(R.layout.item_jianshu_tab, parent, false);
return new TabHolder(itemView);
}
@Override
public void onBindViewHolder(TabHolder holder, int position) {
switch (position) {
case 0:
holder.mTvBg.setBackgroundResource(R.drawable.label_shape);
holder.mTvBg.setText("小说精选");
break;
case 1:
holder.mTvBg.setBackgroundResource(R.drawable.label_shape2);
holder.mTvBg.setText("摄影游记");
break;
case 2:
holder.mTvBg.setBackgroundResource(R.drawable.label_shape3);
holder.mTvBg.setText("漫画手绘");
break;
case 3:
holder.mTvBg.setBackgroundResource(R.drawable.label_shape4);
holder.mTvBg.setText("签约作者");
break;
default:
holder.mTvBg.setBackgroundResource(R.drawable.label_shape);
holder.mTvBg.setText("你猜我猜");
break;
}
}
@Override
public int getItemCount() {
return 5;
}
class TabHolder extends RecyclerView.ViewHolder {
private TextView mTvBg;
public TabHolder(View itemView) {
super(itemView);
mTvBg = itemView.findViewById(R.id.tv_bg);
}
}
}
class JianShuItemRVAdapter extends RecyclerView.Adapter <JianShuItemRVAdapter.ItemTab>{
private Context mContext;
private LayoutInflater mInflater;
public JianShuItemRVAdapter(Context context) {
mContext = context;
mInflater = LayoutInflater.from(context);
}
@Override
public ItemTab onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = mInflater.inflate(R.layout.item_jianshu,parent,false);
return new ItemTab(itemView);
}
@Override
public void onBindViewHolder(ItemTab holder, int position) {
}
@Override
public int getItemCount() {
return 10;
}
class ItemTab extends RecyclerView.ViewHolder{
public ItemTab(View itemView) {
super(itemView);
}
}
}
主页面
public class JianShuActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_jian_shu);
initViewPager();
initRecycleView();
}
/**
* author : 贺金龙
* create time : 2017/11/7 10:40
* description : 初始化ViewPager
*/
private void initViewPager() {
ViewPager vp = (ViewPager) findViewById(R.id.vp);
vp.setAdapter(new JianShuVPAdapter(this));
}
/**
* author : 贺金龙
* create time : 2017/11/7 10:49
* description : 初始化顶部和底部的RecycleView
*/
private void initRecycleView() {
RecyclerView rvTab = (RecyclerView) findViewById(R.id.rv_tab);
RecyclerView rvItem = (RecyclerView) findViewById(R.id.rv_bottom);
rvTab.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
rvTab.setAdapter(new JianShuTabRVAdapter(this));
rvItem.setLayoutManager(new LinearLayoutManager(this));
rvItem.setAdapter(new JianShuItemRVAdapter(this));
}
}
2017年09月11日补充:
如果ToolBar想要联动得话,必须要嵌套在AppBarLayout中去,否则不会有效果的(其实具体为什么我还真的不知道)!