11

I currently have a list view that displays information of things that have to be done.

When an user clicks the item on the listview, then the app checks which item has been clicked and set as done.

If the item has been set as done, it will show an imageview with a check; this imageview is part of the item of the listview.

everything is working well. If I scroll, exit the activity and open it again, uncheck the item, everything works well and shows or hide the imageview of the corresponding listview item.

BUT my problem is that this:

I have 2 buttons to sort the list view items, alphabetically and in order of date. When I click them, they work great. BUT, the app doesn't show the imageview of the items that have been checked.

I know this is because in order to make the checks appear, I need the listview to be fully loaded. I mean, show in the activity with all the info.

My question is:

How can I know when the list view is done populating or loading, so that I can call the method that make sure which items have been check to show the image view?

I have use isfocused(), onfocuschanged(), onWindowChangeState(), and all those type of methods, but none of them works to trigger my method.

Is there any way to be able to know when the listview gets populated to make the check appear on the items that are been show, without any user interaction?

Thanks for your time and help.

PD: I already have the part where the user scroll the list, that part is taken care of.

I'm using a SimpleCursorAdapter to fill the listview.

This is where I fill the list view:

public void mostrarLista(){

        Cursor c = admin.obtenerCursorGastosFijos(ordenadoPor);

          // The desired columns to be bound
          String[] columnas = new String[] {"_id", "Descripcion", "Costo_Estimado", "Fecha_Pago"};

          // the XML defined views which the data will be bound to
          int[] views = new int[] {R.id.IdGstFijo, R.id.DescGstFijo, R.id.CostoGstFijo, R.id.FechaGstFijo };

          // create the adapter using the cursor pointing to the desired data 
          //as well as the layout information
          dataAdapter = new SimpleCursorAdapter(this, R.layout.lista_gastos_fijos, c, columnas, views, 0);

          listaGastos = (ListView) findViewById(R.id.listaGastosFijos1);
          // Assign adapter to ListView
          listaGastos.setAdapter(dataAdapter);

          listaGastos.setOnItemLongClickListener(new OnItemLongClickListener() {

                @Override
                public boolean onItemLongClick(AdapterView<?> Listview, View v,
                        int position, long id) {
                    // TODO Auto-generated method stub
                    Cursor cursor = (Cursor) Listview.getItemAtPosition(position);


                    String idGst=cursor.getString(cursor.getColumnIndexOrThrow("_id"));

                    dialogoOpcionesGst(Integer.parseInt(idGst), v).show();


                    return true;
                }
              });

          listaGastos.setOnScrollListener(new OnScrollListener(){

            @Override
            public void onScroll(AbsListView arg0, int arg1, int arg2,
                    int arg3) {
                // TODO Auto-generated method stub
            }

            @Override
            public void onScrollStateChanged(AbsListView arg0, int arg1) {
                // TODO Auto-generated method stub
                mostrarItemsPagados(listaGastos);
            }

          });

    }

This is the method that I did to navigate the items that are visible and see if they were checked or not

public void mostrarItemsPagados(ListView lista){
        for (int i = 0; i <= lista.getLastVisiblePosition() - lista.getFirstVisiblePosition(); i++){
        View item = (View)lista.getChildAt(i);
        ImageView img = (ImageView)item.findViewById(R.id.imgPagado);
        if(admin.existeGstFijoReal(Integer.parseInt(((TextView)item.findViewById(R.id.IdGstFijo)).getText().toString()))){
            img.setImageResource(R.drawable.img_check);
        }
        else
            img.setImageDrawable(null);
        }
    }

this is the method I use to sort the list:

    public void ordenarNombre(View v){
        ordenadoPor=1;
        mostrarLista();
    }

and well, the layout of the item inside the list is:

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

<TextView
    android:id="@+id/IdGstFijo"
    android:layout_height="match_parent"
    android:layout_width="0dp"
    android:layout_weight="2"
    android:visibility="gone"
    android:gravity="center"
    android:lines="4" />

<TextView
    android:id="@+id/DescGstFijo"
    android:layout_height="match_parent"
    android:layout_width="0dp"
    android:layout_weight="2"
    android:gravity="center"
    android:lines="4" />

 <TextView
    android:id="@+id/CostoGstFijo"
    android:layout_height="match_parent"
    android:layout_width="0dp"
    android:layout_weight="2"
    android:gravity="center"
    android:lines="4"/>

  <TextView
    android:id="@+id/FechaGstFijo"
    android:layout_height="match_parent"
    android:layout_width="0dp"
    android:layout_weight="2"
    android:gravity="center"        
    android:lines="4" />

  <ImageView
    android:id="@+id/imgPagado"
    android:layout_height="match_parent"
    android:layout_width="0dp"
    android:layout_weight="1"

    />

