原文地址:http://blog.csdn.net/a105865708/article/details/17959459

上一次我们试验了有弹性的ScrollView。详情

这一次,我们来试验有弹性的ScrollView。

国际惯例,效果图:

主要代码:

  

 import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.AbsListView;
import android.widget.ListView; /**
* ElasticScrollView有弹性的ListView
*/
public class ElasticListView extends ListView {
private float y;
private Rect normal = new Rect();
private boolean animationFinish = true; public ElasticListView(Context context) {
super(context);
init();
} public ElasticListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
} protected void onScrollChanged(int l, int t, int oldl, int oldt) { } boolean overScrolled = false;
private void init() {
setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
} @Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
overScrolled = false;
}
});
} @Override
protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
overScrolled = true;
} @Override
public boolean onTouchEvent(MotionEvent ev) {
commOnTouchEvent(ev);
return super.onTouchEvent(ev);
} public void commOnTouchEvent(MotionEvent ev) {
if (animationFinish) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
y = ev.getY();
break;
case MotionEvent.ACTION_UP:
y = 0;
if (isNeedAnimation()) {
animation();
}
break;
case MotionEvent.ACTION_MOVE:
final float preY = y == 0 ? ev.getY() : y;
float nowY = ev.getY();
int deltaY = (int) (preY - nowY); y = nowY;
// 当滚动到最上或者最下时就不会再滚动,这时移动布局
if (isNeedMove(deltaY)) {
if (normal.isEmpty()) {
// 保存正常的布局位置
normal.set(getLeft(), getTop(), getRight(), getBottom());
}
// 移动布局
layout(getLeft(), getTop() - deltaY / 2, getRight(), getBottom() - deltaY / 2);
}
break;
default:
break;
}
}
} // 开启动画移动
public void animation() {
// 开启移动动画
TranslateAnimation ta = new TranslateAnimation(0, 0, 0, normal.top - getTop());
ta.setDuration(200);
ta.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
animationFinish = false; } @Override
public void onAnimationRepeat(Animation animation) { } @Override
public void onAnimationEnd(Animation animation) {
clearAnimation();
// 设置回到正常的布局位置
layout(normal.left, normal.top, normal.right, normal.bottom);
normal.setEmpty();
animationFinish = true;
}
});
startAnimation(ta);
} // 是否需要开启动画
public boolean isNeedAnimation() {
return !normal.isEmpty();
} // 是否需要移动布局
public boolean isNeedMove(float deltaY) {
if (overScrolled && getChildCount() > 0) {
if (getLastVisiblePosition() == getCount() - 1 && deltaY > 0) {
return true;
}
if (getFirstVisiblePosition() == 0 && deltaY < 0) {
return true;
}
}
return false;
}
}

测试代码:

 public class MainActivity extends Activity {
ElasticListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); listView = (ElasticListView) findViewById(R.id.listview); String[] listValues = new String[20];
for (int i=0;i<listValues.length;i++) {
listValues[i] = "TextView" + i;
}
listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listValues));
}
}
 public class MainActivity extends Activity {
ElasticListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); listView = (ElasticListView) findViewById(R.id.listview); String[] listValues = new String[20];
for (int i=0;i<listValues.length;i++) {
listValues[i] = "TextView" + i;
}
listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listValues));
}
}

