Android自定义ScrollView实现上下反弹效果

来源:互联网 发布:软件工程质量 编辑:程序博客网 时间:2024/06/11 13:38

在Android中ScrollView是没有上下反弹效果,IOS中的控件默认是有上下反弹效果。实现上下反弹效果对于用户来说可能体验感觉会更好一些。ScrollView实现上下反弹效果原理很简单,下面先来说一下实现原理,然后在贴代码。

1、首先自定义个CustomerScrollView类,继承ScrollView

2、重写onFinishInflate()方法,该方法会在视图生成后调用,重写该方法的目的是获取ScrollView的子视图

3、监听ScrollView的onTouch事件,在该事件中根据不同的事件去处理不同的事情。

import android.content.Context;import android.graphics.Rect;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.animation.TranslateAnimation;import android.widget.ScrollView;/** *  * 可以上下反弹的ScrollView */public class CustomerScrollView extends ScrollView {    private View inner;    private Rect rect = new Rect();    private float y=0;    private int size=4;//    public CustomerScrollView(Context context) {        super(context, null);        init();    }    public CustomerScrollView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }       /**    * 初始化设置    * 去掉ScrollView的边缘效果    */    private void init()    {        setOverScrollMode(OVER_SCROLL_NEVER);//去掉边缘效果    }    @Override    protected void onFinishInflate() {        super.onFinishInflate();        //获取子布局        if (this.getChildAt(0) != null) {            inner = this.getChildAt(0);        }    }    //监听ScrollView的onTouchEvent事件    @Override    public boolean onTouchEvent(MotionEvent ev) {//如果inner为null,即scrollView没有子视图,直接返回        if (inner == null) {            return super.onTouchEvent(ev);        }//自定义事件处理方法        customerOnTouchEvent(ev);        return super.onTouchEvent(ev);    }    /**     * 自定义触摸事件     *     * @author King     * created at 2016/1/9 11:55     */    private void customerOnTouchEvent(MotionEvent event) {        switch (event.getAction())        {            case MotionEvent.ACTION_DOWN:                //手指按下是记录y的坐标                y=event.getY();                break;            case MotionEvent.ACTION_UP:                //手指抬起的时候计算是否需要回到正常状态                if(isNeedAnimation())                {                    animationToNomal();                }                break;            case MotionEvent.ACTION_MOVE:                //手指一动的时候重新布局View                float nowY=event.getY();                int deltaY=(int)((y-nowY)/size);                y=nowY;                if(isNeedMove())                {                    if(rect.isEmpty())                    {                        rect.set(inner.getLeft(),inner.getTop(),inner.getRight(),inner.getBottom());                        return;                    }                    int yy=inner.getTop()-deltaY;//滑动的偏移量                    inner.layout(inner.getLeft(),yy,inner.getRight(),inner.getBottom()-deltaY);                }                break;        }    }    private boolean isNeedAnimation()    {        return !rect.isEmpty();    }    /**    * 手指抬起后将页面回到原始状态    *     *     */    private void animationToNomal()    {        TranslateAnimation translateAnimation=new TranslateAnimation(0,0,inner.getTop(),rect.top);        translateAnimation.setDuration(200);        inner.startAnimation(translateAnimation);        inner.layout(rect.left, rect.top, rect.right, rect.bottom);        rect.setEmpty();    }    /**    * 是否需要移动    */    public boolean isNeedMove()    {        int offset=inner.getMeasuredHeight()-getHeight();        int scrollY=getScrollY();//getScrollY表示Y轴滚动的距离        int t=getScrollY()+getHeight();//getHeight:获取scrollView的高度        debug("offset="+offset+",scrollY="+scrollY+",inner.getMeasuredHeight()="+inner.getMeasuredHeight()+",getScrollY()+getHeight()="+String.valueOf(t));        debug("getHeight="+getHeight()+",getScrollY()="+getScrollY());        //inner.getMeasuredHeight<=t:判断滚动条是否滚到底部        if(scrollY==0||inner.getMeasuredHeight()<=t)        {            return true;        }        return false;    }    private void debug(String msg)    {        Log.d("CustomerScrollerView","-----------------"+msg);    }}


代码中的注释很详细了,这里就不在赘述了。

在布局页面的布局:


    <com.test.app.widget.CustomerScrollView        android:layout_width="match_parent"        android:layout_height="match_parent"        >        <LinearLayout            android:layout_width="match_parent"            android:layout_height="match_parent"            android:orientation="vertical">            <TextView                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:text="ddddddd" />            <TextView                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:text="ddddddd" />            <TextView                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:text="ddddddd" />            <TextView                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:text="ddddddd" />                  </LinearLayout>    </com.test.app.widget.CustomerScrollView>


在LinearLayout中可以随意的放置组件了。


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 转南京江宁户口怎么办儿童医保 剑与家园鬼服怎么办 花生苗出现虫洞怎么办 被蝎子草扎到手怎么办 被蝎子草蛰了怎么办 螫麻子草扎了怎么办 苹果app没删除干净怎么办 字写的太潦草看不懂怎么办 肝内胆管结石疼怎么办 肝内胆管有结石怎么办 肝里胆管有结石怎么办 被信任的人算计你怎么办 卡罗拉1.8油耗高怎么办 请问09年途锐柴油版怎么办 油电混合没电了怎么办 前向运动精子3%怎么办 精子活力正常精子活率低怎么办? 精子形态正常率低怎么办 前向运动精子20%怎么办 不运动精子率高怎么办 前向运动精子少怎么办 精子前向运动力低怎么办 精子异常形态率高怎么办 精子正常率才1%怎么办 精子头部缺陷率高怎么办 前向运动精子15%怎么办 精子向前运动力低怎么办 前向运动精子10%怎么办 前向运动精子12%怎么办 前向运动精子2%怎么办 正常精子形态只有10%怎么办 精子混合畸形率高怎么办 正常形态精子才2怎么办 精子密度低至0.8怎么办 精子总活动率低怎么办 前向运动精子低怎么办 精子畸形率百分之94怎么办 实验室授权签字人考不过怎么办 万和热水器排污口漏水怎么办 万和热水器水箱漏水怎么办 军训鞋大了怎么办妙招