Vini.g.fer
  • 11,639
  • 16
  • 61
  • 90
user2549221
  • 209
  • 1
  • 3
  • 10
  • its too long keep it sort do you want something at the end of list – Trikaldarshiii Sep 05 '13 at 03:32
  • One thing it never ends load only those items are loaded which are currently on display when you scroll then the others are being loaded – Trikaldarshiii Sep 05 '13 at 03:34
  • Hi :) and how to i know when the items that are currently displayed, are done loading? Thats what I need so I can call my method and put the check to the items that the user checked before. – user2549221 Sep 05 '13 at 03:55
  • No no I think your condition is different is your check box is part of list or other than list – Trikaldarshiii Sep 05 '13 at 13:49
  • please put some code Your list_layout file and your java code for inserting data to it – Trikaldarshiii Sep 05 '13 at 13:50
  • when you attach adapter then its okay and its loaded with list view after setting adapter you can presume that its loaded – Trikaldarshiii Sep 06 '13 at 01:23
  • @Hi-TechKitKatAndroid mmm... i kinda dont get it. Do i need to use some kind of event or is there a way to validate this, so it can make the imageview visible when an item is checked? or should i just add the method that do that validation inside the insert data method? – user2549221 Sep 07 '13 at 03:16

5 Answers5

4

You should not rely on the condition of "finish loading data", instead, you should set the image view visibility on the fly.

You should do something like this in your getView method of your list view adapter.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final ItemView item;
    if (convertView == null) {
        item = mLayoutInflator.inflate(R.layout.listlayout)
    } else {
        item = (ItemView) convertView;
    }

    ImageView image = (ImageView)item.findViewById(R.id.yourimageidinitemview);
    if(mTodoTask[posistion].isChecked) {
        image.setVisibility(View.Visible);
    } else {
        image.setVisibility(View.Invisible);
    }
    return item;
}
Robin
  • 10,052
  • 6
  • 31
  • 52
4

My solution:

list = (ListView) findViewById(R.id.list);
list.getViewTreeObserver().addOnPreDrawListener(mOnPreDrawListener);
...
private final ViewTreeObserver.OnPreDrawListener mOnPreDrawListener = new ViewTreeObserver.OnPreDrawListener() {
    @Override
    public boolean onPreDraw() {
        mMessageList.getViewTreeObserver().removeOnPreDrawListener(this);
        // Do what you want to do on data loading here

        return true;
    }
};
mc.dev
  • 2,675
  • 3
  • 21
  • 27
3

You can use a Handler to accomplish this task, like this:

In your activity add the Handler as any other property.

private Handler mListViewDidLoadHanlder = new Handler(new Handler.Callback() { 
    @Override
    public boolean handleMessage(Message message) {
        //Do whatever you need here the listview is loaded
        return false;
    }
});

And inside the getView method of your listview you do the comparison to see if the current position is the last one , so , it will finish (just put it before the return):

public View getView(int position, View convertView, ViewGroup parent) {
         //Your views logic here

         if (position == mObjects.size() - 1) {
                mViewDidLoadHanlder.sendEmptyMessage(0);
            }

         return convertView;
     }
Renan Grativol
  • 1,062
  • 15
  • 20
  • 3
    The number of items displayed in a listview doesn't correlate to the total number in the dataset (mObjects). The list will complete it's rendering when the last "visible" item is displayed and NOT when the last item in the dataset is displayed. – Johann Nov 27 '14 at 20:03
3

It worked for me (mc.android.developer):

listview.getViewTreeObserver().addOnPreDrawListener(OnPreDrawListener);

private final ViewTreeObserver.OnPreDrawListener OnPreDrawListener = new ViewTreeObserver.OnPreDrawListener() {
    @Override
    public boolean onPreDraw() {

    //do changes
        return true;
    }
};
Abandoned Cart
  • 4,512
  • 1
  • 34
  • 41
2

Ok, i manage to solve the problem.

All i had to do, was override the getView method as said.

But, since Im using a SimpleCursorAdapter extended Class, I had to do something like this:

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

     View item = super.getView(position, convertView, parent);

     //Validation code for drawing or not the check image


     return item;
}

So, that did the work, and now everytime the listview is reordered or drawn or scrolled the views are refreshed correctly.

Thanks guys for the help

user2549221
  • 209
  • 1
  • 3
  • 10