1.应用栏布局AppBarLayout功能
应用栏布局AppBarLayout其实继承自线性布局LinearLayout,所以它具备了LinearLayout的所有属性与方法,除此之外,应用栏布局的额外功能主要有以下几点:
- 支持响应页面主体的滑动行为,即在页面主体进行上移或者下拉时,AppBarLayout能够捕捉到页面主体的滚动操作。
- 捕捉到滚动操作后,还要通知头部控件(通常是Toolbar),高速头部控件你要怎么滚,是爱咋咋滚,还是满大街滚。
2.顶部导航栏的动态滚动效果具体到实现上步骤
- 在build.gradle中添加几个库的编译支持,包括appcompat-v7库(Toolbar需要)、design库(AppBarLayout需要)、recyclerview库(主页面的RecyclerView需要)。如果你是AndoridX环境,直接依赖 implementation 'com.google.android.material:material:1.0.0-rc01'
- 布局文件的根布局采用CoordinatorLayout,因为design库的动态效果都依赖于该控件;并且该节点要添加命名空间声明xmlns:app="http://schemas.android.com/apk/res-auto"
- 使用AppBarLayout节点包裹Toolbar节点,也就是将Toolbar节点作为AppBarLayout节点的下级节点。
- 给Toolbar节点添加滚动属性app:layout_scrollFlags="scroll|enterAlways",指定工具栏的滚动行为标志。
- 演示界面的页面主体使用RecyclerView控件,并给该控件节点添加行为属性即app:layout_behavior="@string/appbar_scrolling_view_behavior",表示通知AppBarLayout捕捉RecyclerView的滚动操作。
3.AppBarLayout结合RecyclerView的布局文件代码示例
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/abl_title"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/tl_title"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#AAAAFF"
app:layout_scrollFlags="scroll|enterAlways" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
item_collapse.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_item"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="#aaffff"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_seq"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:textColor="#000000"
android:textSize="17sp" />
<TextView
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="8"
android:gravity="center"
android:textColor="#000000"
android:textSize="17sp" />
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private String[] yearArray = {"鼠年", "牛年", "虎年", "兔年", "龙年", "蛇年",
"马年", "羊年", "猴年", "鸡年", "狗年", "猪年","鼠年", "牛年", "虎年", "兔年", "龙年", "蛇年",
"马年", "羊年", "猴年", "鸡年", "狗年", "猪年","鼠年", "牛年", "虎年", "兔年", "龙年", "蛇年",
"马年", "羊年", "猴年", "鸡年", "狗年", "猪年"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 从布局文件中获取名叫tl_title的工具栏
Toolbar tl_title = findViewById(R.id.tl_title);
// 使用tl_title替换系统自带的ActionBar
setSupportActionBar(tl_title);
// 从布局文件中获取名叫rv_main的循环视图
RecyclerView rv_main = findViewById(R.id.rv_main);
// 创建一个垂直方向的线性布局管理器
LinearLayoutManager llm = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
// 设置循环视图的布局管理器
rv_main.setLayoutManager(llm);
// 构建一个十二生肖的线性适配器
RecyclerCollapseAdapter adapter = new RecyclerCollapseAdapter(this, yearArray);
// 给rv_main设置十二生肖线性适配器
rv_main.setAdapter(adapter);
}
}
RecyclerCollapseAdapter.java
public class RecyclerCollapseAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final static String TAG = "RecyclerCollapseAdapter";
private Context mContext; // 声明一个上下文对象
private String[] mTitleArray; // 标题文字数组
public RecyclerCollapseAdapter(Context context, String[] titleArray) {
mContext = context;
mTitleArray = titleArray;
}
// 获取列表项的个数
public int getItemCount() {
return mTitleArray.length;
}
// 创建列表项的视图持有者
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup vg, int viewType) {
// 根据布局文件item_collapse.xml生成视图对象
View v = LayoutInflater.from(mContext).inflate(R.layout.item_collapse, vg, false);
return new TitleHolder(v);
}
// 绑定列表项的视图持有者
public void onBindViewHolder(RecyclerView.ViewHolder vh, final int position) {
TitleHolder holder = (TitleHolder) vh;
holder.tv_seq.setText("" + (position + 1));
holder.tv_title.setText(mTitleArray[position]);
}
// 获取列表项的类型
public int getItemViewType(int position) {
return 0;
}
// 获取列表项的编号
public long getItemId(int position) {
return position;
}
// 定义列表项的视图持有者
public class TitleHolder extends RecyclerView.ViewHolder {
public LinearLayout ll_item; // 声明列表项的线性布局
public TextView tv_seq; // 声明列表项序号的文本视图
public TextView tv_title; // 声明列表项标题的文本视图
public TitleHolder(View v) {
super(v);
ll_item = v.findViewById(R.id.ll_item);
tv_seq = v.findViewById(R.id.tv_seq);
tv_title = v.findViewById(R.id.tv_title);
}
}
}
4.NestedScrollView介绍
NestedScrollView继承自框架布局FrameLayout,其用法与ScrollView相似,例如都必须只能带一个直接子视图、都是允许内部视图上下滚动等等。NestedScrollView多出来的功能,则是跟AppBarLayout配合使用,藉由触发Toolbar的滚动行为,因此可把它当作是兼容了Android 5.0 新特性的增强版ScrollView。