Autore Topic: Ottenere la posizione dell'ultimo item visualizzato all'interno della listView  (Letto 518 volte)

Offline ValerioAdo

  • Utente normale
  • ***
  • Post: 316
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Huawei Ascend g525
  • Sistema operativo:
    windows 8.1
Salve a tutti!

Con la mia applicazione carico dei dati scaricati da un db online all'interno di una listView con un adapter custom.
Quando faccio il refresh di tale lista devo riscaricare i dati da inserire nella lista, ma se nel frattempo (cioè prima che l'app arrivi a settare l'adapter per la listView)  scrollo verso il basso la lista (o comunque non sono più al primo item) al momento di settare l'adapter mi ritrovo al primo primo elemento dalla lista.

Io vorrei che la lista non tornasse al suo primo elemento ma che rimanga all'altezza dell'ultimo elemento visualizzato...

Al momento io faccio così per ottenere la posizione:

Codice (Java): [Seleziona]
 listview1.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView absListView, int i) {

            }

            @Override
            public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

               //lisview1Position=visibleItemCount;

                if (firstVisibleItem == 0) {
                    swipeView.setEnabled(true);
                    lisview1Position=0;
                } else {
                    swipeView.setEnabled(false);
                }



            }
        });

Ma al momento di andare a settare la posizione molte volte sbaglia....

Ovviamente setto la posizione in questo modo:
Codice (Java): [Seleziona]
   listview1.setSelection(lisview1Position);

Avete qualche suggerimento?

Grazie mille in anticipo!

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 596
  • Respect: +133
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Samsung Galaxy Nexus
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 7 x64
Re:Ottenere la posizione dell'ultimo item visualizzato all'interno della listView
« Risposta #1 il: 24 Novembre 2015, 15:30:03 CET »
+1

Mi permetto di suggerirti un approccio differente.

Modifica l'adapter aggiungendo un metodo che ti permette di aggiornare i dati senza cambiare posizione del ListView.

