【问题标题】:Number of visible list items in dynamic list view动态列表视图中可见列表项的数量
【发布时间】:2017-11-20 13:12:16
【问题描述】:

我正在初始化如下所示的列表视图并设置其自定义适配器

 lvRecords = (ListView) findViewById(R.id.lv_records);
 lvRecords.setAdapter(adapterSearchResult);

下面是我的适配器

public class SearchResultListAdapter extends ArrayAdapter implements View.OnClickListener{
        private Context context;
        private ArrayList<Record> records;
        private int numOfPaginatorBtns = 0;

        static class HolderView {
            public TextView tvBahiNum;
            public TextView tvRegNum;
            public TextView tvYear;
            public Button btnDetails;
            public Button btnRegistry;
        }

        @SuppressWarnings("unchecked")
        public SearchResultListAdapter(Context c, ArrayList<Record> records, int numOfPaginatorBtns) {
            super(c, R.layout.search_result_item, records);
            this.context = c;
            this.records = records;
            this.numOfPaginatorBtns = numOfPaginatorBtns;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            Log.e("position", Integer.toString(position));
            if (convertView == null) {
                Log.e("in" , "convert View");
                LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(R.layout.search_result_item, parent, false);

                HolderView listItem = new HolderView();
                listItem.tvBahiNum = (TextView) convertView.findViewById(R.id.tv_bahi_num);
                listItem.tvRegNum = (TextView) convertView.findViewById(R.id.tv_reg_num);
                listItem.tvYear = (TextView) convertView.findViewById(R.id.tv_year);
                listItem.btnDetails = (Button) convertView.findViewById(R.id.btn_details);
                listItem.btnDetails.setOnClickListener(this);

                convertView.setTag(listItem);`}`

            HolderView listItem = (HolderView) convertView.getTag();

            Record rec = records.get(position);

            listItem.tvRegNum.setText(rec.regNum);
            listItem.tvBahiNum.setText(rec.bahiNum);
            listItem.tvYear.setText(rec.year);
            return convertView;
        }

        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.btn_details:
                    break;
            }
        }
    }

我想检查在我的列表视图 (lvRecords) 的第一个视图中调用了多少次 getView。基本上我想跟踪可见列表项的数量。

有什么帮助吗?谢谢!!

【问题讨论】:

  • if (convertView == null) 块内,第一次创建视图。此块将仅针对屏幕上最大数量的可见项目运行。因此,在适配器类中声明一个全局变量,并在 if 块中增加它并记录它。一段时间后,该值将变得恒定。好吧,这都是理论,应该可行。告诉我
  • 嗯,这会给我列表视图中的项目总数...我想知道可见项目数
  • 不,这不会为您提供列表视图中的项目总数。该 if 块将仅针对屏幕上可见的最大项目数执行。先试试看
  • 如何在列表视图的第一个视图中跟踪它?
  • getView() 为每个项目调用一次。所以对于列表视图的第一个视图,只会调用一次。

标签: android list listview


【解决方案1】:

初始化列表并设置适配器后,您可以使用 ListView 的 getLastVisiblePosition()getFirstVisiblePosition() 方法查看有多少项可见。

注意:必须在屏幕上绘制 ListView 才能使这些方法起作用。如果您想在列表绘制后立即获得计数,您可以尝试在视图本身上发布一个可运行对象,如下所示:

lvRecords.post(new Runnable() {
            @Override
            public void run() {
                int itemsShown = lvRecords.getLastVisiblePosition() - lvRecords.getFirstVisiblePosition(); 
            }
        });

如果您打算在用户每次滚动时对项目进行计数,您可以实现一个滚动监听器:

    lvRecords.setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView absListView, int scrollState) {
            if(scrollState == SCROLL_STATE_IDLE) {
                int noOfItemsVisible = lvRecords.getLastVisiblePosition() - lvRecords.getFirstVisiblePosition();
                Log.e("no of items visible", String.valueOf(noOfItemsVisible));
            }
        }

        @Override
        public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            Log.e("no of items visible", String.valueOf(visibleItemCount));
        }
    });

onScrollStateChanged 方法在每次状态改变时被调用(用户正在滚动,执行了一个投掷,或者列表停止滚动)。

onScroll 方法在每次列表位置发生变化时被调用,并且在列表滚动时每秒会被调用多次,所以你应该避免在这里做太多的操作。

【讨论】:

  • 我会很高兴使用 getFirstVisiblePosition() 并获得 LastVisiblePosition(),但它总是为 LastVisiblePosition 返回 -1。尽管我的上一个位置已完全(不是部分)显示出来。
  • 由于 AdapterView 的 getLastVisiblePosition() 实现是基于视图的 getChildCount() 方法,因此在绘制视图之前进行调用会导致返回值 -1。我还用注释更新了答案。我希望它有所帮助。
  • 很高兴听到这个消息:D
【解决方案2】:

您已经记录了该职位,看看您有多少关于该职位的日志。

【讨论】:

  • 这等于我的列表项数,但我只想跟踪当前可见项数。
  • 我可能错了,但我认为列表视图是在开始时创建所有视图。如果你想为屏幕创建视图,你必须使用回收器视图。
  • @DanSerb 你肯定错了。 ListView 已经使用了项目回收,并且只在屏幕上绘制了项目(加上上面和下面的一些以便更平滑的滚动)。 (stackoverflow.com/questions/26728651/recyclerview-vs-listview)
  • 那我很糟糕。我实际上使用过它们,但我忘记了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-17
  • 2014-02-24
  • 2012-03-25
  • 1970-01-01
  • 2011-10-08
  • 1970-01-01
相关资源
最近更新 更多