Autore Topic: Creare un custom Adapter  (Letto 602 volte)

Offline felasandroid

  • Utente normale
  • ***
  • Post: 345
  • Respect: +10
    • Github
    • balduzziantonio
    • balduzziantonio.unifi
    • Mostra profilo
  • Dispositivo Android:
    Huawei P8 Lite
  • Play Store ID:
    FelasTech
  • Sistema operativo:
    Windows 10
Creare un custom Adapter
« il: 07 Maggio 2015, 16:10:48 CEST »
0
CIao

mi sto cimentando a creare un CustomAdapter perchè mi servirebbe inserire un bottone per ogni elemento di una ListView.

Il primo approccio era questo:

Codice (Java): [Seleziona]
 list.setAdapter(new SimpleAdapter(
                getActivity(), mlist, R.layout.item_list_avvisi,
                new String[]{"Nome", "Cognome", "Titolo", "Info"}, new int[]{
                R.id.nome, R.id.cognome, R.id.titolo, R.id.info}));

Solo che visto che il layout "item_list_avvisi" contiene una ImageButton dove cliccarci, questo approccio non va più bene e devo crearmi un CustomAdapter.
Ho iniziato a crearlo ma come faccio a settare i dati?

per ora ho fatto questo:


Codice (Java): [Seleziona]
public class CustomAdapter extends BaseAdapter {


    Context context;
    private LayoutInflater mInflater;
    ArrayList<HashMap<String, Object>> mlist;

    public CustomAdapter(Context context,ArrayList<HashMap<String, Object>> mlist){

        this.context = context;
        this.mlist=mlist;
        mInflater = ( LayoutInflater )context.
                getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    }
    public class ViewHolder {

        public ImageButton mImageButton;
        public TextView mTitleView;
        public TextView mNomeView;
        public TextView mCognomeView;
        public TextView mInfoView;

    }


    @Override
    public int getCount() {
        return 0;
    }

    @Override
    public Object getItem(int position) {

        if (mlist != null && position >= 0 && position < getCount()) {
            return mlist.get(position);
        }
        return null;
    }

    @Override
    public long getItemId(int position) {

        return position;
    }

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

        View view = convertView;

        if (view == null) {

            view = mInflater.inflate(R.layout.item_list_avvisi, null);
            viewHolder = new ViewHolder();

            viewHolder.mImageButton = (ImageButton) view.findViewById(R.id.imageButton);
            viewHolder.mCognomeView = (TextView) view.findViewById(R.id.cognome);
            viewHolder.mNomeView = (TextView) view.findViewById(R.id.nome);
            viewHolder.mTitleView = (TextView) view.findViewById(R.id.titolo);
            viewHolder.mInfoView = (TextView) view.findViewById(R.id.info);

            viewHolder.mImageButton.setClickable(true);
            viewHolder.mImageButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {



                    Intent shareIntent = new Intent();
                    shareIntent.setAction(Intent.ACTION_SEND);

                    shareIntent.putExtra(Intent.EXTRA_TEXT, (String) "Avviso " + viewHolder.mNomeView.getText().toString()
                            );
                    shareIntent.setType("text/plain");
                    context.startActivity(shareIntent);


                }
            });
 view.setTag(viewHolder);

        }
        else {
            viewHolder = (ViewHolder) view.getTag();
        }

        setData(viewHolder, mlist, position);

        return view;
    }
    private void setData(ViewHolder viewHolder, ArrayList<HashMap<String, Object>> mlist) {


        viewHolder.mCognomeView.setText(mlist.get(position).get("Cognome").toString());


    }
}


Son riuscito a farlo funzionare ma quello che non mi riesce è come faccio a far funzionare a dovere l'evento click sull ImageButton ?

Perchè in pratica in questa maniera mi prende il valore ma non dell'elemento selezionato ma del successivo..
« Ultima modifica: 07 Maggio 2015, 18:10:26 CEST da felasandroid »

Offline tonno16

  • Utente storico
  • *****
  • Post: 1184
  • Respect: +57
    • Mostra profilo
  • Dispositivo Android:
    moto g
  • Play Store ID:
    Diego Tonini
  • Sistema operativo:
    OpenSuse
Re:Creare un custom Adapter
« Risposta #1 il: 07 Maggio 2015, 19:40:31 CEST »
0
Mi sembra un po mal incasinato il tutto. Hai seguito la guida presente su questo forum?

Offline felasandroid

  • Utente normale
  • ***
  • Post: 345
  • Respect: +10
    • Github
    • balduzziantonio
    • balduzziantonio.unifi
    • Mostra profilo
  • Dispositivo Android:
    Huawei P8 Lite
  • Play Store ID:
    FelasTech
  • Sistema operativo:
    Windows 10
