Android自定义控件9----scrollTo/scrollBy实现滑动和直接绘制滑动的对比使用demo测试

效果图:


项目结构:


代码:

MainActivity
package com.example.scrolltest;

import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
/*
	1. 瞬间移动视图的内容: 利用View的scroll方法
		1). scrollBy(int x, int y) : 滑动指定的偏移量(从当前位置瞬间)
			x: x轴上的偏移量, x>0内容向左滑动, x<0内容向右滑动, x=0水平方向不滑动
			y: y轴上的偏移量, y>0内容向上滑动, y<0内容向下滑动, y=0垂直方向不滑动
		2). scrollTo(int x, int y) : 滑动到指定的偏移量(从当前位置瞬间)
			x: 目标位置x轴上的偏移量, x>0移动到原始位置的左侧, x<0移动到原始位置的右侧,x=0移动到水平原始位置,
			y: 目标位置y轴上的偏移量, y>0移动到原始位置的上侧, y<0移动到原始位置的下侧, y=0移动到垂直原始位置
	2. 平滑移动视图的内容: 利用Scoller和View的scroll方法
		1). Scoller是实现View平滑移动的帮助类, 它本身并不能实现对View的移动
		2). 平滑移动的基本原理: 将整个从起始位置到结束位置的移动分解成多个小的距离, 循环调用scrollTo()实现平滑移动
		3). 相关API:
			a. Scoller类:
				-->Scoller(Context context) : 创建对象的构造方法
				-->startScroll(int startX, int startY, int dx, int dy, int duration) : 开始平滑移动视图(这个方法本身不会产生滑动)
					startX : 起始位置的X偏移量
					startY : 起始位置的Y偏移量
					dx: 滑动多大的X偏移量(如果是0,X方向不会滑动)
					dy: 滑动多大的Y偏移量(如果是0,Y方向不会滑动)
					duration : 整个过程持续的时间(ms)
				-->startScroll(int startX, int startY, int dx, int dy): 开始平滑移动视图(时间为250ms)
				-->boolean computeScrollOffset() : 计算当前移动的偏移量, 并将其保存到Scoller对象中, 如果滑动还没有完成返回true
				-->int getCurrX() : 得到计算出的X偏移量
				-->int getCurrY() : 得到计算出的Y偏移量
			b. View类
				-->invalidate() : 强制重绘, 导致draw()-->computeScroll()
					在scoller.startScroll()后必须执行此方法
				-->computeScroll() : 需要重写此方法, 用于计算移动, 此方法在draw()中调用
					调用scoller计算移动偏移量
					调用view对象scrollTo()到计算出的偏移量
					调用View对象invalidate()强制重绘, 导致computeScroll()再次执行
 */
//  对应视频
//  http://www.gulixueyuan.com/course/124/learn#lesson/1910
//  scrollBy的使用
public class MainActivity extends Activity {
    private Button btnScrollLeft;
    private Button btnScrollRight;
    private Button btnScrollUp;
    private Button btnScrollDown;
    private Button btnReset1;
    private Button btnReset2;
    private MyImageView ivMain;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        myOnclick();
    }
    private void myOnclick() {
        btnScrollLeft.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ivMain.scrollBy(10, 0);
                Log.e("TAG", ivMain.getScrollX() + "-");
            }
        });
        btnScrollRight.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ivMain.scrollBy(-10, 0);
                Log.e("TAG", ivMain.getScrollX() + "-");
            }
        });
        btnScrollUp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ivMain.scrollBy(0, 10);
                Log.e("TAG", ivMain.getScrollX() + "-");
            }
        });
        btnScrollDown.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ivMain.scrollBy(0, -10);
                Log.e("TAG", ivMain.getScrollX() + "-");
            }
        });
        btnReset1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ivMain.scrollTo(0, 0);
            }
        });
        btnReset2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ivMain.reset();
            }
        });


    }

    private void initView() {
        btnScrollLeft = (Button)findViewById( R.id.btnScrollLeft );
        btnScrollRight = (Button)findViewById( R.id.btnScrollRight );
        btnScrollUp = (Button)findViewById( R.id.btnScrollUp );
        btnScrollDown = (Button)findViewById( R.id.btnScrollDown );
        btnReset1 = (Button)findViewById(R.id.btnReset1);
        btnReset2 = (Button)findViewById( R.id.btnReset2 );
        ivMain = (MyImageView)findViewById( R.id.ivMain );
    }
}
自动以控件MyImageView
package com.example.scrolltest;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageView;
import android.widget.Scroller;
import android.widget.Toast;

import com.orhanobut.logger.Logger;

