0

From the Android development page we have the following quote for Custom ArrayAdapter of ListViews:

"there is absolutely no guarantee on the order in which getView() will be called nor how many times."

When I have the following and getView is called a few times, it's no problem, since I'm just recycling the Views instead of inflating them again:

@Override
public void getView(int position, View convertView, ViewGroup parent){
    Log.i(TAG, "getView of position " + String.valueOf(position) + " is called");

    View view = convertView;
    if(view == null){
        view = inflater.inflate(layoutResourceId, parent, false);
        TextView myTextView1 = (TextView) view.findViewById(R.id.my_tv1);
        Button myButton1 = (Button) view.findViewById(R.id.my_btn1);
        ... // More views
        view.setTag(new MyViewHolder(myTextView1, myButton1, ...));
    }
    MyViewHolder h = (MyViewHolder) view.getTag();

    h.myTextView1.setText("Some text");
    h.myButton1.setText("Some button text");
    h.myButton1.setEnabled(buttonEnabled);
}

The problem with using the if(view == null) -> inflate view and create ViewHolder; else -> use ViewHolder of Tag is when you scroll up and down real fast in the list, the order of the items in the list changes. Could be because of the first part of the quote:

"there is absolutely no guarantee on the order in which getView() will be called..."

Though I think it's just a bug with ListViews itself instead of the Adapter. (Not sure, but whatever the cause is, it IS a BUG.)

The only way I was able to fix that so far is always inflating the view:

@Override
public void getView(int position, View convertView, ViewGroup parent){
    Log.i(TAG, "getView of position " + String.valueOf(position) + " is called");

    // NOTE: In Android it's recommended to use the convertView as the view, instead of
    // retrieving it every time from the inflater. But since there is a bug in Android ListViews
    // which changes the order of the Items when you scroll up- and down real fast,
    // I use the inflater every time and ignore the convertView parameter
    view = inflater.inflate(layoutResourceId, parent, false);
    TextView myTextView1 = (TextView) view.findViewById(R.id.my_tv1);
    Button myButton1 = (Button) view.findViewById(R.id.my_btn1);
    ... // More views
    view.setTag(new MyViewHolder(myTextView1, myButton1, ...));

    MyViewHolder h = (MyViewHolder) view.getTag();

    h.myTextView1.setText("Some text");
    h.myButton1.setText("Some button text");
    h.myButton1.setEnabled(buttonEnabled);
}

All works fine, the order of the items remain when scrolling up- and down fast. But now the performance is going down quickly.. For quite a long time I just ignored this performance issues, but right now I'm facing a new problem after I made some changes to the layout of my item. Never had this issue before, but now I face (for some unknown reason) the second part of the quote:

"there is absolutely no guarantee how many times getView() will be called..."

Right now with a ListView containing 14 visible elements at creation. When I go to the ChecklistActivity which contains the ListView with this Adapter, I get the following Logcat-messages:

07-23 03:17:14.516: V/MyAdapter(1395): getView(0)
07-23 03:17:16.556: V/MyAdapter(1395): getView(1)
07-23 03:17:16.946: V/MyAdapter(1395): getView(2)
07-23 03:17:17.316: V/MyAdapter(1395): getView(3)
07-23 03:17:17.776: V/MyAdapter(1395): getView(4)
07-23 03:17:18.136: V/MyAdapter(1395): getView(5)
07-23 03:17:18.286: V/MyAdapter(1395): getView(6)
07-23 03:17:18.466: V/MyAdapter(1395): getView(7)
07-23 03:17:18.576: V/MyAdapter(1395): getView(8)
07-23 03:17:18.806: V/MyAdapter(1395): getView(9)
07-23 03:17:19.016: V/MyAdapter(1395): getView(10)
07-23 03:17:19.246: V/MyAdapter(1395): getView(11)
07-23 03:17:19.346: D/dalvikvm(1395): GC_FOR_ALLOC freed 220K, 10% free 5545K/6108K, paused 82ms, total 85ms
07-23 03:17:19.526: V/MyAdapter(1395): getView(12)
07-23 03:17:19.666: V/MyAdapter(1395): getView(13)
07-23 03:17:19.786: V/MyAdapter(1395): getView(14)
07-23 03:17:20.046: I/Choreographer(1395): Skipped 1491 frames!  The application may be doing too much work on its main thread.
07-23 03:17:20.066: V/ChecklistActivity(1395): onCreateOptionsMenu
07-23 03:17:20.406: I/Choreographer(1395): Skipped 64 frames!  The application may be doing too much work on its main thread.
07-23 03:17:20.416: V/MyAdapter(1395): getView(2)
07-23 03:17:20.576: V/MyAdapter(1395): getView(3)
07-23 03:17:20.866: V/MyAdapter(1395): getView(4)
07-23 03:17:21.036: V/MyAdapter(1395): getView(5)
07-23 03:17:21.206: V/MyAdapter(1395): getView(6)
07-23 03:17:21.396: V/MyAdapter(1395): getView(7)
07-23 03:17:21.606: V/MyAdapter(1395): getView(8)
07-23 03:17:21.866: V/MyAdapter(1395): getView(9)
07-23 03:17:22.116: V/MyAdapter(1395): getView(10)
07-23 03:17:22.336: V/MyAdapter(1395): getView(11)
07-23 03:17:22.496: V/MyAdapter(1395): getView(12)
07-23 03:17:22.646: V/MyAdapter(1395): getView(13)
07-23 03:17:22.806: V/MyAdapter(1395): getView(14)
07-23 03:17:23.616: V/MainActivity(1395): onStop
07-23 03:17:23.616: I/Choreographer(1395): Skipped 160 frames!  The application may be doing too much work on its main thread.
07-23 03:17:24.246: I/Choreographer(1395): Skipped 112 frames!  The application may be doing too much work on its main thread.
07-23 03:17:24.286: V/MyAdapter(1395): getView(4)
07-23 03:17:24.396: D/dalvikvm(1395): GC_FOR_ALLOC freed 397K, 8% free 6099K/6568K, paused 100ms, total 107ms
07-23 03:17:24.646: V/MyAdapter(1395): getView(5)
07-23 03:17:24.756: V/MyAdapter(1395): getView(6)
07-23 03:17:24.886: V/MyAdapter(1395): getView(7)
07-23 03:17:25.046: V/MyAdapter(1395): getView(8)
07-23 03:17:25.196: V/MyAdapter(1395): getView(9)
07-23 03:17:25.356: V/MyAdapter(1395): getView(10)
07-23 03:17:25.486: V/MyAdapter(1395): getView(11)
07-23 03:17:25.596: V/MyAdapter(1395): getView(12)
07-23 03:17:25.726: V/MyAdapter(1395): getView(13)
07-23 03:17:25.846: V/MyAdapter(1395): getView(14)
07-23 03:17:26.146: I/Choreographer(1395): Skipped 35 frames!  The application may be doing too much work on its main thread.
07-23 03:17:26.406: V/MyAdapter(1395): getView(6)
07-23 03:17:26.586: V/MyAdapter(1395): getView(7)
07-23 03:17:26.786: V/MyAdapter(1395): getView(8)
07-23 03:17:26.896: V/MyAdapter(1395): getView(9)
07-23 03:17:27.156: V/MyAdapter(1395): getView(10)
07-23 03:17:27.296: V/MyAdapter(1395): getView(11)
07-23 03:17:27.436: V/MyAdapter(1395): getView(12)
07-23 03:17:27.646: V/MyAdapter(1395): getView(13)
07-23 03:17:27.766: V/MyAdapter(1395): getView(14)
07-23 03:17:28.186: I/Choreographer(1395): Skipped 56 frames!  The application may be doing too much work on its main thread.
07-23 03:17:28.426: D/dalvikvm(1395): GC_FOR_ALLOC freed 523K, 9% free 6713K/7308K, paused 108ms, total 112ms
07-23 03:17:28.506: I/Choreographer(1395): Skipped 60 frames!  The application may be doing too much work on its main thread.
07-23 03:17:28.606: V/MyAdapter(1395): getView(8)
07-23 03:17:28.806: V/MyAdapter(1395): getView(9)
07-23 03:17:28.926: V/MyAdapter(1395): getView(10)
07-23 03:17:29.136: V/MyAdapter(1395): getView(11)
07-23 03:17:29.256: V/MyAdapter(1395): getView(12)
07-23 03:17:29.406: V/MyAdapter(1395): getView(13)
07-23 03:17:29.516: V/MyAdapter(1395): getView(14)
07-23 03:17:29.816: I/Choreographer(1395): Skipped 35 frames!  The application may be doing too much work on its main thread.
07-23 03:17:30.096: V/MyAdapter(1395): getView(9)
07-23 03:17:30.216: V/MyAdapter(1395): getView(10)
07-23 03:17:30.366: V/MyAdapter(1395): getView(11)
07-23 03:17:30.496: V/MyAdapter(1395): getView(12)
07-23 03:17:30.646: V/MyAdapter(1395): getView(13)
07-23 03:17:30.796: V/MyAdapter(1395): getView(14)
07-23 03:17:31.166: I/Choreographer(1395): Skipped 53 frames!  The application may be doing too much work on its main thread.
07-23 03:17:31.376: I/Choreographer(1395): Skipped 32 frames!  The application may be doing too much work on its main thread.
07-23 03:17:31.426: V/MyAdapter(1395): getView(10)
07-23 03:17:31.546: V/MyAdapter(1395): getView(11)
07-23 03:17:31.736: V/MyAdapter(1395): getView(12)
07-23 03:17:31.906: V/MyAdapter(1395): getView(13)
07-23 03:17:32.046: V/MyAdapter(1395): getView(14)
07-23 03:17:32.306: I/Choreographer(1395): Skipped 31 frames!  The application may be doing too much work on its main thread.
07-23 03:17:32.536: I/Choreographer(1395): Skipped 35 frames!  The application may be doing too much work on its main thread.
07-23 03:17:32.606: V/MyAdapter(1395): getView(11)
07-23 03:17:32.816: V/MyAdapter(1395): getView(12)
07-23 03:17:32.986: D/dalvikvm(1395): GC_FOR_ALLOC freed 729K, 10% free 7323K/8124K, paused 121ms, total 128ms
07-23 03:17:33.166: V/MyAdapter(1395): getView(13)
07-23 03:17:33.496: V/MyAdapter(1395): getView(14)
07-23 03:17:34.056: V/MyAdapter(1395): getView(12)
07-23 03:17:34.186: V/MyAdapter(1395): getView(13)
07-23 03:17:34.316: V/MyAdapter(1395): getView(14)
07-23 03:17:34.596: I/Choreographer(1395): Skipped 34 frames!  The application may be doing too much work on its main thread.
07-23 03:17:34.846: I/Choreographer(1395): Skipped 36 frames!  The application may be doing too much work on its main thread.
07-23 03:17:34.906: V/MyAdapter(1395): getView(13)
07-23 03:17:35.016: V/MyAdapter(1395): getView(14)
07-23 03:17:35.546: V/MyAdapter(1395): getView(14)
07-23 03:17:36.066: I/Choreographer(1395): Skipped 31 frames!  The application may be doing too much work on its main thread.

I have absolutely no idea why it's called so many times, but I'd like it to only be called once each. And if someone knows a solution for this fast-scrolling bugs that changes the order without inflating the View every single time in the getView() it would also be a huge help.

PS: Ignore the first 07-23 03:17:20.046: I/Choreographer(1395): Skipped 1491 frames! The application may be doing too much work on its main thread. I'm currently working on that.. Inflating the View is one of the reasons why the performance lacks, but there are also some other issues that I'm trying to fix.

Still, why can't Android just have a robust ArrayAdapter. One that doesn't change the order of items when someone is scrolling up- and down fast. Or an options so you can choose to remember the items outside of the visible region.. This could theoretically also create performance issues if you remember to many items, but it will solve a lot of problems, including those with EditText-input being reset again after they are out of the visible region. Then we shouldn't have to use TextWatchers, Tags with Holders and such..

Ok, I'm sidetracking now.. It's just the way it is and I can't change that. So let's just focus on fixing the problems explained above (fast-scrolling bug without inflating every time AND getView not getting called so many times on creation).


EDIT 1:

Some more info about other parts of my code:

checklist_activity.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:descendantFocusability="afterDescendants" />

</RelativeLayout>

list_item.xml outer layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
<!-- height is wrap content since I have views that are Visible / Gone based on the Item's state -->

    <!-- All my View elements -->

</RelativeLayout>

For my item, see this different stackoverflow question of mine.


EDIT 2:

Here below a copy of my current MyAdapter.java class (PS: Removed comments, imports and Logs for easier readability). When I scroll up- and down fast in the Emulator, the Images stay the same, but the Texts (of the Product-Names, Prices and such) are being mixed up. I've got a list ordered by Category and Product-Name and I want to list to retain this order in the ListView.

public class MyAdapter extends ArrayAdapter<OrderedProductItem>
{
    private static final String TAG = "MyAdapter";
    public static MyAdapter mAdapter;