Re:Creare un custom Adapter
« Risposta #2 il: 08 Maggio 2015, 17:35:35 CEST »
0
Mi sembra un po mal incasinato il tutto. Hai seguito la guida presente su questo forum?

No la guida qui no. In pratica il mio problema è che non riesco a prendere il valore giusto dell'elemento nella lista.
Cioè ogni elemento della lista ha un bottone l'evento associato a questo bottone è creare un intent. Il problema è associare al bottone cliccato l'elemento giusto della lista dal Custom Adapter.
Ho provato a mettere final position ma il problema è che quando scorro la lista i valori passano da 0 a 3 e poi ancora riparte da 0 quindi non fa..

Offline tonno16

  • Utente storico
  • *****
  • Post: 1184
  • Respect: +57
    • Mostra profilo
  • Dispositivo Android:
    moto g
  • Play Store ID:
    Diego Tonini
  • Sistema operativo:
    OpenSuse
Re:Creare un custom Adapter
« Risposta #3 il: 08 Maggio 2015, 17:39:48 CEST »
0
Setta un clicklistener direttamente nell' adapter. Hai il context. Puoi fare startActivity()

Offline felasandroid

  • Utente normale
  • ***
  • Post: 345
  • Respect: +10
    • Github
    • balduzziantonio
    • balduzziantonio.unifi
    • Mostra profilo
  • Dispositivo Android:
    Huawei P8 Lite
  • Play Store ID:
    FelasTech
  • Sistema operativo:
    Windows 10
Re:Creare un custom Adapter
« Risposta #4 il: 08 Maggio 2015, 17:53:27 CEST »
0
Setta un clicklistener direttamente nell' adapter. Hai il context. Puoi fare startActivity()

e ma facendo in questo modo basta che clicco in un punto qualsiasi dell'elemento giusto?

Offline tonno16

  • Utente storico
  • *****
  • Post: 1184
  • Respect: +57
    • Mostra profilo
  • Dispositivo Android:
    moto g
  • Play Store ID:
    Diego Tonini
  • Sistema operativo:
    OpenSuse
Re:Creare un custom Adapter
« Risposta #5 il: 08 Maggio 2015, 17:56:01 CEST »
0
No. Intendo di settore un click listener sul bottone dentro l'adapter. Non un clickItemListener sulla listView

Offline felasandroid

  • Utente normale
  • ***
  • Post: 345
  • Respect: +10
    • Github
    • balduzziantonio
    • balduzziantonio.unifi
    • Mostra profilo
  • Dispositivo Android:
    Huawei P8 Lite
  • Play Store ID:
    FelasTech
  • Sistema operativo:
    Windows 10
Re:Creare un custom Adapter
« Risposta #6 il: 08 Maggio 2015, 17:59:01 CEST »
0
No. Intendo di settore un click listener sul bottone dentro l'adapter. Non un clickItemListener sulla listView


Si dentro il getView ho messo:

Codice (Java): [Seleziona]
 viewHolder.mImageButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    Intent shareIntent = new Intent();
                    shareIntent.setAction(Intent.ACTION_SEND);
......

Offline tonno16

  • Utente storico
  • *****
  • Post: 1184
  • Respect: +57
    • Mostra profilo
  • Dispositivo Android:
    moto g
  • Play Store ID:
    Diego Tonini
  • Sistema operativo:
    OpenSuse
Re:Creare un custom Adapter
« Risposta #7 il: 08 Maggio 2015, 17:59:45 CEST »
0
Cosi intendevo. Deve funzionare

Offline felasandroid

  • Utente normale
  • ***
  • Post: 345
  • Respect: +10
    • Github
    • balduzziantonio
    • balduzziantonio.unifi
    • Mostra profilo
  • Dispositivo Android:
    Huawei P8 Lite
  • Play Store ID:
    FelasTech
  • Sistema operativo:
    Windows 10
Re:Creare un custom Adapter
« Risposta #8 il: 08 Maggio 2015, 18:10:23 CEST »
0
Cosi intendevo. Deve funzionare

