View中的scrollTo和scrollBy

来源:互联网 发布:淘宝怎么申请换货 编辑:程序博客网 时间:2024/05/17 08:21

声明:本文除Demo外的部分,整理,转载自:http://blog.csdn.net/qinjuning/article/details/7247126

首先 ,我们必须明白在Android View视图是没有边界的,Canvas是没有边界的,只不过我们通过绘制特定的View时对Canvas对象进行了一定的操作,例如 : translate(平移)、clipRect(剪切)等,以便达到我们的对该Canvas对象绘制的要求 ,我们可以将这种无边界的视图称为“视图坐标”-----它不受物理屏幕限制。通常我们所理解的一个Layout布局文件只是该视图的显示区域,超过了这个显示区域将不能显示到父视图的区域中 ,对应的,我们可以将这种有边界的视图称为“布局坐标”------ 父视图给子视图分配的布局(layout)大小。而且, 一个视图的在屏幕的起始坐标位于视图坐标起始处,如下图所示。


黑色框框表示该子视图的布局坐标, 褐色框框表示该子视图的视图坐标--该坐标是无限的,超过了父视图给子视图规定的区域后,不再显示该超出内容。
那么下面的问题就是:如何将我们的视图的任意坐标能显示到该视图的中心坐标上呢? 由于该布局位置是只能显示特定的一块视图内容 ,因此我们需要通过scrollTo()或者scrollBy()方法将我们期望的视图“滚动”至布局坐标上。

在View.java中提供了了如下两个变量以及相应的属性方法去读取滚动值 ,如下: View.java类中:

/**      * The offset, in pixels, by which the content of this view is scrolled      * horizontally.      * {@hide}      */      protected int mScrollX;   //该视图内容相当于视图起始坐标的偏移量   , X轴 方向      /**      * The offset, in pixels, by which the content of this view is scrolled      * vertically.      * {@hide}      */      protected int 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.      */      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.      */      public final int getScrollY() {          return mScrollY;      }  
注意,所谓的“by which the content of this view is scrolled”表示该偏移量只针对于该View中onDraw()方法里的
具体内容实现,而不针对绘制背景图片等 。

提示:下文中提到的当前视图内容是在绘制在布局坐标处的内容。

public void scrollTo(int x, int y)

说明:在当前视图内容偏移至(x , y)坐标处,即显示(可视)区域位于(x , y)坐标处。

 * 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;          //回调onScrollChanged方法          onScrollChanged(mScrollX, mScrollY, oldX, oldY);          if (!awakenScrollBars()) {              invalidate();  //一般都引起重绘          }      }  }  
public void scrollBy(int x, int y):

说明:在当前视图内容继续偏移(x , y)个单位,显示(可视)区域也跟着偏移(x,y)个单位。

/**    * 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    */    // 看出原因了吧 。。 mScrollX 与 mScrollY 代表我们当前偏移的位置 , 在当前位置继续偏移(x ,y)个单位    public void scrollBy(int x, int y) {        scrollTo(mScrollX + x, mScrollY + y);    }  

Demo代码:

public class Activity1 extends Activity {private Button scrollToLeft;private Button scrollToRight;private Button scrollByLeft;private Button scrollByRight;private TextView text;private ImageView img;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_activity1);initViews();}private void initViews() {scrollToLeft = (Button) findViewById(R.id.btn_scroll_left);scrollToRight = (Button) findViewById(R.id.btn_scroll_right);scrollByLeft = (Button) findViewById(R.id.btn_scrollby_left);scrollByRight = (Button) findViewById(R.id.btn_scrollby_right);text = (TextView) findViewById(R.id.text);img = (ImageView) findViewById(R.id.img);scrollToLeft.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {text.scrollTo(100, 0);img.scrollTo(100, 0);}});scrollToRight.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {text.scrollTo(-100, 0);img.scrollTo(-100, 0);}});scrollByLeft.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {text.scrollBy(20, 10);img.scrollBy(20, 10);}});scrollByRight.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {text.scrollBy(-20, -10);img.scrollBy(-20, -10);}});}}
布局:

<LinearLayout 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.scrollerlearn.Activity1" >    <Button         android:id="@+id/btn_scroll_left"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="scrollTo left"        />        <Button         android:id="@+id/btn_scroll_right"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="scrollTo right"        />    <Button         android:id="@+id/btn_scrollby_left"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="scrollBy left"        />        <Button         android:id="@+id/btn_scrollby_right"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="scrollBy right"        />        <TextView        android:id="@+id/text"        android:layout_width="100dp"        android:layout_height="100dp"        android:text="@string/hello_world"        android:background="@android:color/holo_green_dark"         />    <ImageView        android:id="@+id/img"        android:layout_width="100dp"        android:layout_height="100dp"        android:src="@drawable/ic_launcher"         /></LinearLayout>
点击按钮,可以看到对应的位移效果:

 

点击srollTo left,srollTo right,会立即将控件内容移动到指定坐标,  scrollBy left,scrollBy right会在当前位置进行平移,TextView是设置了背景色的,但是只有字体会移动,而背景色不会,因为这个偏移量是针对onDraw方法的具体内容实现的,同样,ImageView的src属性的图片会移动,而背景色不会。

0 0
原创粉丝点击