【转】Android自定义控件(三)——有弹性的ListView的更多相关文章

  1. 老猪带你玩转android自定义控件二——自定义索引栏listview

    带索引栏的listview,在android开发非常普遍,方便用户进行字母索引,就像微信通讯录这样: 今天,我们就从零到一实现这个具有索引栏的listview. 怎么实现这个控件了,我们应当梳理出一个 ...

  2. 玩转android自定义控件二——自定义索引栏listview

    带索引栏的listview,在android开发非常普遍,方便用户进行字母索引,就像微信通讯录这样: 今天,我们就从零到一实现这个具有索引栏的listview. 怎么实现这个控件了,我们应当梳理出一个 ...

  3. Android自定义控件三种方式

    1.组合原生控件(继承自ViewGroup.LinearLayout.FrameLayout.RelativeLayout等)   将原生空间做组合,自定义一些事件 2.自己绘制控件(继承自View) ...

  4. android自定义控件(三) 自定义属性

    书接上回 在xml里建立属性,然后java代码里用typedArray获得这些属性,得到属性后,利用属性做一些事.例:得到xml里的color,赋给paint. 1.在res/values/下新建at ...

  5. android自定义控件(三) 增加内容 自定义属性 format详解

    转自 http://www.gisall.com/html/35/160435-5369.html 1. reference:参考某一资源ID. (1)属性定义: <declare-stylea ...

  6. Android自定义控件(三)——有弹性的ListView

    上一次我们试验了有弹性的ScrollView.详情 这一次,我们来试验有弹性的ScrollView. 国际惯例,效果图: 主要代码: import android.content.Context; i ...

  7. Android自定义控件——有弹性的ListView,ScrollView

    上一次我们试验了有弹性的ScrollView.详情 这一次,我们来试验有弹性的ScrollView. 国际惯例,效果图: 主要代码: [java] view plaincopy import andr ...

  8. Android自定义控件(四)——让每一个Activity UI都具有弹性

    前面我们已经介绍了如何让你的ScrollView,ListView具有弹性, 今天,我们在前面的基础上,做一下适当的修改,让那些既不是ScrollView,也不是ListView的Activity页面 ...

  9. Android自定义控件之自定义组合控件(三)

    前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...

随机推荐

  1. Google Cloud VM上在线扩硬盘

    Google Cloud VM是可以在线扩展Disk的大小的. 一.创建VM和磁盘 比如我有一台VM,附加了一块Disk,大小是120GB.如下图: 在VM中进行格式化: mkfs.ext4 -F / ...

  2. thinkphp5 设置.htaccess报input file specified的解决方法

    先去检查服务器设置,这个网上方法很多就不说了,如果服务器没问题还是报这个错误的话可能和php版本有关 php5.4和以下版本的.htaccess <IfModule mod_rewrite.c& ...

  3. python3 安装 past 包

    python3 安装 past 包 $ pip install future 错误现象 缺乏包的引用 from past.types import unicode 参考链接 https://pypi. ...

  4. 【转】Jmeter安装 for windows

    总结: 一.Jmeter安装总结 1.配置Java环境变量时需要注意设置的路径需要和JDK安装的路径一样 2.配置Java环境变量时需要注意JDK的版本号 3.配置环境变量时多个变量以分号隔开,但是确 ...

  5. HDU 4547 CD操作 (LCA最近公共祖先Tarjan模版)

    CD操作 倍增法  https://i.cnblogs.com/EditPosts.aspx?postid=8605845 Time Limit : 10000/5000ms (Java/Other) ...

  6. 杂项:UN-APP

    ylbtech-杂项:APP 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部     6.返回顶部   7.返回顶部   8.返回顶部   9.返回顶部   10 ...

  7. cocos2d-x v3.3开发环境配置

    开发环境: Win10 VS2012 链接:http://pan.baidu.com/s/1bn6S31d 密码:j2ol 配置Java SDK: 新建:JAVA_HOME =G:\Java\jdk1 ...

  8. linux c++ rabbitMq Demo

    1.在vs上实现远程调试Linux c++程序:https://www.jianshu.com/p/8b51a795cb92. 2.调试需要c++11,升级redhat上的gcc版本,虚拟机gcc版本 ...

  9. python's twenty eithth day for me 模块和包

    模块: 什么是模块: 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀,但其实import加载的模块分为四个通用类别: 1,使用python编写的代码 ...

  10. java - 读取,导出 excel文件数据

    首先需下载poi java包,添加至构建路径, 写处理方法: import java.io.FileInputStream;import java.io.FileOutputStream;import ...