View的滑动

scrollBy与scrollTo

在view中都有scrollBy和scrollTo的两个方法,所以所有的view控件都是可以实现滚动的,

 /**
     * 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);
    }
scrollBy是让当前的这个View在当前的位置上向某个方向移动(基于当前位置向某个方向移动多少),而scrollTo是移动到一个确切的目的地


这里涉及两个变量mScrollX和mScrollY,mScrollX的意思就是view的内容的左边缘与view的左边缘的水平距离,单位为px,而mScrollY就是view内容的上边缘与View的上边缘的距离


可以通过getScrollX 和getScrollY得到,默认是0

这里说的View的滑动,指的是view内容的滑动,view的位置是不会改变的

看例子:

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {

    private Button mScrollTo;
    private Button mScrollBy;
    private LinearLayout root;

    private static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mScrollTo = (Button) this.findViewById(R.id.scrollToBut);
        mScrollBy = (Button) this.findViewById(R.id.scrollByBut);
        root = (LinearLayout) this.findViewById(R.id.root);

        mScrollBy.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                root.scrollBy(-60, -100);
            }
        });

        mScrollTo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                root.scrollTo(-60, -100);
            }
        });


    }
}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:id="@+id/root"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.jinxiong.scroller1.MainActivity">

    <Button
        android:id="@+id/scrollToBut"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="scrollToBut"
        />

    <Button
        android:id="@+id/scrollByBut"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="scrollByBut"/>
</LinearLayout>


这里涉及到一个就是它滑动的方向问题,跟view的位置坐标相反

(view的位置坐标)

而它滑动的方向刚刚相反,上图中的+变为-

使用动画

使用动画滑动view 实际上改变的是view 的translationX 和translationY的值,可以使用view动画(补间动画),还可以使用属性动画

 super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final TextView textView = (TextView) this.findViewById(R.id.textView);

        textView.startAnimation(AnimationUtils.loadAnimation(this, R.anim.test));

//        TranslateAnimation animation = new TranslateAnimation(0, 0, 0, 100);
//        animation.setDuration(5000);
//        textView.startAnimation(animation);
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "click" + textView.getTranslationY(), Toast.LENGTH_SHORT).show();
            }
        });
//        ObjectAnimator.ofFloat(textView, "translationY", 0, 100).start();

    }
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:duration="5000"
    >
    <translate
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="0"
        android:toYDelta="100"/>
</set>


如果想要动画停止之后留在动画的最后一个位置的话
     android:fillAfter="true"
把这个设为true,其实补间(view)动画并没有真正的改变这个view的布局,也就是说这个view的真正位置还是在动画开始那个地方,view动画操作的是这个view的影像

上面为列子,当你加上fillAfter = true 之后,动画结束之后你点击你所看到的textView的位置,是不会有Toast出现的,当你点击textView的最开始的地方,就会有Toast出现

Toast显示这个view的translationX和Y是为0,所以并没有改变view的真正布局


当然你可以是有属性动画,

ObjectAnimator.ofFloat(textView, "translationY", 0, 100).start();
这个就可以解决这个问题,因为这个属性动画是通过改变view的translationX和Y的值的


改变布局的参数

就是改变LayoutParams的值,比如书我想把view向左移动100px 那么就可以使marginLeft + 100

 super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final TextView textView = (TextView) this.findViewById(R.id.textView);

        final ViewGroup.MarginLayoutParams marginLayoutParams = (ViewGroup.MarginLayoutParams) textView.getLayoutParams();
        
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "click" + textView.getTranslationY(), Toast.LENGTH_SHORT).show();
                marginLayoutParams.leftMargin += 100;
                textView.requestLayout();
            }
        });
    }
比较

scrollTo/scrollBy:

方便的实现滑动的效果,不会影响view内部元素的点击事件,缺点:它只是滑动view的内容,而并非滑动view本身

动画

view动画的缺点是不是真正的去改变view的布局,属性动画就没有这个缺点,实际使用中,动画适用在那些不需要交互的view上面比较好,并且比较炫酷的效果都是动画实现的

改变布局参数

使用稍微麻烦,没什么了,常用在那些需要交互的view上面


下面有个例子,可以拖动整个view,在屏幕上随意滑动



 super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RelativeLayout relativeLayout = (RelativeLayout) this.findViewById(R.id.root);


        relativeLayout.setOnTouchListener(new View.OnTouchListener() {
            int mLastX;
            int mLastY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN: {
                        mLastX = (int) event.getRawX();
                        mLastY = (int) event.getRawY();
                        break;
                    }
                    case MotionEvent.ACTION_UP: {
                        int x = (int) event.getRawX();
                        int y = (int) event.getRawY();
                        v.setTranslationX(v.getTranslationX() + x - mLastX);
                        v.setTranslationY(v.getTranslationY() + y - mLastY);
                        break;
                    }
                }
                return true;
            }
        });

通过平移这个view 达到这个效果







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值