1. MainActivity.java
package com.habby.sliderbar;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import com.habby.sliderbar.SpringListView.SpringListener;
public class MainActivity extends Activity implements OnClickListener {
private final String TAG = getClass().getSimpleName();
private SpringListView mListView = null;
private SpringListener mSpringListener = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
default:
break;
}
}
private void initView() {
mListView = (SpringListView) findViewById(R.id.name_lv);
List<String> datas = new ArrayList<String>();
for (int i = 0; i < 25; ++i) {
datas.add("fuck you");
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
datas);
mListView.setAdapter(adapter);
mSpringListener = new SpringListener() {
@Override
public void onSpringUpPush() {
Log.e(TAG, "UpPush !");
}
@Override
public void onSpringDownPush() {
Log.e(TAG, "DownPush");
}
@Override
public void onSpringCompleted() {
Log.e(TAG, "Completed !");
}
};
mListView.registerSpringListener(mSpringListener);
}
}
2. SpringListView.java 自定义控件
package com.habby.sliderbar;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ListView;
/**
* 针对一个带上拉/下拉弹簧效果的ListView,比普通的ListView仅仅多了弹簧效果而已;
* 因此,可以重写ListView,添加弹簧效果即可,其他的行为依旧是默认的ListView行为。
* 子线程用于处理 “弹回” 效果。
* @author habby
*
*/
public class SpringListView extends ListView implements Runnable {
private float mLastDownY = 0f;
private int mDistance = 0; // 手指/弹簧拉去移动的距离
private int mStep = 10;
private boolean mPositive = false; // 滚动方向
private SpringListener mListener;
public SpringListView(Context ctx, AttributeSet attrs) {
super(ctx, attrs);
}
public SpringListView(Context ctx, AttributeSet attrs, int defStyle) {
super(ctx, attrs, defStyle);
}
public SpringListView(Context ctx) {
super(ctx);
}
/**
* 只有满足这个情况才会有下拉弹簧:
* 当按下时,ListView可以显示的第1行是处于顶部第1个或底部最后1个时,下拉或上拉才有弹簧效果。
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (getFirstVisiblePosition() == 0 || getLastVisiblePosition() == getCount() - 1) {
mLastDownY = event.getY();
return true;
}
mDistance = 0;
break;
case MotionEvent.ACTION_MOVE: // 拉伸
mDistance = (int) (mLastDownY - event.getY());
if ((mDistance < 0 && (getFirstVisiblePosition() == 0))
|| (mDistance > 0 && (getLastVisiblePosition() == getCount() - 1))) {
mDistance /= 2;
scrollTo(0, mDistance);
if (mListener != null) {
if (mDistance < 0) {
mListener.onSpringDownPush();
} else if (mDistance > 0) {
mListener.onSpringUpPush();
}
}
return true;
}
mDistance = 0;
break;
case MotionEvent.ACTION_UP: // 松手的时候,弹回来
if ((mDistance < 0 && getFirstVisiblePosition() == 0)
|| (mDistance > 0 && getLastVisiblePosition() == getCount() - 1)) {
mStep = 1;
mPositive = (mDistance >= 0);
this.post(this); // 启动子线程,用于 "弹回" 效果
return true;
}
mDistance = 0;
break;
default:
break;
}
// 其他情况使用ListView(父类)本身的行为,不覆盖。这里仅仅是覆盖了ListView以上的2中情况。
return super.onTouchEvent(event);
}
@Override
public void run() {
mDistance += mDistance > 0 ? -mStep : mStep;
scrollTo(0, mDistance);
if ((mPositive && mDistance <= 0) || (!mPositive && mDistance >= 0)) {
scrollTo(0, 0);
mDistance = 0;
mLastDownY = 0f;
if (mListener != null) {
mListener.onSpringCompleted();
}
return;
}
mStep += 5;
this.postDelayed(this, 10);
}
public void registerSpringListener(SpringListener listener) {
mListener = listener;
}
/**
* 回调接口
*/
public interface SpringListener {
public void onSpringDownPush(); // 下拉
public void onSpringUpPush(); // 上拉
public void onSpringCompleted(); //"回弹" 完成
}
}
3. activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white" >
<com.habby.sliderbar.SpringListView
android:id="@+id/name_lv"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="vertical" />
</RelativeLayout>
本文介绍如何实现一个自定义的ListView组件,该组件具备上下拉动时触发弹簧效果的功能。通过继承ListView并重写其触摸事件处理方法,实现手指拖动时的弹簧反弹效果,并通过回调接口监听弹簧的运动状态。
568

被折叠的 条评论
为什么被折叠?



