Android中MaterialDesign的使用,以及实现仿网易新闻客户端的UI效果(五)

快过年了,在这给大家拜个早年~~

工厂也没啥事做,也快放假了,这篇就提早发~~

前面几篇已经把主要的UI效果实现了,这篇我们说一下自定义Behavior。

我们先在acticity_main中添加一点东西:

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:background="@color/colorPrimary"
            >

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:textSize="35sp"
                android:text="自定义Behavior"/>

        </LinearLayout>

可以看到,添加了一个LinearLayout和一个TextView,需要注意的是,LInearLayout是CoordinatorLayout的直接子控件。

自定义Behavior,首先我们需要做的是继承CoordinatorLayout.Behavior。接着重写其中的两个方法,分别是 onStartNestedScroll 和 onNestedPreScroll。那么这两个方法具体是干什么用的呢。我们先来看一下具体的代码:

public class MyBottomBehavior extends CoordinatorLayout.Behavior {

    private int totalY;
    private int childHeight;

    @Override
    public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) {
        return (axes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
    }

    @Override
    public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {

        if (totalY > 0 && dy < 0 || totalY < 0 && dy > 0){

            totalY = 0;
            child.animate().cancel();
            return;
        }

        childHeight = child.getHeight();
        totalY += dy;
        if (child.getVisibility() == View.INVISIBLE && totalY < 0 ){

            show(child);

        }else if (child.getVisibility() == View.VISIBLE && totalY > childHeight){

            hide(child);
            Log.v("totalY",totalY+"");

        }

    }

    private void show(final View child) {


        ObjectAnimator animator = ObjectAnimator.ofFloat(child,"translationY",0);
        animator.setDuration(200);
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {

                child.setVisibility(View.VISIBLE);
                super.onAnimationEnd(animation);
            }
        });
        animator.start();
    }

    private void hide(final View child) {


            ObjectAnimator animator = ObjectAnimator.ofFloat(child,"translationY",child.getHeight());
            animator.setDuration(200);
            animator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {

                    child.setVisibility(View.INVISIBLE);
                    super.onAnimationEnd(animation);
                }
            });
            animator.start();


    }
}

我们先来看看上面说到的两个方法:

1.boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View directTargetChild, @NonNull View target, int axes, int type)

看到就蒙了,好多参数,别急,我们先说说这个方法的作用,这个方法返回的是boolean值,当返回值是false的时候就不会触发onNestedPreScroll,反之,当返回值是true时,onNestedPreScroll才会执行。那么,很明显,这个方法,我们可以用来判断滑动的方向,当滑动方向是竖直的时候,我们才返回true。再看代码中,这个方法只有一条语句 就是 return (axes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;

这句代码的意思就是判断滑动方向是否是竖直方向。

2.onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View target, int dx, int dy, @NonNull int[] consumed, int type)

在这个方法中,child代表LinearLayout,dy表示当前竖直方向上的移动距离。需要注意的是。上面这两个方法,会在你滑动的时候不断调用。dy表示的并不是总的滑动距离,而是当前滑动的距离,所以我们需要一个totalY来记录,竖直方向的总滑动距离。注意,dy是有正负的,当我们向上滑(手指向上滑动)的时候dy是正值,反之,则是赋值。那么onNestedPreScroll这个方法中的第一个if判断的意思就很明显了,就是当用户切换方向的时候(用户本来是向上或向下滑动的,突然变了方向,变成向下或者向上滑动。)如果大家觉得难理解,那么,totalY是记录竖直方向滑动距离总数的。假如,我们现在向上滑动,此时dy和totalY都是大于0的(都是正数),突然,我们切换方向,向下滑动,此时totalY因为记录的是总距离,数值较大,并不会立马变成负数。但是dy记录的是一小段的距离,此时的dy是负数。那么,由此我们可以判断用户反方向滑动了。那么在这里,我们把totalY重置,并且把正在执行的动画取消掉。
剩下的,if和else if语句,则判断当前child的显示状态,以及当前的滑动距离(totalY)。来对child进行显示或者隐藏的操作。

3.这里我们只拿一个show方法来说。就是执行一段属性动画。需要注意的是,这里我们需要设置监听,在动画执行完毕的时候,设置child的Visibility。

到这,自定义的Behavior就定义好了。接着,我们要在string.xml中,定义字符串。如下:

<resources>
    <string name="app_name">MaterialDesignDemo</string>
    <string name="user_name">休言半纸无多重</string>
    <string name="show">I wish you all I ever wanted for you, I wish you the best. 我希望你不负我的期望,愿你一切安好。</string>
    <string name="my_bottom_behavior">android.lgt.materialdesigndemo.MyBottomBehavior</string>
</resources>

看最后一个字符串my_bottom_behavior ,有一点,后面需要关联对应的我们定义的Behavior类。

接着,我们在 activity_main 的LinearLayout中加上Behavior属性。如下:

    <LinearLayout
        。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
        app:layout_behavior="@string/my_bottom_behavior"
            >

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:textSize="35sp"
                android:text="自定义Behavior"/>

        </LinearLayout>

ok,这样,我们就完成了。接着我们来看看效果。
图一 这里写图片描述

这里写图片描述

如上,第一张是我们打开显示的界面。第二张,是当我们向上滑动的时候LinearLayout就会隐藏,第三张,当我们向下滑动的时候LinearLayout就会显示出来。

到这,我们的自定义Behavior就搞定了。

本人菜鸟,不对之处,请各路大神指教。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值