【转】Android自定义控件(三)——有弹性的ListView
原文地址: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的更多相关文章
- 老猪带你玩转android自定义控件二——自定义索引栏listview
带索引栏的listview,在android开发非常普遍,方便用户进行字母索引,就像微信通讯录这样: 今天,我们就从零到一实现这个具有索引栏的listview. 怎么实现这个控件了,我们应当梳理出一个 ...
- 玩转android自定义控件二——自定义索引栏listview
带索引栏的listview,在android开发非常普遍,方便用户进行字母索引,就像微信通讯录这样: 今天,我们就从零到一实现这个具有索引栏的listview. 怎么实现这个控件了,我们应当梳理出一个 ...
- Android自定义控件三种方式
1.组合原生控件(继承自ViewGroup.LinearLayout.FrameLayout.RelativeLayout等) 将原生空间做组合,自定义一些事件 2.自己绘制控件(继承自View) ...
- android自定义控件(三) 自定义属性
书接上回 在xml里建立属性,然后java代码里用typedArray获得这些属性,得到属性后,利用属性做一些事.例:得到xml里的color,赋给paint. 1.在res/values/下新建at ...
- android自定义控件(三) 增加内容 自定义属性 format详解
转自 http://www.gisall.com/html/35/160435-5369.html 1. reference:参考某一资源ID. (1)属性定义: <declare-stylea ...
- Android自定义控件(三)——有弹性的ListView
上一次我们试验了有弹性的ScrollView.详情 这一次,我们来试验有弹性的ScrollView. 国际惯例,效果图: 主要代码: import android.content.Context; i ...
- Android自定义控件——有弹性的ListView,ScrollView
上一次我们试验了有弹性的ScrollView.详情 这一次,我们来试验有弹性的ScrollView. 国际惯例,效果图: 主要代码: [java] view plaincopy import andr ...
- Android自定义控件(四)——让每一个Activity UI都具有弹性
前面我们已经介绍了如何让你的ScrollView,ListView具有弹性, 今天,我们在前面的基础上,做一下适当的修改,让那些既不是ScrollView,也不是ListView的Activity页面 ...
- Android自定义控件之自定义组合控件(三)
前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...
随机推荐
- Winform判断是否已启动
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...
- 杂项:UN-HTML
ylbtech-杂项:HTML 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 7.返回顶部 8.返回顶部 9.返回顶部 1 ...
- AngularJS:简介
ylbtech-AngularJS:简介 1.返回顶部 1. AngularJS 简介 AngularJS 是一个 JavaScript 框架.它可通过 <script> 标签添加到 HT ...
- 缓存 memcached 与 redis
Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...
- .gitignore non-valiate
Git忽略规则及.gitignore规则不生效的解决办法 分享到:更多19 2015-02-12 分类:Share2人评论65,215 次人浏览 在git中如果想忽略掉某个文件,不让这个文件提交 ...
- 2014.8.25 VS新建项目模板消失解决方法
Vs2005 新建项目时windows应用程序模板消失问题解决方法: 1:进入C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\IDE\ ...
- puclic 页面公共CSS样式
body, div, dl, dt, dd, ul, ol, li, pre, form, fieldset, blockquote, h1, h2, h3, h4, h5, h6,p{ paddin ...
- requirejs——基础
一.requirejs存在的意义: 我们引用外部JS文件通常是这样引用的: <script src="1.js"></script> <script ...
- [原创]Spring JdbcTemplate 使用总结与经验分享
引言 近期开发的几个项目,均是基于Spring boot框架的web后端项目,使用JdbcTemplate执行数据库操作,实际开发过程中,掌握了一些有效的开发经验,踩过一些坑,在此做个记录及总结,与各 ...
- 开启mysql远程访问
一.登陆mysql以后执行以下命令: GRANT ALL ON *.* TO username@'%' IDENTIFIED BY 'password' WITH GRANT OPTION; FLUS ...