    private Context context;
    private int layoutResourceId;
    private LayoutInflater inflater;

    public MyAdapter(Context c, int layoutId, ArrayList<OrderedProductItem> objects){
        super(c, layoutId, objects);

        layoutResourceId = layoutId;
        context = c;
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        mAdapter = this;
    }

    private OnTouchListener itemOnTouchListener = new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if(v instanceof EditText){
                EditText et = (EditText)v;
                et.setFocusable(true);
                et.setFocusableInTouchMode(true);
            }
            else{
                ListItemTagHolder h = (ListItemTagHolder) v.getTag();
                h.etAmount.setFocusable(false);
                h.etAmount.setFocusableInTouchMode(false);
                h.actvName.setFocusable(false);
                h.actvName.setFocusableInTouchMode(false);
            }
            return false;
        }
    };

    @Override
    public View getView(int position, View convertView, ViewGroup parent){
        View view = convertView;
        ListItemTagHolder h;
        if(view == null){
            view = inflater.inflate(layoutResourceId, parent, false);
            RelativeLayout rl = (RelativeLayout) view.findViewById(R.id.item_layout);
            h = new ListItemTagHolder(rl);
            view.setTag(h);
        }
        else
            h = (ListItemTagHolder) view.getTag();

        /*
        View view = inflater.inflate(layoutResourceId, parent, false);
        RelativeLayout rl = (RelativeLayout) view.findViewById(R.id.item_layout);
        view.setTag(new ListItemTagHolder(rl));
        final ListItemTagHolder h = (ListItemTagHolder) view.getTag();
        */

        if(h != null){
            h.orderedProductItem = Controller.getInstance().getOrderedProductItems().get(position);

            MainActivity.getImageLoader().imageForImageView(h.orderedProductItem.getCheckState().rID(), h.imageView);

            String productName = Controller.getInstance().getProductById(h.orderedProductItem.getProductId()).getName();
            // (I use a Validation-class to compare Strings or Check if they aren't null/empty)
            if(!V.compare(h.tvName.getText().toString(), productName, true, true))
                h.tvName.setText(productName);

            String priceString = C.doubleToPrice(Controller.getInstance().getProductById(h.orderedProductItem.getProductId()).getPrice(), "€", true);
            if(!V.compare(h.tvPrice.getText().toString(), priceString, true, true))
                h.tvPrice.setText(priceString);

            String resultAmount = String.valueOf(h.orderedProductItem.getResultAmount());
            if(!V.compare(h.etAmount.getText().toString(), resultAmount, true, true))
                h.etAmount.setText(resultAmount);

            ChecklistActivity.cActivity.updateAutoCompleteTextViewWithFilter(h, h.orderedProductItem.getSelectedFilter());

            ChecklistActivity.cActivity.updateTagsSpinner(h, null);

            h.etAmount.addTextChangedListener(new MyTextWatcher(h.etAmount));
            h.actvName.addTextChangedListener(new MyTextWatcher(h.actvName));

            h.etAmount.setTag(h.orderedProductItem);
            h.actvName.setTag(h.orderedProductItem);

            ChecklistActivity.cActivity.updateChangeEditTexts(view, h);

            view.setOnTouchListener(itemOnTouchListener);
            h.etAmount.setOnTouchListener(itemOnTouchListener);
            h.actvName.setOnTouchListener(itemOnTouchListener);
        }

        return view;
    }
}

With the following Holder-class:

public class ListItemTagHolder
{
    public final RelativeLayout relativeLayout;

    public final LinearLayout leftLL, rightLL;
    public final ImageView imageView;
    public final TextView tvName, tvPrice, tvTags;
    public final EditText etAmount;
    public final AutoCompleteTextView actvName;
    public final Spinner spTags;
    public final ImageButton btnTags;
    public final Space spaceImage, spacePrice;
    public OrderedProductItem orderedProductItem;

