android scrollto scrollby 扯一扯

废话不多说,直接上思路---

1:试想一个界面,父布局是LinearLayout,竖直方向排列,然后里面添加两个View,如果我点击第一个View,直接调用第二个View的scrollTo或者scrollBy方法,第二个View会移动吗?给出代码和布局文件----

布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              android:background="#00ff00">
    <View
            android:layout_width="200dp"
            android:layout_height="50dp"
            android:id="@+id/button1"
            android:background="#ff0000"/>
    <View
            android:layout_width="200dp"
            android:layout_height="50dp"
            android:id="@+id/button2"
            android:background="#0000ff"/>
</LinearLayout>

分别设置了三种不同的颜色,方便查看效果,接下来是Activity的代码--

public class ActivityText extends Activity implements View.OnClickListener {
	private View button1;
	private View button2;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_text);
		button1 = findViewById(R.id.button1);
		button2 = findViewById(R.id.button2);
		button1.setOnClickListener(this);
	}

	@Override
	public void onClick(View view) {
		if (view.getId() == R.id.button1) {
			//			button2.scrollBy(-30, -30);
			button2.scrollTo(30, 30);
		}
	}
}

由于很简单,这里就不上传简单的例子了,我直接说现象:他妈的第二个View根本就没有动~,根本就没有效果--

我就开始想了,猜测--是不是必须移动移动View的父容器,它里面的孩子才会移动?好,我就进行了下面的第二个实验--

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              android:background="#00ff00"
              android:id="@+id/ll">
    <View
            android:layout_width="200dp"
            android:layout_height="50dp"
            android:id="@+id/button1"
            android:background="#ff0000"/>
    <View
            android:layout_width="200dp"
            android:layout_height="50dp"
            android:id="@+id/button2"
            android:background="#0000ff"/>
</LinearLayout>

大家注意看,这次我在两个View的父容器中添加了一个id,叫做ll,然后在Activity中获得LinearLayout的引用--

public class ActivityText extends Activity implements View.OnClickListener {
	private View button1;
	private View button2;
	private LinearLayout ll;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_text);
		ll = (LinearLayout) findViewById(R.id.ll);
		button1 = findViewById(R.id.button1);
		button2 = findViewById(R.id.button2);
		button1.setOnClickListener(this);
	}

	@Override
	public void onClick(View view) {
		if (view.getId() == R.id.button1) {
			ll.scrollBy(-30, -30);
		}
	}
}

注意看onClick的代码,里面我调用LinearLayout的scrollBy方法,LinearLayout里面的两个View竟然神奇的动起来了,这是为什么呢?不过到现在为止可以确定的是调用ViewGroup的scrollBy或者scrollTo方法,该ViewGroup里面的孩子会动起来。假如直接调用非ViewGroup的View的scrollBy或者scrollTo方法,是一点反应也没有的---那我就纳闷了,是不是ViewGroup里面的源代码在dispatchDraw()方法里面执行了什么特别的操作?

查看ViewGroup的dispatchDraw()方法,发现一些蛛丝马迹----

  int saveCount = 0;
2777        final boolean clipToPadding = (flags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK;
2778        if (clipToPadding) {
2779            saveCount = canvas.save();
2780            canvas.clipRect(mScrollX + mPaddingLeft, mScrollY + mPaddingTop,
2781                    mScrollX + mRight - mLeft - mPaddingRight,
2782                    mScrollY + mBottom - mTop - mPaddingBottom);
2783
2784        }

注意看这几句代码,总感觉是这里的原因--现在明确以下,我们直接调用View(非ViewGroup)的scrollTo或者scrollBy方法是没有效果的,说明单个View的绘制里面并没有对mScrollX和mScrollY这两个变量进行特别的操作--,既然不是View的问题,看上面的源代码,我只能找到是ViewGroup里面的问题了--再说明一点,我们调用scrollTo或者scrollBy方法会对mScrollX和mScrollY这两个变量进行操作--。我从上面的代码得出了一个结论:原来是父容器滚动画布后再绘制自己的孩子,这样就孩子就全部动起来了---,那有人就会问了,要是我不想动全部的孩子,就只是想动第二个View呢?此时你应该想到了办法了,既然是操作孩子的父容器,那么我们只需要在你要移动的View的外面套上一层View就可以了---下面验证以下我们的想法--

布局文件:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              android:background="#00ff00"
              android:id="@+id/ll">
    <View
            android:layout_width="200dp"
            android:layout_height="50dp"
            android:id="@+id/button1"
            android:background="#ff0000"/>
    <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#000000"
            android:id="@+id/fl">
        <View
                android:layout_width="200dp"
                android:layout_height="50dp"
                android:id="@+id/button2"
                android:background="#0000ff"/>
    </FrameLayout>
</LinearLayout>

这一次我在我要移动的View外部套了一个FrameLayout,然后在Activity中得到FrameLayout的引用---

public class ActivityText extends Activity implements View.OnClickListener {
	private View button1;
	private View button2;
	private LinearLayout ll;
	private FrameLayout fl;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_text);
		ll = (LinearLayout) findViewById(R.id.ll);
		fl = (FrameLayout) findViewById(R.id.fl);
		button1 = findViewById(R.id.button1);
		button2 = findViewById(R.id.button2);
		button1.setOnClickListener(this);
	}

	@Override
	public void onClick(View view) {
		if (view.getId() == R.id.button1) {
			fl.scrollBy(-30, -30);
		}
	}
}

这一次在onClick事件里面我调用FrameLayout的scrollBy方法,从而达到了让第二个View移动的目的----

读者可以自己实验以下,看一下效果---

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值