【转】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自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...
随机推荐
- linux 下安装php扩展
linux下安装php扩展 步骤: 1.在扩展解压包目录执行 phpize 2.执行 ./configure --with-php-config=/usr/local/php/bin/php-conf ...
- 华为公司内部培训资料_介绍RTSP的消息、信令等
https://wenku.baidu.com/view/b10415dabd64783e08122b9c.html
- Python 自动化测试config配置文件ini 配置目录
import ConfigParserimport os path = os.path.join(os.path.dirname(__file__), 'config.ini').replace('\ ...
- Git使用点滴记录: You have no permission to access this repo.
代码托管在https://coding.net上面,之前Git用https的方式都好好的,没有出什么问题.结果今天git pull代码的时候一直提示以下信息: remote: Coding.net T ...
- C Primer Plus学习笔记(十一)- 存储类别、链接和内存管理
存储类别 从硬件方面来看,被储存的每个值都占用一定的物理内存,C 语言把这样的一块内存称为对象(object) 对象可以储存一个或多个值.一个对象可能并未储存实际的值,但是它在储存适当的值时一定具有相 ...
- Vertrigo Serv + testlink 环境搭建
今天偶要教大家,使用VertrigoServ来搭建PHP服务器平台.有兴趣的你将会马上拥有一台PHP的WEB服务器哦,呵呵! 第一次给偶的感觉类似于我们租用的PHP虚拟主机.功能可和APPSERV媲美 ...
- 我是怎么用python模仿勒索软件加密文件的(病毒)
前言: 今天下午上学,用python写个勒索脚本然后打包成exe是个不错的选择 我们来搞事情吧.看那学校我就不想上学. 0x01:要用到的模块,各位请自行准备 import win32api,win3 ...
- 上传图片用图片文件的对象hash哈希值判断图片是否一样,避免重复提交相同的图片到服务器中
上传图片用图片文件的对象hash哈希值判断图片是否一样,避免重复提交相同的图片到服务器中 前端:要用到一个插件,点击下载 <!DOCTYPE html> <html xmlns=&q ...
- 什么是jsonp?——使用jsonp解决跨域请求问题
我们在使用ajax请求的时候经常会产生跨域问题,这是由于浏览器的同源策略导致的.所谓同源,即域名.协议.端口均相同,否则不管是静态页面还是动态网页或者web服务都无法通过ajax正常请求.有时候,我们 ...
- OK6410之tftp下载内核,nfs…
原文地址:OK6410之tftp下载内核,nfs挂载文件系统全过程详解[转]作者:千山我独行 由于工作的平台也是嵌入式,差不多的平台,所以一直就没有把自己买过来的ok6410板子好好玩玩.以前一直都是 ...