android scrollto scrollby 扯一扯

来源:互联网 发布:矩阵的n次方怎么求 编辑:程序博客网 时间:2024/06/05 09:38

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

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;@Overrideprotected 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);}@Overridepublic 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;@Overrideprotected 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);}@Overridepublic 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);27832784        }

注意看这几句代码,总感觉是这里的原因--现在明确以下,我们直接调用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;@Overrideprotected 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);}@Overridepublic void onClick(View view) {if (view.getId() == R.id.button1) {fl.scrollBy(-30, -30);}}}

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

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

1 0
原创粉丝点击