zek
zek

Reputation: 55

Change image on click in custom listview Android

In my custom listview I want to change Image when the image is clicked. But currently when I click on Image, last row image is changed not the one on which I clicked. My customAdapter classis below:

package com.zek.androidvoicechanger;

import java.util.List;

import org.w3c.dom.Text;

import android.app.Activity;
import android.content.Context;
import android.media.Image;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;

public class CustomAdapter extends ArrayAdapter<Items> {

    Context context;
    ImageView image ;


//  int[] Radio = { R.drawable.play, R.drawable.pause };

    public CustomAdapter(Context context, int resourceId, List<Items> items) {
        super(context, resourceId, items);
        this.context = context;
    }

    private class ViewHolder {
        // ImageView imageView;

        TextView txtTitle;
//      ImageView img;

    }

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

        ViewHolder holder = null;

        Items rowItem = getItem(position);

        LayoutInflater mInflater = (LayoutInflater) context
                .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.custom_list, null);
            holder = new ViewHolder();

            holder.txtTitle = (TextView) convertView
                    .findViewById(R.id.textView1);
//          holder.img = (ImageView) convertView.findViewById(R.id.imageView2);
            image = (ImageView) convertView.findViewById(R.id.imageView2);
        //  holder.rdo = (RadioButton) convertView.findViewById(R.id.radioButton1);
            convertView.setTag(holder);
        } else
            holder = (ViewHolder) convertView.getTag();

        holder.txtTitle.setText(rowItem.getTitle());

        image.setImageResource(rowItem.getImageId());
        image.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(context, "image clicked", 1000).show();
                if(position==0){
                image.setImageResource(R.drawable.pause);
                }
                AudioListner.playRecord(position);

            }
        });



    //holder.rdo.setTag(position);
//      holder.rdo.setOnCheckedChangeListener(new OnCheckedChangeListener() {
//          
//          @Override
//          public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//
//          
//              
//          }
//      });

//      rdo.setOnClickListener(new OnClickListener() {
//
//          @Override
//          public void onClick(View v) {
//
//              
//              if(position==0){
//                  rdo.indexOfChild(findViewById(isEnabled(position)));
//                  Toast.makeText(context, "image clicked", 1000).show();
//                  rdo.setBackgroundResource(R.drawable.pause);
//                  AudioListner.playRecord(position);
//                  
//              }
//              
//              
//              
//              if (rdo.isClickable()) {
//                  rdo.setBackgroundResource(R.drawable.pause);
//                  Toast.makeText(context, "image clicked", 1000).show();
//
//                  //Radio[1] = 1;
//                  AudioListner.playRecord(position);
//                  
//              } else {
//              //  rdo.setBackgroundResource(R.drawable.play);
//                  Toast.makeText(context, "image not clicked", 1000).show();
//
//              }
////
//          }
//      });

        return convertView;
    }

}

Any help will be appreciated.

Upvotes: 2

Views: 10634

Answers (3)

Saket
Saket

Reputation: 3076

Adapter based views like ListView recycles its views to save resources. During scrolls, ListView will recycle views that are no more visible. This post by Lucas is a great place to learn more about its working: http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/

So registering onClick in your getView() method might not be a very good idea. Instead use the setOnItemClickListener() method on your ListView.

To accomplish what you're trying to do, you can do this:

Edit: Updated my code as per your comment.

mYourListView..setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick (AdapterView<?> parent, View view, int position, long id) {
            Toast.makeText(context, "Item #" + position + " clicked", Toast.LENGTH_SHORT).show();

            // here, "position" is the position of your item and "id" is your
            // item's id in your data set.

            // mLastClickedPosition is a member field of type long which 
            // stores the position of the most recently clicked item, 
            // initially set to -1
            if(mLastClickedPosition != -1){
                  // do something to pause the item in your list at this position
            }

            // next, update mLastClickedPosition
            mLastClickedPosition = position

            // find the image in your view and update it
            if(position==0){
                  ImageView imageView = view.findViewById(R.id.your_image);
                  imageView.setImageResource(R.drawable.pause);
            }

            // play audio
            AudioListner.playRecord(position);

        }
    });

Upvotes: 4

kiruwka
kiruwka

Reputation: 9450

In your posted code you have ImageView image which belongs to your adapter, and therefore "global" to your list.

Instead, what you seem to want is to have onClick handler for each individual list item.

For this I recommend you to implement OnItemClickListener for you listView,

or alternatively you could change your onClick code to something like :

    // set onClick for each img in the list
    holder.img.setOnClickListener(new OnClickListener() { 

        @Override
        public void onClick(View v) {
            ((ImageView) v).setImageResource(R.drawable.pause);
        }
    });

and don't forget to initialize holder.img as it is currently commented out.

Upvotes: 1

Vikram Singh
Vikram Singh

Reputation: 1420

For this you have to maintain the position of clicked row. You can do this by creating an array. Everytime you click on a row image, you can add this row's position into this array. Also use this arrray to populate your listview using if-else condition. I have aaded that in code.

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

        ViewHolder holder = null;

        Items rowItem = getItem(position);

        LayoutInflater mInflater = (LayoutInflater) context
                .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.custom_list, null);
            holder = new ViewHolder();

            holder.txtTitle = (TextView) convertView
                    .findViewById(R.id.textView1);
//          holder.img = (ImageView) convertView.findViewById(R.id.imageView2);
            image = (ImageView) convertView.findViewById(R.id.imageView2);
        //  holder.rdo = (RadioButton) convertView.findViewById(R.id.radioButton1);
            convertView.setTag(holder);
        } else
            holder = (ViewHolder) convertView.getTag();


        if(yourSelectedImageArray.contains(position)){

         image.setImageResource(R.drawable.pause);//your clicked image
        }else{
        image.setImageResource(rowItem.getImageId());//your default image
        }
        holder.txtTitle.setText(rowItem.getTitle());

        //image.setImageResource(rowItem.getImageId());
        image.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(context, "image clicked", 1000).show();
                if(position==0){ //not sure about this logic..
                yourSelectedImageArray.add(position);//add the clicked position into an                       array.
                image.setImageResource(R.drawable.pause);
                }
                AudioListner.playRecord(position);

            }
        });

    return convertView;
}

also dont forget to remove position from this array when you click on any other row. Hope you got my point.

Upvotes: -1

Related Questions