purtroppo non funziona.. Questo è il getView completo:

 
Codice (Java): [Seleziona]
@Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        view = convertView;

        if (view == null) {

            view = mInflater.inflate(R.layout.item_list_avvisi, parent, false);
            viewHolder = new ViewHolder();

            viewHolder.mImageButton = (ImageButton) view.findViewById(R.id.imageButton);
            viewHolder.mCognomeView = (TextView) view.findViewById(R.id.cognome);
            viewHolder.mNomeView = (TextView) view.findViewById(R.id.nome);
            viewHolder.mTitleView = (TextView) view.findViewById(R.id.titolo);
            viewHolder.mInfoView = (TextView) view.findViewById(R.id.info);

            viewHolder.mImageButton.setClickable(true);


            viewHolder.mImageButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    Intent shareIntent = new Intent();
                    shareIntent.setAction(Intent.ACTION_SEND);


                    shareIntent.putExtra(Intent.EXTRA_TEXT, (String) "Avviso: " + mlist.get(position).get("Nome").toString() + " " +
                                    mlist.get(position).get("Cognome").toString() + "\n" +
                                    mlist.get(position).get("Titolo").toString() + "\n" +
                                    mlist.get(position).get("Info").toString()
                    );
                    shareIntent.setType("text/plain");
                    context.startActivity(shareIntent);


                }
            });

            view.setTag(viewHolder);

        } else {
            viewHolder = (ViewHolder) view.getTag();
        }

        setData(viewHolder, mlist, position);

        return view;
    }

In questa maniera non fa perchè position va da 0 a 3 e poi cicla da 0 a 3.. senza mettere position a final però non riesco a associare l'ImageButton all'elemento cliccato..non so se son stato chiaro

Offline tonno16

  • Utente storico
  • *****
  • Post: 1184
  • Respect: +57
    • Mostra profilo
  • Dispositivo Android:
    moto g
  • Play Store ID:
    Diego Tonini
  • Sistema operativo:
    OpenSuse
Re:Creare un custom Adapter
« Risposta #9 il: 08 Maggio 2015, 18:18:38 CEST »
0
Non ti sei spiegato per niente. Di logica deve funzionare per forza. Se non funziona sbagli qualcosa. Non capisco cosa intendi per ciclo.
Ti consiglio di riscrivere i metodi. È brutto vedere get(parametro). Metti getCognome e getNome() non fa differenza ma è intuitivo.

Offline felasandroid

  • Utente normale
  • ***
  • Post: 345
  • Respect: +10
    • Github
    • balduzziantonio
    • balduzziantonio.unifi
    • Mostra profilo
  • Dispositivo Android:
    Huawei P8 Lite
  • Play Store ID:
    FelasTech
  • Sistema operativo:
    Windows 10
Re:Creare un custom Adapter
« Risposta #10 il: 08 Maggio 2015, 18:30:57 CEST »
0
Non ti sei spiegato per niente. Di logica deve funzionare per forza. Se non funziona sbagli qualcosa. Non capisco cosa intendi per ciclo.
Ti consiglio di riscrivere i metodi. È brutto vedere get(parametro). Metti getCognome e getNome() non fa differenza ma è intuitivo.

La lista è un ArrayList<HashMap<String, Object>> per questo c'è "Nome", "Cognome"..Ad ogni modo lasciando perdere quello che stampa, io cliccando sull'ImageButton di un'elemento voglio prendere il testo che c'è dentro la TexView sempre di quell'elemento..ecco questo non mi riesce..

Ho provato quasi di tutto ad esempio:

Codice (Java): [Seleziona]
viewHolder.mImageButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    Intent shareIntent = new Intent();
                    shareIntent.setAction(Intent.ACTION_SEND);

                   viewHolder.mCognomeView.getText().toString());
....

oppure

Codice (Java): [Seleziona]
viewHolder.mImageButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    Intent shareIntent = new Intent();
                    shareIntent.setAction(Intent.ACTION_SEND);

TextView tx = (TextView) v.findViewById(R.id.cognome);
tx.getText().toString()


ma nulla mi prende valori sbagliati da quello che io ho cliccato.

Riassunto:

Ho una listview e un custom  adapter. Ogni elemento del custom adapter ha un'ImageButton e delle TextView.
Benissimo, setto il clicklistener per l'ImageButton e cliccando voglio prendere dei valori da TextView di quell'elemento. Questi valori non mi riesce prenderli correttamente.
« Ultima modifica: 08 Maggio 2015, 18:33:53 CEST da felasandroid »

Offline tonno16

  • Utente storico
  • *****
  • Post: 1184
  • Respect: +57
    • Mostra profilo
  • Dispositivo Android:
    moto g
  • Play Store ID:
    Diego Tonini
  • Sistema operativo:
    OpenSuse
Re:Creare un custom Adapter
« Risposta #11 il: 08 Maggio 2015, 18:34:52 CEST »
0
Non ha senso quello che fai.
Alla riga i esima de hai il tuo i esimo oggetto dell' array lista.

Tutti i campi del viewholder sono ovviamente texview radio imageview etc....

Tu nel getView devi impostare i testi in ogni texview. E sti testi li prendi dall' oggetto iesimo prima citato.
Se applichi onCkickListener() al bottone è inutile che vai a pescare il testo dalla texview. Il valore stringa già ce lo devi avere.

Post unito: [time]08 Maggio 2015, 18:49:20 CEST[/time]
Ho capito benissimo cosa vuoi fare. Quando vado al PC te lo scrivo

Post unito: 08 Maggio 2015, 18:55:28 CEST
Un esempio. Ho una lista di Exam. List<Exam>:

Codice (Java): [Seleziona]
@Override
    public View getView(int position, View v, ViewGroup parent) {

        Exam e = getItem(position);
        ExamHolder holder;
        if(v==null){
            v = mInflater.inflate(mLayoutResId,parent,false);
            holder = new ExamHolder();
            holder.tvName = (TextView) v.findViewById(R.id.tvName);
            holder.tvMark = (TextView) v.findViewById(R.id.tvMark);
            holder.tvDate = (TextView) v.findViewById(R.id.tvDate);
            holder.tvCfu  = (TextView) v.findViewById(R.id.tvCfu);

            v.setTag(holder);
        } else {
            holder = (ExamHolder) v.getTag();
        }

        holder.tvCfu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String nome = e.getExamName();
            }
        });
        holder.tvName.setText(e.getExamName());
        holder.tvMark.setText(e.getMark());
        holder.tvCfu.setText(e.getCfu());
        holder.tvDate.setText(Utils.getDateFromMillis(e.getDate()));

        return v;
    }

dove vedi String nome, crea il tuo intent. e come putExtra non ho messo tvDate.getText().toString. Ho messo proprio un oggetot stringa ricavato da e. Quel "e" è l'i-esimo oggetto Exam alla riga i-esima
« Ultima modifica: 08 Maggio 2015, 18:55:28 CEST da tonno16, Reason: Merged DoublePost »

Offline felasandroid

  • Utente normale
  • ***
  • Post: 345
  • Respect: +10
    • Github
    • balduzziantonio
    • balduzziantonio.unifi
    • Mostra profilo
  • Dispositivo Android:
    Huawei P8 Lite
  • Play Store ID:
    FelasTech
  • Sistema operativo:
    Windows 10
Re:Creare un custom Adapter
« Risposta #12 il: 08 Maggio 2015, 19:18:39 CEST »
0
allora la mia lista è un ArrayList<HashMap<String, Object>>.

Quindi ho modificato il codice seguendo quello che hai fatto in questa maniera:

Codice (Java): [Seleziona]
 @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        view = convertView;
        e = (HashMap<String, Object>) getItem(position);

        if (view == null) {

            view = mInflater.inflate(R.layout.item_list_avvisi, parent, false);
            viewHolder = new ViewHolder();

            viewHolder.mImageButton = (ImageButton) view.findViewById(R.id.imageButton);
            viewHolder.mCognomeView = (TextView) view.findViewById(R.id.cognome);
            viewHolder.mNomeView = (TextView) view.findViewById(R.id.nome);
            viewHolder.mTitleView = (TextView) view.findViewById(R.id.titolo);
            viewHolder.mInfoView = (TextView) view.findViewById(R.id.info);

            viewHolder.mImageButton.setClickable(true);


            view.setTag(viewHolder);

        } else {
            viewHolder = (ViewHolder) view.getTag();
        }

        viewHolder.mImageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent shareIntent = new Intent();
                shareIntent.setAction(Intent.ACTION_SEND);


                Log.d("TAG", e.get("Nome").toString());


                shareIntent.putExtra(Intent.EXTRA_TEXT, (String) "Avviso : " + e.get("Nome").toString() + " " +
                                mCognome + "\n" +
                                mTitolo + "\n" +
                                mInfo
                );
                shareIntent.setType("text/plain");
                context.startActivity(shareIntent);


            }
        });

      viewHolder.mCognomeView.setText(e.get("Cognome").toString());
        viewHolder.mNomeView.setText(e.get("Nome").toString());
        viewHolder.mTitleView.setText(e.get("Titolo").toString());
        viewHolder.mInfoView.setText(e.get("Info").toString());

        return view;
    }


}


solo che
Codice (Java): [Seleziona]
e.get("Nome").toString() continua a prendermi il valore sbagliato..Magari sbaglio il getItem?

Post unito: 09 Maggio 2015, 13:49:55 CEST

Scusa se ti stresso anzi grazie per gli sforzi ad aiutarmi.
Son 2 giorni che ci sbatto la testa ma non ho trovato la soluzione. Forse sbaglio nell'impostare il getItem o getItemId ? meglio che provo a crearmi una lista di oggetti diversa da quella che ho fatto? (cioè senza HashMap ma lista semplice)
« Ultima modifica: 09 Maggio 2015, 13:49:55 CEST da felasandroid, Reason: Merged DoublePost »