CoordinatorLayout系列(五)例子

系列文章:
CoordinatorLayout系列(一):Behavior
CoordinatorLayout系列(二)AppBarLayout
CoordinatorLayout系列(三)AppBarLayout之layout_scrollFlags
CoordinatorLayout系列(四)CollapsingToolbarLayout
CoordinatorLayout系列(五)例子

这一篇讲两个例子,实现如下效果;

demo地址:https://github.com/whoami-I/CoordinatorLayoutExample
第一个是ToolBar能跟随手指的上下滑动而产生渐变的效果,而不是默认的动画,默认效果是达到某个阈值之后,就执行一个动画把ToolBar变成绿色。
实现起来也很简单,就是运用AppBarLayout的OnOffsetChangedListener监听,上代码:



        

            

            

        


    

布局一般,就是把ToolBar放进CollapsingToolBarLayout

AppBarLayout.OnOffsetChangedListener listener = new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                // get total height and calc ratio
                int totalHeight = mCollapsingToolbarLayout.getHeight() - mToolBar.getHeight() - ((FrameLayout.LayoutParams) mToolBar.getLayoutParams()).topMargin;
                float ratio = getRatio(-verticalOffset, totalHeight);
                changeToolBar(ratio); //改变toolbar透明度
                changeStatusBar(ratio); //改变状态栏颜色
            }
        };
        // 初始化时,将toolbar设置成透明
        changeToolBar(0);
	private void changeStatusBar(float ratio) {
        int transparent = (int) (255 * ratio);
        int color = 0x008577 | (transparent << 24);
        getWindow().setStatusBarColor(color);
    }
 	private void changeToolBar(float ratio) {
        mToolBar.setAlpha(ratio);
    }
    private float getRatio(int cur, int total) {
        float ratio = 0.0f;
        //这里之所以这样转换,是设置toolbar开始变透明时的阈值,这个阈值为滑动到toolbar下面100像素处,才开始变化
        int offset = 100;
        if (cur >= total - offset) {
            cur = cur - (total - offset);
            total = offset;
            ratio = cur * 1.0f / total;
            ratio = ratio > 1.0f ? 1.0f : ratio;
        }
        return ratio;
    }

添加AppBarLayout滑动监听,然后根据滑动的距离来设置透明度信息,要注意,因为这是我们自定义的效果,因此要先disable系统默认的效果,可以把CollapsingToolBarLayout的scrim都设置成null

app:contentScrim="@null"
app:statusBarScrim="@null"

或者是阈值改为0

app:scrimVisibleHeightTrigger="0dp"

第二个例子也是可以用上面同样的方式实现的,但我们换一种思路,使用自定义Behavior的方法,看看能不能行得通。

首先看布局,因为要使用Behavior,那么CircleImageView肯定是作为CoordinatorLayout的直接子view存在的


    

        
            ......

        
    

    


上面的recyclerview和Toolbar都被我省略掉了
直接上Behavior吧:

public class HeadScaleBehavior extends CoordinatorLayout.Behavior {

    private static String TAG = "HeadScaleBehavior";

    public HeadScaleBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onDependentViewChanged(@NonNull CoordinatorLayout parent, @NonNull ImageView child, @NonNull View dependency) {
        //set position
        int centerY = (int) ((dependency.getBottom() - dependency.getTop() + dependency.getY()) / 2);
        child.setY(centerY - child.getHeight() / 2);

        //set scale and alpha
        float ratio = (-dependency.getY()) / (((AppBarLayout)dependency).getTotalScrollRange());
        child.setScaleX(1.0f - ratio);
        child.setScaleY(1.0f - ratio);
        return true;
    }

    @Override
    public boolean layoutDependsOn(@NonNull CoordinatorLayout parent, @NonNull ImageView child, @NonNull View dependency) {

        return dependency instanceof AppBarLayout;
    }
}

首先确定位置,因为我们的效果是CircleImageView跟随AppBarLayout上下移动的,但是现在的CircleImageView是位于CoordinatorLayout里面的,因此需要知道AppBarLayout的移动距离和位置,移动距离就使用getY()方法获取,然后计算比例的时候,需要知道AppBarLayout总共能够滑动多少距离,使用AppBarLayout.getTotalScrollRange()方法即可。

你可能感兴趣的:(安卓UI)