您的位置:首页 > 其它

ListView阻尼效果

2015-06-04 17:20 295 查看
效果图省略。。。

activity_main.xml(只有一个自定义ListView)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.dampingdemo.MainActivity" >

<com.example.dampingdemo.DampingListView1
android:id="@+id/listView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</com.example.dampingdemo.DampingListView1>

</RelativeLayout>


MainActivity(ArrayListAdapter 为了简化代码)

package com.example.dampingdemo;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;

public class MainActivity extends Activity {

private DampingListView1 dampingListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dampingListView = (DampingListView1) findViewById(R.id.listView);

//data
String[] data = {"A","B","C","A","B","C","A","B","C","A","B","C","A","B","C","A","B","C","A","B","C","A","B","C"};
//获取适配器
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,data );
//设置适配器
dampingListView.setAdapter(adapter);
}
}
DampingListView1(第一种方法)

package com.example.dampingdemo;

import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ExpandableListView;
import android.widget.ListView;
/**
*   1. 在View中增加了overSrollBy方法,用于记录x, y 轴上滚动

2. 在AbsListView的onTouchEvent中判断是否到达边界(顶部 或 底部) ,然后调用view.overScrollBy ,传入 mScrollY等参数

3. overScrollBy 最终赋值给View的mScrollX, mScrollY 两个变量

4. 在AbsListView中调用完overScrollBy之后,调用invalidate重绘
*
*/
public class DampingListView1 extends ListView {
private static final int MAX_Y_OVERSCROLL_DISTANCE = 200;

private Context mContext;
private int mMaxYOverscrollDistance;

public DampingListView1(Context context) {
super(context);
mContext = context;
initBounceListView();
}

public DampingListView1(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
initBounceListView();
}

public DampingListView1(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
initBounceListView();
}

private void initBounceListView() {

final DisplayMetrics metrics = mContext.getResources()
.getDisplayMetrics();
final float density = metrics.density;

mMaxYOverscrollDistance = (int) (density * MAX_Y_OVERSCROLL_DISTANCE);
}

@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,
int scrollY, int scrollRangeX, int scrollRangeY,
int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
return super.overScrollBy(deltaX, deltaY, scrollX, scrollY,
scrollRangeX, scrollRangeY, maxOverScrollX,
mMaxYOverscrollDistance, isTouchEvent);
}

}


+++++++++++++++++++++++++++或者第二种方法+++++++++++++++++++++++++++++++++++++++

DampingListView

package com.example.dampingdemo;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ExpandableListView;
import android.widget.ListView;

public class DampingListView extends ListView implements Runnable {

// 手指点位置的Y坐标
private float mLastDownY = 0f;
// 移动距离
private int mDistance = 0;
private int mStep = 0;
// 是否移动过
private boolean mPositive = false;

/**
* 构造器
*/
public DampingListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

public DampingListView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public DampingListView(Context context) {
super(context);
}

/**
* TouchEvent事件
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 系列事件,手指第一次按下时触发
if (mLastDownY == 0f && mDistance == 0) {
mLastDownY = event.getY();
return true;
}
break;

case MotionEvent.ACTION_CANCEL:
break;

case MotionEvent.ACTION_UP:
// 手指离开之后触发
if (mDistance != 0) {
mStep = 1;
mPositive = (mDistance >= 0);
// 即可把你的Runnable对象增加到UI线程中运行。
this.post(this);
return true;
}
// 重新赋值
mLastDownY = 0f;
mDistance = 0;
break;

case MotionEvent.ACTION_MOVE: // 手指按下之后滑动触发
if (mLastDownY != 0f) {
mDistance = (int) (mLastDownY - event.getY());
if ((mDistance < 0 && getFirstVisiblePosition() == 0 && getChildAt(
0).getTop() == 0)
|| (mDistance > 0 && getLastVisiblePosition() == getCount() - 1)) {
// 第一个位置并且是想下拉,就滑动或者最后一个位置向上拉
// 这个判断的作用是在非顶端的部分不会有此滚动
mDistance /= 3; // 这里是为了减少滚动的距离
scrollTo(0, mDistance); // 滚动
return true;
}
}
// 置为0,有自动滑动的效果
mDistance = 0;
break;
}
return super.onTouchEvent(event);
}

public void run() {
mDistance += mDistance > 0 ? -mStep : mStep;
scrollTo(0, mDistance);
// 下拉mPositive是false,上拉是true
if ((mPositive && mDistance <= 0) || (!mPositive && mDistance >= 0)) {
scrollTo(0, 0);
mDistance = 0;
mLastDownY = 0f;
return;
}
mStep += 1;
this.post(this);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: