直接上代码
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import com.letv.tvos.lechou.utils.LogCat;
public class SmoothScrollListView extends ListView implements OnKeyListener {
private int itemsCount;
private int itemHeight;
private ListAdapter adapter;
private int scrollDuration = 1000;
private boolean isScrollTop;
private Timer timer;
private OnScrollBottomListener onScrollBottomListener;
private OnScrollTopListener onScrollTopListener;
public SmoothScrollListView(Context context) {
this(context, null);
}
public SmoothScrollListView(Context context, AttributeSet attrs) {
super(context, attrs);
this.setOnKeyListener(this);
this.setSmoothScrollbarEnabled(true);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (adapter != null) {
//获取每个item 的高度,因为要调用滑动的方法,每次滑动的距离就是item 的高度
itemHeight = this.getChildAt(0).getHeight();
}
}
@Override
public void setAdapter(ListAdapter adapter) {
super.setAdapter(adapter);
this.adapter = adapter;
//获取listview item的count,一定要是由adapter获得,不能通过listView,因为listView是动态添加删除孩子的,可以打印一下比较看看
itemsCount = adapter.getCount();
}
/**
* 设置滚动动画的滚动时间
*
* @param scrollDutation
*/
public void setScrollDuration(int scrollDutation) {
this.scrollDuration = scrollDutation;
}
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP) {
return false;
}
//获取当前被选中的状态
int currentItemPosition = this.getSelectedItemPosition();
if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
//当时倒数第二个的时候
if (currentItemPosition == itemsCount - 2) {
//如果listView的最后一个可见Item是倒数第二个item,或者是倒数第一个item同时timer不为空,这时要滚动一次,并让最后一个item获取焦点
if(this.getLastVisiblePosition() == itemsCount - 2 || (this.getLastVisiblePosition() == itemsCount - 1 && timer != null)){
LogCat.e("倒数第二个");
this.smoothScrollBy(itemHeight, scrollDuration);
if(timer == null){
smoothScrollToBottom();
}else{
timer.cancel();
timer = null;
//延迟一下,再让最后一个item编程selected状态,不让没有动画,太突兀
smoothScrollToBottom();
}
// this.smoothScrollToPositionFromTop(itemsCount - 1, 0, scrollDuration);
// this.setSelection(itemsCount - 1);
}
return false;
} else if (currentItemPosition == itemsCount - 1) {
//当是最后一个item是selectionItem,则给出回调,让他不要在滚动了
if (onScrollBottomListener != null) {
onScrollBottomListener.onScrollBottom();
}
return true;
} else {
//是中间其他状态的时候,滚动一个item的距离
this.smoothScrollBy(itemHeight, scrollDuration);
// this.smoothScrollToPositionFromTop(currentItemPosition + 1, 0, scrollDuration);
return false;
}
}
if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
if (currentItemPosition == 1) {
if(this.getChildAt(0).isFocusable() == false){
this.smoothScrollBy(-itemHeight, scrollDuration);
}
return false;
} else if (currentItemPosition == 0) {
if (onScrollTopListener != null) {
onScrollTopListener.onScrollTop();
}
return isScrollTop;
} else {
this.smoothScrollBy(-itemHeight, scrollDuration);
return false;
}
}
return false;
}
private void smoothScrollToBottom(){
LogCat.e("平滑移动到最后");
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
SmoothScrollListView.this.post(new Runnable() {
@Override
public void run() {
SmoothScrollListView.this.setSelection(SmoothScrollListView.this.getLastVisiblePosition());
}
});
}
}, scrollDuration / 3);
}
/**
* 当滚动到底部的时候的监听
*/
public interface OnScrollBottomListener {
void onScrollBottom();
}
public void setOnScrollBottomListener(
OnScrollBottomListener onScrollBottomListener) {
this.onScrollBottomListener = onScrollBottomListener;
}
/**
* 当滚动到顶部的时候的监听
*/
public interface OnScrollTopListener {
void onScrollTop();
}
public void setOnScrollTopListener(OnScrollTopListener onScrollTopListener) {
isScrollTop = true;
this.onScrollTopListener = onScrollTopListener;
}
}