0

I am initializing a list view like below and setting its custom adapter

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

Below is my adapter

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

I want to check how many times my getView is called for the first view of my list View (lvRecords). Basically i want to track number of visible list items.

Any help? Thanks!!

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Naila
  • 270
  • 1
  • 4
  • 26
  • Inside the `if (convertView == null)` block, view is being created for the first time. This block will run only for the maximum number of visible items on the screen. So, declare a global variable in the adapter class and increment it in the if-block and log it. After a while that value will become constant. Well, this is all theory and should work. Let me know – denvercoder9 Nov 20 '17 at 13:26
  • Well that'll give me the total number of items in list view... I want to know the visible items count – Naila Nov 20 '17 at 13:27
  • No, that won't give you the total number of items in the listview. That if-block will only execute for the maximum number of items that can be visible on the screen. Try it out first – denvercoder9 Nov 20 '17 at 13:31
  • How can i track that for the first view of list view? – Naila Nov 20 '17 at 13:41
  • `getView()` is called once for each item. So for the first view of the list view, it will be called only one time. – denvercoder9 Nov 20 '17 at 13:44

2 Answers2

3

After you initialise the list and set an adapter you can use the ListView's getLastVisiblePosition() and getFirstVisiblePosition() methods too see how many items are visible.

Note: The ListView has to be drawn on screen in order for these methods to work. If you want to get the count just after the list is drawn you could try posting a runnable on the view itself like so:

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

If you are planning to count the items every time the user scrolls, you can implement a scroll listener:

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

The onScrollStateChanged method gets called every time the state changes (the user is scrolling, a fling is performed, or the list stops scrolling).

The onScroll method gets called every time the list position changes, and will be called multiple times per second while the list is being scrolled, so you should avoid doing too many operations here.

Vlad
  • 397
  • 1
  • 12
  • i shall be glad to use getFirstVisiblePosition() and get LastVisiblePosition(), but it always returns me -1 for LastVisiblePosition. Inspite of the fact that my last position is completely (not partially) shown. – Naila Nov 21 '17 at 05:23
  • Since the AdapterView's `getLastVisiblePosition()` implementation is based on the view's `getChildCount()` method, so making the call before the view is drawn, would lead to a -1 return value. I have also updated the answer with a note. I hope it helps. – Vlad Nov 21 '17 at 09:30
  • 1
    Happy to hear that :D – Vlad Nov 21 '17 at 12:11
0

You have logged the position, take a look at how many logs you have regarding that.

Dan
  • 110
  • 3
  • That's equal to number of my list items, but i want to track only the current visible items count. – Naila Nov 20 '17 at 13:18
  • I might be wrong, but i think the list view is creating all the views at start. If you want to have views created just for the screen you have to use recycler view. – Dan Nov 20 '17 at 13:24
  • @DanSerb You are certainly wrong here. The ListView already used items recycling and only drew the items on the screen (plus a few ones above and below for smoother scrolling). (https://stackoverflow.com/questions/26728651/recyclerview-vs-listview) – Vlad Nov 20 '17 at 14:09
  • My bad then. I actually used them but I forgot. – Dan Nov 20 '17 at 14:51