Android开发之Coordinatorlayout控件的内部源码学习
1.先看下运行的效果吧
运行效果一
运行效果二
运行效果三
2.CoordinatorLayout控件能实现两个功能:顶层布局的实现;通过协调调度子布局的形式实现触摸影响布局的形式产生动画效果。
目前网上有很多对CoordinatorLayout控件的介绍,但是都是对其使用介绍,本章内容会对CoordinatorLayout控件的源码进行介绍,有助于大家更详细的学习并应用到实践中。
3.下面给出了Coordinatortablayout控件库文件的代码结构
CoordinatorLayout控件lib库代码结构图
4.下面来看下具体的代码实现了
<1>.java代码文件
LoadHeaderImagesListener.java代码内容(此类是一个接口类,用于监听头部)
public interface LoadHeaderImagesListener {
void loadHeaderImages(ImageView imageView, TabLayout.Tab tab);
}
CoordinatorTabLayout.java代码内容(此类就是CoordinatorTabLayout控件的具体实现)
public class CoordinatorTabLayout extends CoordinatorLayout {
private int[] mImageArray, mColorArray;
private Context mContext;
private Toolbar mToolbar;
private ActionBar mActionbar;
private TabLayout mTabLayout;
private ImageView mImageView;
private CollapsingToolbarLayout mCollapsingToolbarLayout;
private LoadHeaderImagesListener mLoadHeaderImagesListener;
public CoordinatorTabLayout(Context context) {
super(context);
mContext = context;
}
public CoordinatorTabLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
if (!isInEditMode()) {
initView(context);
initWidget(context, attrs);
}
}
public CoordinatorTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
if (!isInEditMode()) {
initView(context);
initWidget(context, attrs);
}
}
private void initView(Context context) {
LayoutInflater.from(context).inflate(R.layout.view_coordinatortablayout, this, true);
initToolbar();
mCollapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsingtoolbarlayout);
mTabLayout = (TabLayout) findViewById(R.id.tabLayout);
mImageView = (ImageView) findViewById(R.id.imageview);
}
private void initWidget(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs
, R.styleable.CoordinatorTabLayout);
TypedValue typedValue = new TypedValue();
mContext.getTheme().resolveAttribute(R.attr.colorPrimary, typedValue, true);
int contentScrimColor = typedArray.getColor(
R.styleable.CoordinatorTabLayout_contentScrim, typedValue.data);
mCollapsingToolbarLayout.setContentScrimColor(contentScrimColor);
int tabIndicatorColor = typedArray.getColor(R.styleable.CoordinatorTabLayout_tabIndicatorColor, Color.WHITE);
mTabLayout.setSelectedTabIndicatorColor(tabIndicatorColor);
int tabTextColor = typedArray.getColor(R.styleable.CoordinatorTabLayout_tabTextColor, Color.WHITE);
mTabLayout.setTabTextColors(ColorStateList.valueOf(tabTextColor));
typedArray.recycle();
}
private void initToolbar() {
mToolbar = (Toolbar) findViewById(R.id.toolbar);
((AppCompatActivity) mContext).setSupportActionBar(mToolbar);
mActionbar = ((AppCompatActivity) mContext).getSupportActionBar();
}
/**
* 设置Toolbar标题
*
* @param title 标题
* @return
*/
public CoordinatorTabLayout setTitle(String title) {
if (mActionbar != null) {
mActionbar.setTitle(title);
}
return this;
}
/**
* 设置Toolbar显示返回按钮及标题
*
* @param canBack 是否返回
* @return
*/
public CoordinatorTabLayout setBackEnable(Boolean canBack) {
if (canBack && mActionbar != null) {
mActionbar.setDisplayHomeAsUpEnabled(true);
mActionbar.setHomeAsUpIndicator(R.drawable.ic_arrow_white_24dp);
}
return this;
}
/**
* 设置每个tab对应的头部图片
*
* @param imageArray 图片数组
* @return
*/
public CoordinatorTabLayout setImageArray(@NonNull int[] imageArray) {
mImageArray = imageArray;
setupTabLayout();
return this;
}
/**
* 设置每个tab对应的头部照片和ContentScrimColor
*
* @param imageArray 图片数组
* @param colorArray ContentScrimColor数组
* @return
*/
public CoordinatorTabLayout setImageArray(@NonNull int[] imageArray, @NonNull int[] colorArray) {
mImageArray = imageArray;
mColorArray = colorArray;
setupTabLayout();
return this;
}
/**
* 设置每个tab对应的ContentScrimColor
*
* @param colorArray 图片数组
* @return
*/
public CoordinatorTabLayout setContentScrimColorArray(@NonNull int[] colorArray) {
mColorArray = colorArray;
return this;
}
private void setupTabLayout() {
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
mImageView.startAnimation(AnimationUtils.loadAnimation(mContext, R.anim.anim_dismiss));
if (mLoadHeaderImagesListener == null) {
if (mImageArray != null) {
mImageView.setImageResource(mImageArray[tab.getPosition()]);
}
} else {
mLoadHeaderImagesListener.loadHeaderImages(mImageView, tab);
}
if (mColorArray != null) {
mCollapsingToolbarLayout.setContentScrimColor(
ContextCompat.getColor(
mContext, mColorArray[tab.getPosition()]));
}
mImageView.setAnimation(AnimationUtils.loadAnimation(mContext, R.anim.anim_show));
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
/**
* 设置与该组件搭配的ViewPager
*
* @param viewPager 与TabLayout结合的ViewPager
* @return
*/
public CoordinatorTabLayout setupWithViewPager(ViewPager viewPager) {
mTabLayout.setupWithViewPager(viewPager);
return this;
}
/**
* 获取该组件中的ActionBar
*/
public ActionBar getActionBar() {
return mActionbar;
}
/**
* 获取该组件中的TabLayout
*/
public TabLayout getTabLayout() {
return mTabLayout;
}
/**
* 获取该组件中的ImageView
*/
public ImageView getImageView() {
return mImageView;
}
/**
* 设置LoadHeaderImagesListener
*
* @param loadHeaderImagesListener 设置LoadHeaderImagesListener
* @return
*/
public CoordinatorTabLayout setLoadHeaderImagesListener(LoadHeaderImagesListener loadHeaderImagesListener) {
mLoadHeaderImagesListener = loadHeaderImagesListener;
setupTabLayout();
return this;
}
}
<2>.CoordinatorLayout控件需要的资源文件的实现
- anim文件夹下的动画效果的资源文件
anim_dismiss.xml资源文件
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="500"
android:fromAlpha="1"
android:interpolator="@android:anim/decelerate_interpolator"
android:toAlpha="0.4" />
</set>
anim_show.xml资源文件的实现
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="200"
android:fromAlpha="0.4"
android:interpolator="@android:anim/decelerate_interpolator"
android:toAlpha="1" />
</set>
- drawable文件夹下的资源文件实现
appbarlayout_elevated.xml资源文件实现
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<objectAnimator android:propertyName="elevation"
android:valueTo="8dp"
android:valueType="floatType"
android:duration="1"/>
</item>
</selector>
ic_arrow_white_24dp.xml资源文件实现
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>
- layout布局文件夹下的布局文件实现
view_coordinatortablayout.xml布局文件实现
<?xml version="1.0" encoding="utf-8"?>
<merge 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:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:stateListAnimator="@drawable/appbarlayout_elevated"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingtoolbarlayout"
android:layout_width="match_parent"
android:layout_height="250dp"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:titleEnabled="false">
<ImageView
android:id="@+id/imageview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="top"
android:minHeight="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:titleMarginTop="15dp" />
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
style="@style/TabLayoutStyle"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</merge>
- values文件夹下的资源文件实现
attrs.xml文件资源实现
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CoordinatorTabLayout">
<attr name="contentScrim" format="color" />
<attr name="tabIndicatorColor" format="color" />
<attr name="tabTextColor" format="color" />
</declare-styleable>
</resources>
styles.xml文件资源实现
<resources>
<style name="TabLayoutStyle" parent="Widget.Design.TabLayout">
<item name="tabTextAppearance">@style/TabTextAppearence</item>
</style>
<style name="TabTextAppearence" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
</style>
</resources>
5.以上是CoordinatorLayout控件的一个详细介绍。具体的上述动画效果需要在Activity中实现,此文就不在做过多的描述了,因为有关CoordinatorLayout控件的应用网上有很多介绍,本文只是把CoordinatorLayout控件的源码实现做了介绍,有助于大家从内部结构上认识CoordinatorLayout控件。有不足的地方请大家多多指正批评。