做一个有反弹效果的ScrollView

先上源码:

package com.yxl.scrowview;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.TranslateAnimation;
import android.widget.ScrollView;

public class FTScrollView1 extends ScrollView {

 public FTScrollView1(Context context) {
  this(context, null);
 }

 public FTScrollView1(Context context, AttributeSet attrs) {
  this(context, null, 0);
 }

 public FTScrollView1(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
  init(context, null, 0);
 }

 private void init(Context context, AttributeSet attrs, int defStyle) {
  
 }

 private float firstY = 0;
 
 private View tv ;
 
 //当加载完XML文件里就会调用这个方法
  @Override
  protected void onFinishInflate() {
   if (getChildCount() > 0) {
    tv = getChildAt(0);

   }
  }
 
  boolean isup = false;
  int endY = 0;
 @Override
 public boolean onTouchEvent(MotionEvent ev) {

  switch (ev.getAction()) {
  case MotionEvent.ACTION_DOWN:
   firstY = ev.getY();
   endY = tv.getBottom();
   break;

  case MotionEvent.ACTION_MOVE:
   float tempY = ev.getY();
   int temp = (int) (firstY - tempY);
   //System.out.println(temp);
   scrollBy((int)ev.getX(), temp);
   firstY = tempY;
   if(isNeedMove()) {
   // System.out.println(temp);
   // System.out.println((tv.getTop()) + ":" + (tv.getBottom()));
    tv.layout(tv.getLeft(), tv.getTop() - temp,
      tv.getRight(), tv.getBottom() - temp);
    isup = true;
    //System.out.println(tv.getY());
   }
  
   return true;
  
   
  case MotionEvent.ACTION_UP:
   if(isup) {
    TranslateAnimation translate = new TranslateAnimation(tv.getX(), tv.getX(), tv.getTop(), 0);
    System.out.println(tv.getTop());
    translate.setDuration(200);
    tv.setAnimation(translate);
    
    tv.layout(tv.getLeft(), 0,
      tv.getRight(), endY);
    
    
    
    isup = false;
   }
   System.out.println(tv.getTop());
   
   break;
  default:
   break;
  }

  return super.onTouchEvent(ev);

 }

 
 public boolean isNeedMove() {

  int offset = tv.getMeasuredHeight() - getHeight();
 
  int scrollY = getScrollY();
  
  if (scrollY == 0 || scrollY == offset) {
   return true;
  }
  return false;
 }
}




源码解释:

1.首先通过protected void onFinishInflate()这个方法获得里面的子View;ScrollView的子View只能是一个;

2、响应触摸事件:

   在OntouchEvent后时 Down后获得最开始的Y坐标;通过Move事件得到 新Y坐标;Scrollby来移动View的位置(这个方法是移动本类里的内容);如果移动的位置等于0或者等于最大值则就不会在变化,那么这个时候就是移动到最上面或者最下面的位置了;要想子View在滑动出一个框 来就得用View.layout()这个方法;在移动的过程中,把这个layout变得更大;当Up事件后,为子View添加一个移动动画;也可以用Scroller;这里用的是TranslateAna;最后在用Layout把子View放回到最初位置(此处有个注意事项:View.layout这个方法即把这个子View给放到哪个位置去,那么放到哪个位置后,哪个位置就是开始坐标了(0,0),但这只是对于Translate而说;而View.layout这个方法的坐标是针对于父窗口的)这里最好是Debug看看坐标




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值