Esempio:
Codice (Java): [Seleziona]
        protected class TuoAdapter extends BaseAdapter {
                Context ctx;
                int res;
                TuaClasse[] data;
               
                public TuoAdapter(Context context, int resource, List<TuaClasse> objects) {
                        this(context, resource, objects.toArray(new TuaClasse[objects.size()]));
                }
               
                public TuoAdapter(Context context, int resource, TuaClasse[] objects) {
                        ctx = context;
                        res = resource;
                        data = objects;
                }

                public void refill(TuaClasse[] objects) {
                        if (objects == null) {
                                data = new TuaClasse[0];
                        } else {
                                data = objects;
                        }
                        notifyDataSetChanged();
                }

                //Altri metodi adapter

e quando ricevi i dati aggiornati, invece di creare un nuovo adapter invochi refill su quello esistente (del quale ovviamente devi mantenere un riferimento)

Codice (Java): [Seleziona]
mioAdapter.refill(nuoviDati);
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline ValerioAdo

  • Utente normale
  • ***
  • Post: 316
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Huawei Ascend g525
  • Sistema operativo:
    windows 8.1
Re:Ottenere la posizione dell'ultimo item visualizzato all'interno della listView
« Risposta #2 il: 24 Novembre 2015, 16:11:56 CET »
0
Ho capito cosa dovrei fare... il problema è che il mio adapter è un po più articolato... nel senso che passo all'adapter le variabili tutte in una volta in modo da fare meno chiamate possibili.
Infatti il codice che uso per il set adapter è questa:

Codice (Java): [Seleziona]
listview1.setAdapter(new LazyImageLoadAdapter(getActivity(), Valori.mStrings, Valori.Name, Valori.Left, Valori.quantity, Valori.Description, Valori.Comm, Valori.price, Valori.PrezzoOrig));
ed l'adapter è questo:

Codice (Java): [Seleziona]
public class LazyImageLoadAdapter extends BaseAdapter implements View.OnClickListener {

    private Activity activity;
    private String[] Name;
    private String[] DescriptionText;
    private String[] PriceText;
    private String[] Quantity;
    private String[] URL;
    private String[] Commerciante;
    private String[] Rimasta;
    private String[] VecchioP;

    private static LayoutInflater inflater = null;
    public ImageLoader imageLoader;
    Context mcontext;


    public LazyImageLoadAdapter(Activity a, String[] link, String[] name, String[] Left, String[] quantity, String[] description, String[] commerciante, String[] prezzo, String[] PrezzoO) {


        activity = a;
        URL = link;
        Name = name;
        DescriptionText = description;
        PriceText = prezzo;
        Quantity = quantity;
        Commerciante = commerciante;
        Rimasta = Left;
        VecchioP = PrezzoO;

        if (Valori.Ended == 1) {
            return;
        }

        inflater = (LayoutInflater) activity.
                getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        // Create ImageLoader object to download and show image in list
        // Call ImageLoader constructor to initialize FileCache
        imageLoader = new ImageLoader(activity.getApplicationContext());

        this.mcontext = activity.getApplicationContext();
    }

    public int getCount() {
        return DescriptionText.length;
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    /*********
     * Create a holder Class to contain inflated xml file elements
     *********/

    public static class ViewHolder {

        public TextView Name;
        public TextView Price;
        public TextView Quantity;
        public TextView Desc;
        public TextView Comm;
        public TextView OldPrice;
        public TextView Left;
        public ImageView image;
        public ImageView quantityBar;

    }

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

        View vi = convertView;
        ViewHolder holder;

        if (convertView == null) {

            imageLoader = new ImageLoader(activity.getApplicationContext());

            /****** Inflate tabitem.xml file for each row ( Defined below ) *******/
            vi = inflater.inflate(R.layout.vetrina_row, null);

            /****** View Holder Object to contain tabitem.xml file elements ******/

            holder = new ViewHolder();
            holder.Name = (TextView) vi.findViewById(R.id.Name);
            holder.OldPrice = (TextView) vi.findViewById(R.id.Price2);
            holder.Price = (TextView) vi.findViewById(R.id.Price);
            holder.Quantity = (TextView) vi.findViewById(R.id.Quantity);
            holder.Left = (TextView) vi.findViewById(R.id.Quantity2);
            holder.image = (ImageView) vi.findViewById(R.id.Preview);
            holder.Desc = (TextView) vi.findViewById(R.id.Description);
            holder.Comm = (TextView) vi.findViewById(R.id.Comm);
            holder.quantityBar=(ImageView) vi.findViewById(R.id.imageView11);

            /************  Set holder with LayoutInflater ************/
            vi.setTag(holder);
        } else
            holder = (ViewHolder) vi.getTag();


        holder.Name.setText(Name[position]);
        holder.Price.setText(VecchioP[position]);
        holder.OldPrice.setText(PriceText[position] + "€");
        //holder.Left.setText("Q.tà: " + Rimasta[position]);
        holder.Quantity.setText( Rimasta[position]+"/" + Quantity[position]);
        holder.Desc.setText(DescriptionText[position]);
        holder.Comm.setText(Commerciante[position]);
        ImageView image = holder.image;

        holder.Price.setPaintFlags(holder.Price.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);

        int valore = Integer.parseInt(Quantity[position]);
        int percentuale=35;
        int percent = valore * percentuale / 100;
        int left=Integer.parseInt(Rimasta[position]);

        if(left<=percent){
            //   holder.SoldOut.setBackgroundResource(R.drawable.sold_out);
            holder.quantityBar.setBackgroundResource(R.drawable.disponibililow);
        }else{
            //   holder.SoldOut.setVisibility(View.INVISIBLE);
            holder.quantityBar.setBackgroundResource(R.drawable.disponibili);
        }

        if(Rimasta[position].equals("0")){
            holder.quantityBar.setBackgroundResource(R.drawable.esaurito);
            holder.Quantity.setVisibility(View.INVISIBLE);
        }

        //DisplayImage function from ImageLoader Class
        if (URL[position] != null && !URL[position].isEmpty()) {
            imageLoader.DisplayImage(URL[position], image);
        }

        /******** Set Item Click Listner for LayoutInflater for each row ***********/
        // vi.setOnClickListener(new OnItemClickListener(position));
        return vi;
    }

    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub

    }

Quindi mi ritrovo un po perso....soprattutto nella parte "TuaClasse[] objects"

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 596
  • Respect: +133
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Samsung Galaxy Nexus
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 7 x64
Re:Ottenere la posizione dell'ultimo item visualizzato all'interno della listView
« Risposta #3 il: 24 Novembre 2015, 16:21:04 CET »
+1
Aggiungi

Codice (Java): [Seleziona]
    public refill(String[] link, String[] name, String[] Left, String[] quantity, String[] description, String[] commerciante, String[] prezzo, String[] PrezzoO) {
        URL = link;
        Name = name;
        DescriptionText = description;
        PriceText = prezzo;
        Quantity = quantity;
        Commerciante = commerciante;
        Rimasta = Left;
        VecchioP = PrezzoO;

        notifyDataSetChanged();
    }

tieni un riferimento dell'adapter:

Codice (Java): [Seleziona]
mioAdapter = new LazyImageLoadAdapter(getActivity(), Valori.mStrings, Valori.Name, Valori.Left, Valori.quantity, Valori.Description, Valori.Comm, Valori.price, Valori.PrezzoOrig);
listview1.setAdapter(mioAdapter);

e poi quando fai refresh chiama:

Codice (Java): [Seleziona]
mioAdapter.refill(Valori.mStrings, Valori.Name, Valori.Left, Valori.quantity, Valori.Description, Valori.Comm, Valori.price, Valori.PrezzoOrig);
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline ValerioAdo

  • Utente normale
  • ***
  • Post: 316
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Huawei Ascend g525
  • Sistema operativo:
    windows 8.1
Re:Ottenere la posizione dell'ultimo item visualizzato all'interno della listView
« Risposta #4 il: 24 Novembre 2015, 16:50:11 CET »
0
Ho risolto!

Siccome inserivo le liste in un ViewPager (anche lui con il suo adapter ovviamente) dovevo aggiornare l'adapter sia della lista che del pager!

Ora funziona perfettamente ^^

comunque ho scritto così il codice per aggiornare:

Codice (Java): [Seleziona]
           LazyImageLoadAdapter mioAdapter = new VetrinaLazyImageLoadAdapter(getActivity(), Valori.mStrings, Valori.Name, Valori.Left, Valori.quantity, Valori.Description, Valori.Comm, Valori.price, Valori.PrezzoOrig);

            if(listview1.getAdapter()==null) {
                 listview1.setAdapter(mioAdapter);
                 listview1.setDivider(null);
            }else{
                mioAdapter.refill(Valori.mStrings, Valori.Name, Valori.Left, Valori.quantity, Valori.Description, Valori.Comm, Valori.price, Valori.PrezzoOrig);
            }
.....

  if(Valori.Pager.getAdapter()==null) {
                Valori.Pager.setAdapter(adapter);
            }else{
                adapter.update(pages);
            }

così scrivo direttamente nell'AsynkTask invece che nel refresh

Grazie mille ^^

Offline ValerioAdo

  • Utente normale
  • ***
  • Post: 316
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Huawei Ascend g525
  • Sistema operativo:
    windows 8.1
Re:Ottenere la posizione dell'ultimo item visualizzato all'interno della listView
« Risposta #5 il: 26 Novembre 2015, 08:59:05 CET »
0
Riapro questo post perché mi sono ritrovato davanti ad un problema non piccolo....

Ora il refill non mi aggiorna la lista, nel senso che se mando il refresh e so che c'è stato un cambiamento la lista non è aggiornata.

Ho provato a fare il debug sull'adapter quando refill viene chiamato, funziona correttamente ma poi non passa i dati da aggiornati al GetView.

Cosa dovrei fare?

Grazie mille per l'aiuto e la pazienza

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 596
  • Respect: +133
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Samsung Galaxy Nexus
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 7 x64
Re:Ottenere la posizione dell'ultimo item visualizzato all'interno della listView
« Risposta #6 il: 26 Novembre 2015, 10:37:55 CET »
+1
cambia

Codice (Java): [Seleziona]
        LazyImageLoadAdapter mioAdapter = new VetrinaLazyImageLoadAdapter(getActivity(), Valori.mStrings, Valori.Name, Valori.Left, Valori.quantity, Valori.Description, Valori.Comm, Valori.price, Valori.PrezzoOrig);

        if(listview1.getAdapter()==null) {
                listview1.setAdapter(mioAdapter);
                listview1.setDivider(null);
        }else{
                mioAdapter.refill(Valori.mStrings, Valori.Name, Valori.Left, Valori.quantity, Valori.Description, Valori.Comm, Valori.price, Valori.PrezzoOrig);
        }

in
Codice (Java): [Seleziona]
        LazyImageLoadAdapter mioAdapter = (LazyImageLoadAdapter)listview1.getAdapter();

        if(mioAdapter==null) {
                mioAdapter = new VetrinaLazyImageLoadAdapter(getActivity(), Valori.mStrings, Valori.Name, Valori.Left, Valori.quantity, Valori.Description, Valori.Comm, Valori.price, Valori.PrezzoOrig);
                listview1.setAdapter(mioAdapter);
                listview1.setDivider(null);
        }else{
                mioAdapter.refill(Valori.mStrings, Valori.Name, Valori.Left, Valori.quantity, Valori.Description, Valori.Comm, Valori.price, Valori.PrezzoOrig);
        }
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline ValerioAdo

  • Utente normale
  • ***
  • Post: 316
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Huawei Ascend g525
  • Sistema operativo:
    windows 8.1
Re:Ottenere la posizione dell'ultimo item visualizzato all'interno della listView
« Risposta #7 il: 26 Novembre 2015, 11:25:37 CET »
0
Ora funziona!

Subito non funzionava ma ho fatto una piccola modifica al pager per farlo funzionare

Codice (Java): [Seleziona]
        if (Valori.Pager.getAdapter() == null) {//se l'adapter del pager non è presento lo carico nuovo
                    Valori.Pager.setAdapter(adapter);
                } else {//se invece è presente lo aggiorno
                    adapter.update(pages);
                    adapter.notifyDataSetChanged();
                }

Perfetto, ti ringrazio tantissimo!