我有一个ListView。在适配器内部,当我执行以下操作(下面的代码)时,firstVisible
仅在列表首次显示时等于position
。在滚动期间,当视图明显位于顶部时,适配器仍然没有将其捕获为位于顶部。
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
...
int firstVisible = ((ListView) parent).getFirstVisiblePosition();
if (firstVisible == position) {/
//print some stuff and do work
} else {
//print some other stuff and do other work
}
}
return rowView;
}
所以我的问题是,在滚动过程中如何跟踪特定项目何时位于ListView的顶部?我想从适配器中做到这一点。
修改
当有问题的视图到达顶部时:首先我要将其设置为GONE,以使其不可见。事实上,如果我只能这样做,那就太好了。然后我想抓住它的数据进行一些工作。
答案 0 :(得分:3)
好吧我想我有一个解决方案:
public class MyActivity extends Activity {
ListView listView;
ArrayAdapter<String> adapter;
int firstVisible;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
listView = (ListView) findViewById(R.id.listView);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
processView(v, getItem(position), true);
return v;
}
};
for (int i = 0; i < 30; i++) {
adapter.add("Value " + String.valueOf(i + 1));
}
listView.setAdapter(adapter);
firstVisible = listView.getFirstVisiblePosition();
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (firstVisibleItem != firstVisible) {
onFirstVisibleChanged(firstVisible, firstVisibleItem);
firstVisible = firstVisibleItem;
}
}
});
}
private void processView(View v, String value, boolean fromGetView) {
//if from get view we don't want to set yet wait till it comes from scrolling
if (value.contains("4") && !fromGetView) {
v.setBackgroundResource(android.R.color.holo_orange_light);
} else {
v.setBackgroundResource(android.R.color.transparent);
}
}
private void onFirstVisibleChanged(int oldIndex, int newIndex) {
View v = getViewForPosition(newIndex);
String val = adapter.getItem(newIndex);
processView(v, val, false);
}
/**
* @param position
* position of item in list
* @return null if position outside bounds
*/
public View getViewForPosition(int position) {
int firstPosition = listView.getFirstVisiblePosition() - listView.getHeaderViewsCount();
int wantedChild = position - firstPosition;
// Say, first visible position is 8, you want position 10, wantedChild will now be 2
// So that means your view is child #2 in the ViewGroup:
if (wantedChild < 0 || wantedChild >= listView.getChildCount()) {
return null;
}
return listView.getChildAt(wantedChild);
}
}
我解释做什么的最好方法就是亲自尝试。
这样做的是将字符串“Value n”列表最多30个 如果字符串在滚动时包含数字4,我们会将背景颜色更改为橙色。如果您希望删除视图,我们应该能够这样做:
private void processView(View v, String value, boolean fromGetView) {
//if from get view we don't want to set yet wait till it comes from scrolling
if (value.contains("4") && !fromGetView) {
adapter.remove(value);
} else {
//no action needed
}
}
然而,这可能会让用户感到非常困惑,因为值4移动到顶部时它被移除,值5移动到位。
答案 1 :(得分:1)
getView
,因此当您向下滚动时,大部分时间position
将为firstVisible - 1
,并向上滚动firstVisible + totalVisibleItems
。< / p>
相反,您应该将滚动侦听器绑定到ListView
listView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// Here you can change the model of the firstView and invalidate it for her to be redrawn
}
});