    public ListItemTagHolder(RelativeLayout layout){
        relativeLayout = layout;

        leftLL = (LinearLayout) relativeLayout.findViewById(R.id.left_ll);
        rightLL = (LinearLayout) relativeLayout.findViewById(R.id.right_ll);
        imageView = (ImageView) relativeLayout.findViewById(R.id.image);
        tvName = (TextView) relativeLayout.findViewById(R.id.tv_product_name);
        tvPrice = (TextView) relativeLayout.findViewById(R.id.tv_price);
        tvTags = (TextView) relativeLayout.findViewById(R.id.tv_tags);
        etAmount = (EditText) relativeLayout.findViewById(R.id.et_result_amount);
        actvName = (AutoCompleteTextView) relativeLayout.findViewById(R.id.actv_result_name);
        spTags = (Spinner) relativeLayout.findViewById(R.id.sp_tags);
        btnTags = (ImageButton) relativeLayout.findViewById(R.id.btn_tags);
        spaceImage = (Space) relativeLayout.findViewById(R.id.filler_space_image);
        spacePrice = (Space) relativeLayout.findViewById(R.id.filler_space_price);
    }
}

PS: I know most people put all View-elements in the Holder one by one, and I used to have this. But getting them all from the layout or one by one doesn't make any difference in the problem I'm facing.

PSS: Those three update-methods re-apply the new data from the OrderedProductItem fields in the Spinner / EditTexts / AutoCompleteTextView. I've placed them in the ChecklistActivity since I also use the same method there. This also doesn't make any difference in the problem I'm facing, whether I put them directly in the getView method or call them like I do here.

Community
  • 1
  • 1
Kevin Cruijssen
  • 9,153
  • 9
  • 61
  • 135
  • make sure your listview width and height "match_parent" – kalyan pvs Jul 23 '14 at 07:44
  • No, it is not a bug. Or at least is not a framework bug. You are probably misusing the widget and the adapter – Blackbelt Jul 23 '14 at 07:45
  • Your problem is here: http://stackoverflow.com/a/2639159/719212 – ductran Jul 23 '14 at 07:51
  • @blackbelt Bug can have multiple meanings. Bug in: "It's something happening that isn't suppose to happen and isn't predicted beforehand". And bug in "Something that is very impractical and just a work-around since we don't know how to fix it". The second one is the case here. What practical use can there be to change Item-order when someone is scrolling up and down fast.. It might not be a unexpected bug, but at least it isn't a feature either. I myself sure hope they change that in the (near) future.. – Kevin Cruijssen Jul 23 '14 at 07:54

3 Answers3

3

May I suggest you change your code a little. My ListView's getView() always looks like this and I have no problems with it.

@Override
public void getView(int position, View convertView, ViewGroup parent) {

    View view = convertView;
    MyViewHolder holder = new MyViewHolder();

    if (view == null) {

        view = inflater.inflate(layoutResourceId, null);

        holder.textView1 = (TextView) view.findViewById(R.id.my_tv1);
        holder.button1 = (Button) view.findViewById(R.id.my_btn1);
        // More views

        view.setTag(holder);
    } else {
        holder = (MyViewHolder) view.getTag();
    }

    holder.textView1.setText("Some text");
    holder.button1.setText("Some button text");
    holder.button1.setEnabled(buttonEnabled);
}

public static class MyViewHolder {
    public TextView textView1;
    public Button button1;
    // ... and so on
}
Hristova
  • 156
  • 1
  • 6
  • Have you tried scrolling up and down real fast with this? Since with me it changes the order of items when I do scroll up- and down fast. (Especially on the Emulator) – Kevin Cruijssen Jul 23 '14 at 08:19
  • @KevinCruijssen, are you certain you have the ViewHolder Tag cast in the `else`-block? That's the main problem I see with your code. – Mike M. Jul 23 '14 at 08:31
  • @MikeM., I'm almost sure that this is the actual problem too :) Kevin, Just try making the "else" change and see what happens. – Hristova Jul 23 '14 at 08:34
  • @MikeM. I used to have this and will try it again, but theoretically it shouldn't change anything.. It's either: `view == null -> inflate view, create viewholder, setTag(holder) -> use this created viewholder` in your case, or `view == null -> inflate view, create viewholder, setTag(holder) -> use this create viewholder by getting it from the tag we just set above`.. Anyway, like I said, I will try this again. Btw, have you tried scrolling up- and down fast?.. – Kevin Cruijssen Jul 23 '14 at 08:40
  • "have you tried scrolling up- and down fast?" Yes. On every ListView with a custom Adapter I have ever written. – Mike M. Jul 23 '14 at 08:44
  • @MikeM. Well, when I scroll up- and down fast, the texts that I set of the items (based on the Object-position in the Adapter-list) are mixed up. The View-items itself might not mix up, but the position of the Object-items do. So if I do `myTextView.setText(myObjectList.get(position).getName())` in the getView() and I scroll up- and down fast, the text mixes up with other positions. (The position of the Objects in the List compared to the ListView-Items doesn't match anymore). – Kevin Cruijssen Jul 23 '14 at 09:40
  • Do you use the ViewHolder when you set the text? Like: `holder.textView1.setText(myObjectList.get(position).getName())` – Hristova Jul 23 '14 at 11:13
  • @Hristova Yes I do, can't edit my comment above anymore though.. I've made an Edit to my main post (Edit 2) to show my current ArrayAdapter.java class. Nothing is different from your example, except for filling the TextViews/EditTexts with data from the OrderedProductItem fields using the same getView-position for the ordered OrderedProductItem-list. – Kevin Cruijssen Jul 24 '14 at 07:45
  • Do you think you can give me link to the whole code (like GitHub maybe) so I can run and try to see what the problem is. I'll just need you to help me understand the project and we can figure out the problem together. – Hristova Jul 24 '14 at 11:41
  • @Hristova After I fixed some performance issues I had I don't get the fast-scrolling bug anymore. So either the problem was caused by something I now changed/removed, or the problem only occurs when having a bad performance (my guess is the second one). Anyway, I now use your code (again / used something similar before, but I didn't anymore because of this fast-scrolling bug), so I'll accept yours as the correct answer. PS: I couldn't give you the code since I also use a C# Web API, Database data, some Libraries, etc. and the Android App will also be used privately in my company. – Kevin Cruijssen Jul 28 '14 at 14:52
