setOnClickListener Adapter on a Listview line object

Asked

Viewed 392 times

0

My app has a Listview, in which you receive information from a Json (URL), and each line has an Imageview that when you click, the line information will be added as "Favorite".

For this, I created two images (iconfav_off and iconfav_on),

So I created the layout by getting the iconfav_off as a starter.

<ImageView
    android:layout_width="30dp"
    android:src="@drawable/iconfav_off"
    android:layout_alignParentTop="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true"
    android:layout_height="30dp"
    android:id="@+id/starFav"
    android:tag="off"/>

When clicking on this specific object (not in the Listview line), I need it to be changed to "iconfav_on".

For this, I created a setOnClickListener for the object, inside my Adapter

    ImageView Fav = (ImageView) convertView.findViewById(R.id.starFav);
    Fav.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            FavStatus = String.valueOf(view.getTag());
            if(FavStatus.equals("off")){
                Toast.makeText(getContext(), "ADICIONADO AOS FAVORITOS", Toast.LENGTH_SHORT).show();
                view.setBackgroundResource(R.drawable.iconfav_on);
                view.setTag("on");
            }
            if(FavStatus.equals("on")){
                Toast.makeText(getContext(), "REMOVIDO DOS FAVORITOS", Toast.LENGTH_SHORT).show();
                view.setBackgroundResource(R.drawable.iconfav_off);
                view.setTag("off");
            }

        }
    });

It checks the tag (whether off or on) and performs the exchange.

However MY DIFFICULTY is being that the switch is happening on several lines, when it should be happening only on the object of the clicked line.

I tried it this way and the result was the same

    ImageView Fav = (ImageView) convertView.findViewById(R.id.starFav);
    Fav.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            ImageView FavStatus = (ImageView) ((View) view.getParent()).findViewById(R.id.starFav);
            FavStatus.setBackgroundResource(R.drawable.iconfav_on);
        }
    });

I also adjusted the code to get the "position" of the clicked line, but I don’t know how to set the image of the object of that position, and in this case, I lose the "Tag" control "off" or "on".

    ImageView Fav = (ImageView) convertView.findViewById(R.id.starFav);
    Fav.setTag(position);
    Fav.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            View parentRow = (View) view.getParent();
            ListView listView = (ListView) parentRow.getParent();
            final int position = listView.getPositionForView(parentRow);

            Toast.makeText(getContext(), "botão da posição: " + view.getTag(), Toast.LENGTH_LONG).show();

            ?????

        }
    });

If anyone can help me, in advance I’d appreciate it

UPDATE

Below is the complete Adapter

class AgendaAdapter extends ArrayAdapter<Agenda> {

AgendaAdapter(Context context, ArrayList<Agenda> agenda) {
    super(context, 0, agenda);
}

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

    final Agenda agenda = getItem(position);

    if (convertView == null) {
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.agenda_linha, parent, false);
    }

    TextView tvTitulo = (TextView) convertView.findViewById(R.id.clubeAgendaTitulo);
    TextView tvData = (TextView) convertView.findViewById(R.id.clubeAgendaData);
    TextView tvHora = (TextView) convertView.findViewById(R.id.clubeAgendaHora);

    assert agenda != null;

    tvTitulo.setText(agenda.Nome);
    tvData.setText(agenda.Data);
    tvHora.setText(agenda.Hora);


/***********************************************/
/******TRECHOS DAS TENTATIVAS ANTERIORES *******/
/***********************************************/

    return convertView;
}

RESOLVED IN RESPONSE

  • I believe we would need to see the code of Adapter. I do not recommend making changes only in View, because the ListView uses a recycling standard of Views, if you do not treat the attribute FavStatus of the model in its Adapter, will not have much solution. My recommendation is to leave for the RecyclerView, because you won’t need to treat View outside the Adapter.

  • @Wakim, I put an Adapter code update. How would I use Recyclerview in my code? Is it really the case to use Recyclerview ? What is the use of this function ?

  • So, as its layout is very simple, it is convenient to keep using Listview. But for more complex layouts it is recommended to make use of it instead of Listview. Getting back to the problem, you need to update your Imageview also within getView of your Adapter, based on the Agenda item. For this you need to update the Agenda item instead of adding a View Tag. If you can’t, I can give you an answer early tomorrow.

1 answer

2


for those who had the same doubt that I, just as they helped me, I will leave down the code in which solved my problem, so that I can help others.

I was able to solve, from @Wakim’s guidance, in the comments:

... you need to update your Imageview also within getView of your Adapter, based on the Agenda item. For this you need to update the Agenda item instead of adding a View Tag.

As a beginner, I don’t know if the code is written properly, but it worked.

Before the question, the code snippet below, enters the space commented "EXCERPTS FROM PREVIOUS ATTEMPTS", of the Adapter.

    ImageView Fav = (ImageView) convertView.findViewById(R.id.starFav);
    Fav.setBackgroundResource(R.drawable.iconfav_off);
    if(agenda.Fav.equals("on")){ Fav.setBackgroundResource(R.drawable.iconfav_on); }

    Fav.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String FavSatus = agenda.Fav;
            if(FavSatus.equals("off")){
                Toast.makeText(getContext(), "ADICIONADO AOS FAVORITOS", Toast.LENGTH_SHORT).show();
                view.setBackgroundResource(R.drawable.iconfav_on);
                agenda.Fav = "on";
            }
            if(FavSatus.equals("on")){
                Toast.makeText(getContext(), "REMOVIDO DOS FAVORITOS", Toast.LENGTH_SHORT).show();
                view.setBackgroundResource(R.drawable.iconfav_off);
                agenda.Fav = "off";
            }
        }
    });

By clicking the Bookmark button, I change the image of the object, and set the agenda value. Fav.

To correct the problem that the object was being changed in the other lines, what I did was set the "off" as default, for all items in the list, and change to "on" if my Agenda item.Fav was "on";

Fav.setBackgroundResource(R.drawable.iconfav_off);
if(agenda.Fav.equals("on")){ Fav.setBackgroundResource(R.drawable.iconfav_on); }

Now the default value and the verification of each item will happen whenever displaying/reexibiting the item while scrolling in Listview.

Once adjusted and explained, it may seem obvious the code, but for those who are starting in Java/Android (as I am), can be loss of a few hours of work.

Thanks again to @Wakim for guidance.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.