android自定义弹性布局,android仿苹果弹性布局

在android开发中,常常会要求IOS应用和android应用的体验一致,所以对应android中开发时,很多控件就需要开发人员自己定义,下面就为大家分享一个仿苹果的弹性滑动ScrollView。

package com.fangpc.widget;

import android.content.Context;

import android.graphics.Rect;

import android.os.Build;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.view.View;

import android.view.animation.TranslateAnimation;

import android.widget.ScrollView;

/**

* ScrollView反弹效果的实现

*/

public class BounceScrollView extends ScrollView {

private View inner;// 孩子View

private float y;// 点击时y坐标

private Rect normal = new Rect();// 矩形(这里只是个形式,只是用于判断是否需要动画.)

private boolean isCount = false;// 是否开始计算

public BounceScrollView(Context context, AttributeSet attrs) {

super(context, attrs);

// 取消滑动到顶部或底部时边缘的黄色或蓝色底纹

if (Build.VERSION.SDK_INT >= 9) {

this.setOverScrollMode(View.OVER_SCROLL_NEVER);

}

}

/***

* 根据 XML 生成视图工作完成.该函数在生成视图的最后调用,在所有子视图添加完之后. 即使子类覆盖了 onFinishInflate

* 方法,也应该调用父类的方法,使该方法得以执行.

*/

@Override

protected void onFinishInflate() {

if (getChildCount() > 0) {

inner = getChildAt(0);

}

}

/***

* 监听touch

*/

@Override

public boolean onTouchEvent(MotionEvent ev) {

if (inner != null) {

commOnTouchEvent(ev);

}

return super.onTouchEvent(ev);

}

/***

* 触摸事件

*

* @param ev

*/

public void commOnTouchEvent(MotionEvent ev) {

int action = ev.getAction();

switch (action) {

case MotionEvent.ACTION_DOWN:

break;

case MotionEvent.ACTION_UP:

// 手指松开.

if (isNeedAnimation()) {

animation();

isCount = false;

}

break;

/***

* 排除出第一次移动计算,因为第一次无法得知y坐标, 在MotionEvent.ACTION_DOWN中获取不到,

* 因为此时是MyScrollView的touch事件传递到到了LIstView的孩子item上面.所以从第二次计算开始.

* 然而我们也要进行初始化,就是第一次移动的时候让滑动距离归0. 之后记录准确了就正常执行.

*/

case MotionEvent.ACTION_MOVE:

final float preY = y;// 按下时的y坐标

float nowY = ev.getY();// 时时y坐标

int deltaY = (int) (preY - nowY);// 滑动距离

if (!isCount) {

deltaY = 0; // 在这里要归0.

}

y = nowY;

// 当滚动到最上或者最下时就不会再滚动,这时移动布局

if (isNeedMove()) {

// 初始化头部矩形

if (normal.isEmpty()) {

// 保存正常的布局位置

normal.set(inner.getLeft(), inner.getTop(), inner.getRight(), inner.getBottom());

}

// Log.e("jj", "矩形:" + inner.getLeft() + "," + inner.getTop()

// + "," + inner.getRight() + "," + inner.getBottom());

// 移动布局

inner.layout(inner.getLeft(), inner.getTop() - deltaY / 2, inner.getRight(), inner.getBottom() - deltaY / 2);

}

isCount = true;

break;

default:

break;

}

}

/***

* 回缩动画

*/

public void animation() {

// 开启移动动画

TranslateAnimation ta = new TranslateAnimation(0, 0, inner.getTop(), normal.top);

ta.setDuration(200);

inner.startAnimation(ta);

// 设置回到正常的布局位置

inner.layout(normal.left, normal.top, normal.right, normal.bottom);

// Log.e("jj", "回归:" + normal.left + "," + normal.top + "," +

// normal.right

// + "," + normal.bottom);

normal.setEmpty();

}

// 是否需要开启动画

public boolean isNeedAnimation() {

return !normal.isEmpty();

}

/***

* 是否需要移动布局 inner.getMeasuredHeight():获取的是控件的总高度

*

* getHeight():获取的是屏幕的高度

*

* @return

*/

public boolean isNeedMove() {

int offset = inner.getMeasuredHeight() - getHeight();

int scrollY = getScrollY();

// Log.e("jj", "scrolly=" + scrollY);

// 0是顶部,后面那个是底部

if (scrollY == 0 || scrollY == offset) {

return true;

}

return false;

}

}

使用说明: 1、直接将BounceScrollView放到*.widget包中 2、在布局文件中直接使用BounceScrollView包裹其他布局

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:fadeScrollbars="false"

android:fadingEdge="none"

android:fadingEdgeLength="0dip"

tools:context=".MainActivity" >

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="#FF0000"

android:orientation="vertical" >

...

值得注意的是:BounceScrollView是直接继承自ScrollView的,那么BounceScrollView也需要遵循ScrollView的约定,它内部只允许有一个子View,所以其他布局需要使用一个ViewGroup来包裹。 另外:还可以给BounceScrollView加上背景,使用:android:background="@drawable/coversation_bg" 例如:coversation_bg.xml还可以实现图片的叠加效果

android:src="@drawable/cover_default_bg"

android:tileMode="repeat" />

android:gravity="top|center"

android:src="@drawable/conversation_bg_logo" />

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值