在上一篇的博客中,写了Android Design Support Library 该库的前5个常用控件(SnackBar ,TextInputLayout,FloatingActionButton,TabLayout,NavigationView),然后在这一篇博客中,完善后3个常用布局(AppBarLayout,CoordinatorLayout,CollapsingToolBarLayout).
AppBarLayout :
可以简称为炫酷的顶部栏,可以在这个布局中添加一些其他的常用控件(无论是不是Android Design Support Library 该库中的)
举个例子:
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<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" />
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabTextColor="@android:color/white"
app:tabSelectedTextColor="@android:color/holo_red_light"
app:tabGravity="fill" />
</android.support.design.widget.AppBarLayout>
该AppBarLayout 布局中就添加了Toolbar 和 TabLayout 两个Design库中的常用控件,将Toolbar 和TabLayout 按线性竖直排列 绑定到一起,两者中间没有空隙,无缝的连接在一起。
而且AppBarLayout 一般是与CoordinatorLayout,CollapsingToolBarLayout 一起配合使用的。下面来分别介绍一下使得界面漂亮的这两个布局。
CoordinatorLayout:
控件之间相互作用的布局,可以简单理解为 若在CoordinatorLayout 中绑定了一些控件,然后其中的某个控件位置发生了改变,它将会影响到其他控件的位置。 还是举个代码例子比较明显一点。
xml 代码:
<?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: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:fitsSystemWindows="true">
<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" />
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabTextColor="@android:color/white"
app:tabSelectedTextColor="@android:color/holo_red_light"
app:tabGravity="fill" />
</android.support.design.widget.AppBarLayout>
<!--可滑动的布局内容-->
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
该xml 布局文件中 布局是 外面是 CoordinatorLayout 大布局包住,里面是AppBarLayout 和 ViewPager 线性竖直排列。至于为什么要加ViewPager 主要是因为想要更直观的观察效果。
因为我在ViewPager 中添加了两个Fragment,一个Fragment 用来实现ListView效果,而另一个Fragment用来实现RecyclerView 效果。而这两个View都是用来显示数据的(可以是自己定义的数据,也可以解析网上的数据),下面简单讲解一下两者在 CoordinatorLayout (控件之间会相互作用的布局)的效果不同。
效果如下,若是ListView 则在ViewPager中的Fragment往上滑动内容时,则AppBarLayout 中的TabLayout 上的Title栏不会遮挡住Toolbar 。而RecyclerView 则会使TabLayout上的Title栏在往上滑动内容时会遮挡住Toolbar。
原理就是RecyclerView 中实现了内嵌滚动机制,而ListView没有。查看源码
就可以发现。RecyclerView 中实现了NestedScrollingChild 接口(内嵌滚动的接口)
public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild{
}
而ListView 是继承了AbsListView,而AbsListView 中也没有实现NestedScrollingChild 接口,所以ListView 内部没有实现内嵌滚动机制。
public class ListView extends AbsListView{
}
public abstract class AbsListView extends AdapterView<ListAdapter> implements TextWatcher,
ViewTreeObserver.OnGlobalLayoutListener, Filter.FilterListener,
ViewTreeObserver.OnTouchModeChangeListener,
RemoteViewsAdapter.RemoteAdapterConnectionCallback{
}
倘若读者一定要在ListView 中加入内嵌滚动,那么也行,那就是将ListView 和NestedScrollingView 一起配合使用,因为NestedScrollingView 内部实现了NestedScrollingChild 接口.
因为这里用到了 RecyclerView ,那么下面简单介绍一下RecyclerView 的用法吧!
RecyclerView 是Android L版本中新添加的一个用来取代ListView的SDK,它的灵活性与可替代性比listview更好。
RecyclerView 与ListView 相比来说的话,RecyclerView 可以随意更改显示数据的布局效果.
- LinearLayoutManager(线性布局效果)
- GridLayoutManager(网格布局效果)
- StaggeredGridLayoutManager(瀑布流布局效果)
RecyclerView 的使用分两步:
- 写xml 代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
2.java 代码
- 设置RecyclerView的适配器,RecyclerAdapter
- 设置RecyclerView 要显示的布局效果
private RecyclerView recyclerView;
private RecyclerAdapter adapter;
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
adapter = new RecyclerAdapter(getActivity());
adapter.setListener(new RecyclerAdapter.OnItemClickListener() {
//通过实现RecyclerAdapter 中的设计好的回调接口来添加item 项的点击事件
@Override
public void onItemClick(int position) {
Toast.makeText(getActivity(), "item" + position + "click", Toast.LENGTH_SHORT).show();
Intent intent=new Intent();
intent.setClass(getActivity(), CollapsingToolBarActivity.class);
startActivity(intent);
}
});
recyclerView.setAdapter(adapter); //给RecyclerView 设置添加Adapter
然后就是RecyclerAdapter 这个类中的java 代码
public class RecyclerAdapter extends
RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
private static final int[] imgIds = {R.drawable.img1, R.drawable.img2, R.drawable.img3, R.drawable.img4
, R.drawable.img1, R.drawable.img2, R.drawable.img3, R.drawable.img4};
private OnItemClickListener listener;
private Context context;
public void setListener(OnItemClickListener listener) {
this.listener = listener;
}
public RecyclerAdapter(Context context) {
this.context = context;
}
@Override
public RecyclerAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = View.inflate(context, R.layout.card_view, null);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(RecyclerAdapter.MyViewHolder holder, int position) {
holder.name.setText("item" + position);
holder.pic.setImageResource(imgIds[position]);
holder.position = position;
}
@Override
public int getItemCount() {
return imgIds.length;
}
public class MyViewHolder extends RecyclerView.ViewHolder {
ImageView pic;
TextView name;
View.OnClickListener l;
int position;
public MyViewHolder(View itemView) {
super(itemView);
pic = (ImageView) itemView.findViewById(R.id.pic);
name = (TextView) itemView.findViewById(R.id.name);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.onItemClick(position);
}
});
Toast.makeText(context, "onBindViewHolder: " + count++, Toast.LENGTH_SHORT).show();
}
}
private int count;
public interface OnItemClickListener {
//因为RecyclerView 并没有提供OnItemClickListener,但可以通过设置接口,来回调实现效果
void onItemClick(int position);
}
}
CollapsingToolbarLayout:
可以理解为一个强大的FrameLayout (帧布局).
xml代码: 结合AppBarLayout ,CollapsingToolbarLayout控件可以实现当屏幕内容滚动时收缩Toolbar 的效果.
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="160dp">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingAppBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:statusBarScrim="?attr/colorPrimary">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="@drawable/img2"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.6"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
android:popupTheme="@style/ThemeOverlay.AppCompat.Light">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
其中的ImageView 中的
app:layout_collapseMode=”parallax” 意思是当内容滚动时,该ImageView 也可以一起滚动,并实现视察滚动效果.
app:layout_collapseParallaxMultiplier=”0.6” 指的是上面代码实现的滚动前和滚动后效果相差.
java代码:
public class CollapsingToolBarActivity extends AppCompatActivity {
private CollapsingToolbarLayout collapsingAppBar;
private Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_collapsing_tool_bar);
initView();
}
public void initView(){
collapsingAppBar = (CollapsingToolbarLayout) findViewById(R.id.collapsingAppBar);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar=getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
collapsingAppBar.setTitle("Welcome to Android !");
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId()==android.R.id.home){
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}