1

That isn't a bug!

It doesn't matter how many times getView() called. Every time that android want show a row in your Listview call this method.

You can override getItem(int position) of Adapter for return every Object you want in every position. Besides of this check your list_item height.

    @Override
    public Object getItem(int position) {
        Object item = null;
        if (position >= 0 && position < mData.size()) {
            item = mData.get(position);
        }
        else {
            Log.e(TAG, "Bad position in getItem");
        }

        return item;
    }

mData is your ArrayList of your data that bound to listview.

And be careful that in getView() you should set values for all of your views. that is important.

Ali Mehrpour
  • 603
  • 8
  • 16
  • My ListView width and height are both `match_parent`, my ListItem outer Layout's width is `match_parent` and height is `wrap_content`. I know this second part is probably causing the problems of getView being called multiple times, but I can't make it `match_parent` since View-Elements of the item should be Visible or Gone based on a changeable state. And about the getItem suggestion, am I still able to set Texts of TextViews and such based on the given item-Object fields? And I guess I still need the getView method, don't I? – Kevin Cruijssen Jul 23 '14 at 08:06
  • About your last added sentence: If I still need to set / reset values of my views in the getView method, what is the point of your suggested getItem? How does this relate to my problem? – Kevin Cruijssen Jul 23 '14 at 08:08
  • You can set Texts of Textviews and such based on object fields and Of course you need getView() method. I said if you don't set all values in getView(), maybe you see wrong data and so you think that is wrong and have wrong position ! – Ali Mehrpour Jul 23 '14 at 23:21
  • Your solution can indeed solve the problem of getView being called too many times, so I only set the Texts of my TextViews once, but it doesn't solve the order of items being mixed up when I scroll up-and down. I use `h.myObject = myObjectList.get(position)` in the getView() and set the Texts also in the getView like this: `holder.textView1.setText(h.myObject.getName())` Since I save the objects in the Holder along with the TextViews and such, they aren't being separated. Still, when I scroll up- and down fast, the order of the items (the Texts of the TextViews) change to a random order. – Kevin Cruijssen Jul 24 '14 at 07:51
0

Why do you save OrderedProductItem object in class ListItemTagHolder ? you always get data with this command

getItem(position)

and you don't need to save this object in your ListItemTagHolder class. Maybe this command

 h.orderedProductItem = Controller.getInstance().getOrderedProductItems().get(position);

return wrong data!! I think if you change above command and move out out of ListItemTagHolder class, your problem will be fixed. :)

Ali Mehrpour
  • 603
  • 8
  • 16
  • Because I also get the Holder in my Activity like so: `MyHolder h = (MyHolder)MyViewItem.getTag();`, so I can access the OrderedProductItem of the Item. If you know a way to get the OrderedProductItem of an Item in the ListActivity without knowing it's position, then I'll give it a try to change it to getItem instead. – Kevin Cruijssen Jul 28 '14 at 09:38