1

我有一个列表视图。在适配器内部,当我执行以下操作(下面的代码)时,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 以便它不可见。事实上,如果我只能这样做,那就太好了。然后我想获取它的数据来做一些工作。

4

2 回答 2

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);
    }
}

我解释该怎么做的最好方法就是自己尝试一下。

如果在滚动时字符串包含数字 4,我们会将背景颜色更改为橙​​色,这会创建一个字符串列表“Value n”最多 30。如果您希望删除视图,我们应该可以这样做:

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 会取而代之。

于 2013-09-13T16:31:49.257 回答
1

getView在视图可见之前调用,因此当您向下滚动时,大部分时间position将是firstVisible - 1并且当您向上滚动时firstVisible + totalVisibleItems

相反,您应该将滚动侦听器绑定到您的 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
    }
});
于 2013-09-12T20:33:18.520 回答