public class MyImageView extends ImageView {
//  开始坐标
    private float startX;
	private Scroller scroller;
//	图片宽高
	private int myWidth;
	//  距离左边的距离
	private int slideLeft;
//	画笔
	Paint paint;
//	位图
	Bitmap slidingBitmap;
//	上下文
	Context context;
	public MyImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.context=context;
		scroller = new Scroller(context);
		paint = new Paint();
		//设置抗锯齿,就是图像边缘平滑
		paint.setAntiAlias(true);
//      图片
		slidingBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
//	    设置位图大小
		slidingBitmap = Bitmap.createScaledBitmap(slidingBitmap, 600, 600, true);
	}
	
	public void reset() {
		scroller.startScroll(getScrollX(), getScrollY(), -getScrollX(), -getScrollY(), 1000);
		invalidate();
	}
	
	@Override
	public void computeScroll() {
		if(scroller.computeScrollOffset()) {//滑动还没有完成
			Log.e("TAG", "CurrX="+scroller.getCurrX());
			scrollTo(scroller.getCurrX(), scroller.getCurrY());
			invalidate();
		}
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		myWidth=600;
		Logger.t("111").d("width>>>"+myWidth);
		//      设置宽高
		setMeasuredDimension(600, 600);
	}

	/**
	 * onTouchEvent
	 * 点击事件
	 * 滑动
	 * 触摸都在这里完成
     */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		Log.d("111","onTouchEvent");
		switch (event.getAction()) {
		    case  MotionEvent.ACTION_DOWN:
				startX = event.getX();
				Log.d("111","MotionEvent.ACTION_DOWN");
		        break;
			case MotionEvent.ACTION_MOVE:
//				调用这两个方法,感受两种滑动的不同
				move1(event);
//				move2(event);
				break;
			case MotionEvent.ACTION_UP:
				Log.d("111","MotionEvent.ACTION_UP");
				break;
		}
		return true;
	}

	/**
	 * 使用scrollTo实现滑动
     */
	private void move1(MotionEvent event){
		Log.d("111","MotionEvent.ACTION_MOVE");
		float endX = event.getX();
//		偏移量
		float distanceX = endX- startX;
//		坐标
		int toScrollX= (int) (getScrollX()-distanceX);
		//              设置移动范围
		if(toScrollX<0) {
			toScrollX=0;
		}else if(toScrollX>myWidth) {
			toScrollX=myWidth;
		}
		scrollTo(toScrollX,0);

	}

	/**
	 *绘制实现滑动
     */
	private  void move2(MotionEvent event){
		//              移动一次ACTION_MOVE要执行很多次
		Logger.t("666").d("ACTION_MOVE>>>");
		//2.计算结束值
		float endX = event.getX();
		//3.计算偏移量
		float distanceX = endX - startX;
//                slideLeft = (int) (slideLeft + distanceX);
		slideLeft += distanceX;
		//4.屏蔽非法值
		Logger.t("777").d("distanceX>>>"+distanceX+"endX>>>"+endX+"startX>>>"+startX);
		Logger.t("777").d("距左边的距离>>>"+slideLeft);
		if(slideLeft <0){
			slideLeft = 0;
		}else if(slideLeft>myWidth){
			slideLeft = myWidth;
		}
		//5.刷新,就只重新绘制
		invalidate();
		//6.数据还原(执行了很多周期的初始值向223.11,224.22......)
		startX = event.getX();
	}
	/**
	 * 绘制
	 * @param canvas
	 */
	@Override
	protected void onDraw(Canvas canvas) {
//      super.onDraw(canvas);
//      上面的滑动按钮
		canvas.drawBitmap(slidingBitmap, slideLeft, 0, paint);

	}



}
activity_main.xml中
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/btnScrollLeft"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="左移scrollBy(10, 0)" />

        <Button
            android:id="@+id/btnScrollRight"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="右移scrollBy(-10, 0)" />

        <Button
            android:id="@+id/btnScrollUp"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="上移scrollBy(0, 10)" />

        <Button
            android:id="@+id/btnScrollDown"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="下移scrollBy(0, -10)" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/btnReset1"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="瞬间复位scrollTo(0, 0)" />

        <Button
            android:id="@+id/btnReset2"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="平滑复位View.reset()" />
    </LinearLayout>

    <com.example.scrolltest.MyImageView
        android:id="@+id/ivMain"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:background="#ff0000"
        android:src="@drawable/ic_launcher"
        />

</LinearLayout>
参考视频:
http://www.gulixueyuan.com/course/124/learn#lesson/1910
源码下载:
Myself----scrolltest
http://download.csdn.net/download/zhaihaohao1/10111351



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值