How to give a list of images the behavior of a Radiogroup?

Asked

Viewed 287 times

1

I have 2 image vectors, one for the normal image and another for when it is selected.
When selecting an image on ListView I need the others not to be selected.
I’ve tried many ways and this was my last attempt:

Java activity.:

Integer vetor1[] = {R.drawable.imagem1, R.drawable.imagem2,R.drawable.imagem.3, R.drawable.imagem4, R.drawable.imagem5};
Integer vetor2[] = {R.drawable.imagemselecionada1, R.drawable.imagemselecionada2,R.drawable.imagemselecionada3, R.drawable.imagemselecionada4, R.drawable.imagemselecionada5};

protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity);
        Adapter adaptader =  new Adapter(EscolhaAvatar.this,vetor1,vetor2);
        ListView listaImagens = (ListView) findViewById(R.id.list);
        listaImagens.setAdapter(adapter);
        listaImagens.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

listaImagens.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                desabilitaImagem(view, position);
            }
        });
    }

public void desabilitaImagem(View v, int posicao) {
        ImageView img = (ImageView) v.findViewById(R.id.img);
        listaImagens.setAdapter(adapter);
        img.setImageResource(vetor2[posicao]);
    }

My idea was to recreate the ListView and leave as selected only the image in position

  • I would take that logic out of your view and put it on your Adapter. You can use the image exchange logic inside the Adapter you created. Create an Imageview Listener (implement Onclick).

  • I’ve tried this on Adapter in a lot of ways but not quite right, because I need to change all the other images and on Adapter n there is a way to go through one by one pq it creates one item at a time. The problem is the reference of the other images that I don’t have

  • Then ai you call the Adapter notifyDataSetChanged method it updates the list.

  • you need to devise a way to know which image is selected in order to change the image of the others in getView

  • da para vc create an int variable that stores the position of the image that is selected. ai every time getView is called vc checks whether the first parameter (position) is equal to the value of its variable. if it is equal it uses the selected image, if not it uses the normal image

1 answer

0


With the help of two classes it is simple to implement what you want.

A class to encapsulate a Imageview with selected/not selected states.
She is responsible for guarding the state and the Resources ids images of each state:

Selectableimage.java

public class SelectableImage {

    private final int selectedImageResource;
    private final int unSelectedImageResource;
    private boolean isSelected;

    public SelectableImage(int selectedImageResource, int unSelectedImageResource){

        this.selectedImageResource = selectedImageResource;
        this.unSelectedImageResource = unSelectedImageResource;
    }

    public boolean isSelected() {
        return isSelected;
    }

    public void setSelected(boolean selected) {
        isSelected = selected;
    }

    public int getImageResource(){
        return isSelected ? selectedImageResource : unSelectedImageResource;
    }
}

Since in a set(list) of images there can only be one image selected, we create a class to manage that situation.
She is responsible for keeping the list of Selectableimage and ensure that when one is selected, the previous one is deselected:

Selectableimagegroup.java

public class SelectableImageGroup {

    private ArrayList<SelectableImage> list;
    private SelectableImage selectedImage;

    public SelectableImageGroup(){
        list = new ArrayList<>();
    }

    public void add(SelectableImage selectableImage){
        list.add(selectableImage);
    }

    public void setSelectedImage(SelectableImage selectedImage){
        if(this.selectedImage == selectedImage)return;
        if(!list.contains(selectedImage))throw new IndexOutOfBoundsException();
        if (this.selectedImage != null) {
            this.selectedImage.setSelected(false);
        }
        selectedImage.setSelected(true);
        this.selectedImage = selectedImage;
    }

    public void setSelectedPosition(int position){
        SelectableImage selectedImage = list.get(position);
        setSelectedImage(selectedImage);
    }

    public ArrayList<SelectableImage> getArray(){
        return list;
    }
}

Now just implement the Listview as usual.

Adapter: Selectableimagegroupadapter.java

public class SelectableImageGroupAdapter extends ArrayAdapter<SelectableImage> {

    private final LayoutInflater layoutInflater;
    private final Context context;
    private final int listItemResource;
    private final SelectableImageGroup selectableImageGroup;

    public SelectableImageGroupAdapter(Context context, int listItemResource,
                                       SelectableImageGroup selectableImageGroup) {
        super(context, listItemResource, selectableImageGroup.getArray());

        this.context = context;
        this.listItemResource = listItemResource;
        this.selectableImageGroup = selectableImageGroup;
        layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

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

        View view = convertView;
        if(view == null){
            view = layoutInflater.inflate(listItemResource, parent, false);
        }

        final SelectableImage selectableImage = getItem(position);
        ImageView imageView = (ImageView)view.findViewById(R.id.image);
        imageView.setImageResource(selectableImage.getImageResource());

        //Ver nota
        /*imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                selectableImageGroup.setSelectedImage(selectableImage);
                notifyDataSetChanged();
            }
        });*/

        return view;
    }
}

Layout da Activity: activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

Each Listview item must have one Imageview

Item layout: list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

To use:

public class MainActivity extends AppCompatActivity {

    private SelectableImageGroup selectableImageGroup;
    private SelectableImageGroupAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        selectableImageGroup = new SelectableImageGroup();
        selectableImageGroup.add(new SelectableImage(R.drawable.imagem1,
                                                     R.drawable.imagemselecionada1));
        selectableImageGroup.add(new SelectableImage(R.drawable.imagem2,
                                                     R.drawable.imagemselecionada2));
        selectableImageGroup.add(new SelectableImage(R.drawable.imagem3,
                                                     R.drawable.imagemselecionada3));
        selectableImageGroup.add(new SelectableImage(R.drawable.imagem4,
                                                     R.drawable.imagemselecionada4));
        selectableImageGroup.add(new SelectableImage(R.drawable.imagem5,
                                                     R.drawable.imagemselecionada5));

        ListView listView = (ListView)findViewById(R.id.listView);

        adapter = new SelectableImageGroupAdapter(this,
                R.layout.list_item, selectableImageGroup);

        listView.setAdapter(adapter);

    //****  Ver nota ******
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                selectableImageGroup.setSelectedPosition(position);
                adapter.notifyDataSetChanged();
            }
        });
    //*********************
    }
}

Note:

The way the code is, what toggles between the selected and deselected state is a click on the line of Listview.
If you want this switch to be made only by clicking on Imageview, "comment" the code indicated in Activity and "uncommitted" the code indicated in Adapter

  • It worked out! Thank you so much!

Browser other questions tagged

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