ScrollView反弹效果 仿小米私密短信效果(1)

  • 包含的View

*/

private View mView;

/**

  • 存储正常时的位置

*/

private Rect mRect = new Rect();

/**

  • y坐标

*/

private int y;

private boolean isFirst = true;

public BounceScrollView(Context context, AttributeSet attrs)

{

super(context, attrs);

}

/***

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

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

*/

@Override

protected void onFinishInflate()

{

if (getChildCount() > 0)

mView = getChildAt(0);

super.onFinishInflate();

}

@Override

public boolean onTouchEvent(MotionEvent ev)

{

if (mView != null)

{

commonOnTouch(ev);

}

return super.onTouchEvent(ev);

}

private void commonOnTouch(MotionEvent ev)

{

int action = ev.getAction();

int cy = (int) ev.getY();

switch (action)

{

case MotionEvent.ACTION_DOWN:

break;

/**

  • 跟随手指移动

*/

case MotionEvent.ACTION_MOVE:

int dy = cy - y;

if (isFirst)

{

dy = 0;

isFirst = false;

}

y = cy;

if (isNeedMove())

{

if (mRect.isEmpty())

{

/**

  • 记录移动前的位置

*/

mRect.set(mView.getLeft(), mView.getTop(),

mView.getRight(), mView.getBottom());

}

mView.layout(mView.getLeft(), mView.getTop() + 2 * dy / 3,

mView.getRight(), mView.getBottom() + 2 * dy / 3);

if (shouldCallBack(dy))

{

if (mCallback != null)

{

if(!isCalled)

{

isCalled = true ;

resetPosition();

mCallback.callback();

}

}

}

}

break;

/**

  • 反弹回去

*/

case MotionEvent.ACTION_UP:

if (!mRect.isEmpty())

{

resetPosition();

}

break;

}

}

/**

  • 当从上往下,移动距离达到一半时,回调接口

  • @return

*/

private boolean shouldCallBack(int dy)

{

if (dy > 0 && mView.getTop() > getHeight() / 2)

return true;

return false;

}

private void resetPosition()

{

Animation animation = new TranslateAnimation(0, 0, mView.getTop(),

mRect.top);

animation.setDuration(200);

animation.setFillAfter(true);

mView.startAnimation(animation);

mView.layout(mRect.left, mRect.top, mRect.right, mRect.bottom);

mRect.setEmpty();

isFirst = true;

isCalled = false ;

}

/***

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

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

  • @return

*/

public boolean isNeedMove()

{

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

int scrollY = getScrollY();

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

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

{

return true;

}

return false;

}

public void setCallBack(Callback callback)

{

mCallback = callback;

}

interface Callback

{

void callback();

}

}

主要就是监听onTouchEvent,当MOVE时,ScrollView中的控件跟随手指移动,UP时恢复原来的位置;当达到1/2时,会调用用户设置的回调,细节就自己看代码了。

3、MyListView

package com.example.zhy_bouncescrollview02;

import android.content.Context;

import android.util.AttributeSet;

import android.widget.ListView;

/**

  • 解决ScrollView与ListView的嵌套问题

  • @author zhy

*/

public class MyListView extends ListView

{

public MyListView(Context context, AttributeSet attrs)

{

super(context, attrs);

}

public MyListView(Context context, AttributeSet attrs, int defStyle)

{

super(context, attrs, defStyle);

}

public MyListView(Context context)

{

super(context);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)

{

/**

  • 解决ScrollView与ListView的嵌套问题

*/

int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,

MeasureSpec.AT_MOST);

super.onMeasure(widthMeasureSpec, expandSpec);

}

}

4、主Activity

package com.example.zhy_bouncescrollview02;

import java.util.ArrayList;

import java.util.Arrays;

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.widget.ArrayAdapter;

import android.widget.ListView;

import android.widget.Toast;

import com.example.zhy_bouncescrollview02.BounceScrollView.Callback;

public class MainActivity extends Activity

{

private ListView mListView;

private BounceScrollView mScrollView;

@Override

protected void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mScrollView = (BounceScrollView) findViewById(R.id.id_scrollView);

mScrollView.setCallBack(new Callback()

建议

当我们出去找工作,或者准备找工作的时候,我们一定要想,我面试的目标是什么,我自己的技术栈有哪些,近期能掌握的有哪些,我的哪些短板 ,列出来,有计划的去完成,别看前两天掘金一些大佬在驳来驳去 ,他们的观点是他们的,不要因为他们的观点,膨胀了自己,影响自己的学习节奏。基础很大程度决定你自己技术层次的厚度,你再熟练框架也好,也会比你便宜的,性价比高的替代,很现实的问题但也要有危机意识,当我们年级大了,有哪些亮点,与比我们经历更旺盛的年轻小工程师,竞争。

  • 无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!!!!!!!

  • 准备想说怎么样写简历,想象算了,我觉得,技术就是你最好的简历

  • 我希望每一个努力生活的it工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。

  • 有什么问题想交流,欢迎给我私信,欢迎评论

【附】相关架构及资料

Android高级技术大纲

面试资料整理

内含往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
工程师,竞争。

  • 无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!!!!!!!

  • 准备想说怎么样写简历,想象算了,我觉得,技术就是你最好的简历

  • 我希望每一个努力生活的it工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。

  • 有什么问题想交流,欢迎给我私信,欢迎评论

【附】相关架构及资料

[外链图片转存中…(img-Ty6GgGT6-1715595038370)]

[外链图片转存中…(img-vANV30Vp-1715595038371)]

内含往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值