Android View实现滑动的方式

简述

实现View的滑动有三种方式

  1. 通过View本身提供的scrollTo/scrollBy方法实现滑动
  2. 通过动画给View施加平移效果来实现滑动
  3. 通过改变View LayoutParams使得View重新布局从而实现滑动

使用scrollTo/scrollBy

scrollTo:通过传递的参数实现绝对滑动
scrollBy:通过传递的参数实现相对滑动

scrollTo和scrollBy只能改变View内容的位置,而不能改变View所在布局中的位置。


    /**
     * The offset, in pixels, by which the content of this view is scrolled
     * horizontally.
     * Please use {@link View#getScrollX()} and {@link View#setScrollX(int)} instead of
     * accessing these directly.
     * {@hide}
     */
    @ViewDebug.ExportedProperty(category = "scrolling")
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    protected int mScrollX;
    /**
     * The offset, in pixels, by which the content of this view is scrolled
     * vertically.
     * Please use {@link View#getScrollY()} and {@link View#setScrollY(int)} instead of
     * accessing these directly.
     * {@hide}
     */
    @ViewDebug.ExportedProperty(category = "scrolling")
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    protected int mScrollY;
   
  /**
     * Set the scrolled position of your view. This will cause a call to
     * {@link #onScrollChanged(int, int, int, int)} and the view will be
     * invalidated.
     * @param x the x position to scroll to
     * @param y the y position to scroll to
     */
    public void scrollTo(int x, int y) {
        if (mScrollX != x || mScrollY != y) {
            int oldX = mScrollX;
            int oldY = mScrollY;
            mScrollX = x;
            mScrollY = y;
            invalidateParentCaches();
            onScrollChanged(mScrollX, mScrollY, oldX, oldY);
            if (!awakenScrollBars()) {
                postInvalidateOnAnimation();
            }
        }
    }

    /**
     * Move the scrolled position of your view. This will cause a call to
     * {@link #onScrollChanged(int, int, int, int)} and the view will be
     * invalidated.
     * @param x the amount of pixels to scroll by horizontally
     * @param y the amount of pixels to scroll by vertically
     */
    public void scrollBy(int x, int y) {
        scrollTo(mScrollX + x, mScrollY + y);
    }

    /**
     * Return the scrolled left position of this view. This is the left edge of
     * the displayed part of your view. You do not need to draw any pixels
     * farther left, since those are outside of the frame of your view on
     * screen.
     *
     * @return The left edge of the displayed part of your view, in pixels.
     */
    @InspectableProperty
    public final int getScrollX() {
        return mScrollX;
    }

    /**
     * Return the scrolled top position of this view. This is the top edge of
     * the displayed part of your view. You do not need to draw any pixels above
     * it, since those are outside of the frame of your view on screen.
     *
     * @return The top edge of the displayed part of your view, in pixels.
     */
    @InspectableProperty
    public final int getScrollY() {
        return mScrollY;
    }

从源码上看,scrollBy通过调用scrollTo方法,来实现了基于当前位置的相对滑动。
通过getScrollX、 getScrollY分别获取到mScrollX、mScrollY。
mScrollX、mScrollY单位为像素

使用动画

使用动画来移动View,主要操作View的translationX和translationY属性,可以采用属性动画或者平移动画。
属性动画需要Android3.0以上的版本。
动画并不能真正改变View的位置信息(四个顶点和宽高)。因此在一个View移动到新位置后,单击新位置无法触发onClick事件(平移)。
解决方法:两种方法

  1. 使用属性动画代替平移动画;
  2. 可以在新位置预先创建一个和目标View一模一样的View,他们不但外观一样连onClick事件也一样,当目标View完成平移动画后,就把目标View 设置GONE(textView.setVisibility(View.GONE) ),同时预先设置的View显示出来。

android 动画

平移动画

文件名:translate.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true"
    android:zAdjustment="normal">

    <translate
        android:duration="100"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:interpolator="@android:anim/linear_interpolator"
        android:toXDelta="100"
        android:toYDelta="100" />

</set>

fillAfter:作用View动画执行完是否恢复到动画前的状态。
true:View会停留在动画执行完的状态。
false: VIew会恢复到动画前的状态。

代码调用

 AnimationSet animationSet2=(AnimationSet) AnimationUtils.loadAnimation(this, R.anim.translate);
 textView.startAnimation(animationSet2);

属性动画

      ObjectAnimator.ofFloat(textView, "translationX", 0, 100).setDuration(10000).start();

改变布局参数 LayoutParams

    ViewGroup.LayoutParams layoutParams = textView.getLayoutParams();
    layoutParams.width+=100;
    layoutParams.height=100;
    textView.requestLayout();
    //或者 textView.setLayoutParams(layoutParams);

通过改变LayoutParams 的方式区实现View的滑动同样是一种很灵活的方法。不过需要根据实际情况做不同的处理。

总结

scrollTo/scrollBy: 操作简单,适合对View内容的滑动

是View提供的原生方法,其作用是专门用于View的滑动,比较方便地实现滑动效果并不影响内部元素的单击事件。只能滑动View的内容,并不能滑动View本身。

动画:操作简单,主要适用于没有交互的View和实现复杂的动画。

通过动画来实现View的滑动。优点:就是复杂的动画效果必须通过动画才能实现。使用平移动画的话需要注意的是View的单击事件(fillAfter 为true的情况)。

改变布局参数:操作稍微复杂,适用于有交互的View

主要适用有交互性的View.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android RecyclerView 实现滑动悬停是通过使用 ItemDecoration 来实现的。在 RecyclerView滑动悬停需要满足两个条件:一是要有一个能够进行悬停的 View,二是要能够动态地根据 RecyclerView 的滚动来改变悬停 View 的位置。 实现滑动悬停的步骤如下: 1. 首先,我们需要创建一个继承自 RecyclerView.ItemDecoration 的类,例如名为 StickyHeaderDecoration 的类,来实现悬停 View。 2. 在 StickyHeaderDecoration 类中,我们需要重写 getItemOffsets() 方法,该方法会在每次绘制 RecyclerView 的子项时被调用。在该方法中,我们可以根据子项的位置和需要悬停的条件来判断是否需要为该子项添加偏移量,从而实现悬停的效果。 3. 接下来,在 RecyclerView 的 Adapter 类中,我们需要重写两个方法:getItemViewType() 和 onCreateHolder()。 4. 在 getItemViewType() 方法中,我们可以根据当前子项的位置来判断是否需要为该子项设置一种特殊的 ViewType,用于标识悬停 View。例如当子项为要悬停的位置时,我们可以返回一个特定的 ViewType 值。 5. 在 onCreateHolder() 方法中,我们需要根据 ViewType 的不同创建不同的 ViewHolder。例如当 ViewType 为悬停 View 的类型时,我们可以创建一个单独的 ViewHolder 类来确定悬停 View 的样式。 6. 最后,在 RecyclerView 的布局文件中,我们需要将 StickyHeaderDecoration 添加到 RecyclerView 中,并设置它的布局参数。 通过以上步骤,我们就可以实现滑动悬停的效果了。当滚动 RecyclerView 时,悬停 View 会根据 RecyclerView 的滚动位置动态地改变自己的位置,从而实现滑动悬停的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值