Java 在Android中,如何在尊重fling带来的加速的同时,在listview上实现快照效果?
为了演示,我有一个显示数字列表的列表视图。我想达到这样的效果,当用户滚动ListView并且滚动结束时,它只会在某些位置停止,这样第一个可见的项目总是完全显示出来。我已在下面附上我的尝试代码。当用户拖动以滚动ListView时,它会起作用。但是,当有抛掷时,正常的加速被中断,导致非自然的停止。我的问题是,在获得相同效果的同时,如何考虑投掷引起的加速度Java 在Android中,如何在尊重fling带来的加速的同时,在listview上实现快照效果?,java,android,listview,android-listview,android-animation,Java,Android,Listview,Android Listview,Android Animation,为了演示,我有一个显示数字列表的列表视图。我想达到这样的效果,当用户滚动ListView并且滚动结束时,它只会在某些位置停止,这样第一个可见的项目总是完全显示出来。我已在下面附上我的尝试代码。当用户拖动以滚动ListView时,它会起作用。但是,当有抛掷时,正常的加速被中断,导致非自然的停止。我的问题是,在获得相同效果的同时,如何考虑投掷引起的加速度 package com.example.snaptest; import android.content.Context; import and
package com.example.snaptest;
import android.content.Context;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity {
private static class TestListViewAdapter extends BaseAdapter {
private Context mContext;
public TestListViewAdapter(Context context) {
mContext = context;
}
@Override
public int getCount() {
return 100;
}
@Override
public Object getItem(int position) {
return Integer.toString(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = new TextView(mContext);
textView.setText(Integer.toString(position));
AbsListView.LayoutParams params = new AbsListView.LayoutParams(ViewGroup.LayoutParams
.MATCH_PARENT, 180);
textView.setLayoutParams(params);
return textView;
}
}
private static class TestListView extends ListView {
public TestListView(Context context) {
super(context);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) {
View itemView = getChildAt(0);
int top = Math.abs(itemView.getTop()); // top is a negative value
int bottom = Math.abs(itemView.getBottom());
if (top >= bottom){
smoothScrollToPositionFromTop
(getFirstVisiblePosition() + 1, 0);
} else {
smoothScrollToPositionFromTop
(getFirstVisiblePosition(), 0);
}
}
return super.onTouchEvent(ev);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TestListView listView = new TestListView(this);
listView.setAdapter(new TestListViewAdapter(this));
setContentView(listView);
}
}
我会尝试使用
OnScrollListener
而不是扩展ListView
大概是这样的:
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == AbsListView.SCROLL_STATE_IDLE) {
// snap the listview according to the top/bottom items' visibility
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
谢谢你的建议!我同意这比我在问题中提供的解决方案要好。但动画仍将不平滑,因为捕捉将在ListView已减速到零速度后发生,而不是在减速时自然停止在所需位置。(相比之下,通过重写WillendDraging方法,这在iOS中很容易实现)。我会尝试计算滚动速度,当速度降低到固定阈值时,调用
smoothScrollToPosition()
方法。至于速度,这看起来像:。但我真的不知道这种方法是否有效。