web-dev-qa-db-fra.com

Android: bouton radio dans la vue de liste personnalisée

Je développe une application dans laquelle j'ai besoin d'implémenter des boutons radio en vue liste. Je veux implémenter une vue de liste ayant un bouton radio et deux vues de texte dans chaque ligne. Et un bouton "Ok" sous listview.

J'ai créé une vue de liste et un adaptateur personnalisé. Le code de listview est le suivant:

<ListView
    Android:id="@+id/listview"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    Android:cacheColorHint="#00000000"
    Android:overScrollMode="never"
    tools:ignore="NestedScrolling"
    Android:choiceMode="singleChoice" >
</ListView>

Et j'ai créé une disposition d'adaptateur personnalisée comme:

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent" >

    <TableRow
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        tools:ignore="UselessParent" >

        <RadioButton
            Android:id="@+id/radiobutton"
            Android:layout_width="0sp"
            Android:layout_height="wrap_content"
            Android:layout_weight=".1" />

        <TextView
            Android:id="@+id/textview1"
            Android:layout_width="0sp"
            Android:layout_height="wrap_content"
            Android:layout_weight=".3" />

        <TextView
            Android:id="@+id/textview2"
            Android:layout_width="0sp"
            Android:layout_height="wrap_content"
            Android:layout_weight=".3" />

    </TableRow>

</TableLayout>

Le code Java du fragment est le suivant:

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

// values is a StringArray holding some string values.
CustomAdapter customAdapter = new CustomAdapter (getActivity(), values);
listView.setAdapter(customAdapter );
listView.setOnItemClickListener(this);

@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {}

Et le code de l'adaptateur est le suivant:

public class CustomAdapter extends ArrayAdapter<String> {   
    /** Global declaration of variables. As there scope lies in whole class. */
    private Context context;
    private String[] listOfValues;

    /** Constructor Class */
    public CustomAdapter (Context c,String[] values) {
        super(c,R.layout.adapter_layout,values);
        this.context = c;
        this.listOfValues = values;
    }

    /** Implement getView method for customizing row of list view. */
    public View getView(final int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
        // Creating a view of row.
        View rowView = inflater.inflate(R.layout.adapter_layout, parent, false);

            TextView textView1 = (TextView)rowView.findViewById(R.id.textview1);
            TextView textView2 = (TextView)rowView.findViewById(R.id.textview2);

            RadioButton radioButton = (RadioButton) rowView.findViewById(R.id.radiobutton);

            radioButton.setOnClickListener(new OnClickListener() {          
            @Override   
            public void onClick(View v) {
                Toast.makeText(context, CustomAdapter[position], Toast.LENGTH_SHORT).show();
            }
        });

        return rowView;
    }
}    

Les données de textview1 sont remplies à partir de la base de données SQLite et sur textview2 les données sont "Status Closed". Et en sélectionnant ou en cliquant sur n'importe quel bouton radio, le texte de la vue texte est changé en "Statut ouvert".

Le problème est: Le besoin d'application est qu'un seul bouton radio doit être sélectionné et que les données de textview2 doivent être modifiées lors de la sélection. Et lorsque l'utilisateur clique sur l'autre bouton radio, il est sélectionné et le précédent doit être désélectionné et le texte de textview2 doit être remplacé par "Statut fermé" d'un bouton radio précédemment sélectionné et cliqué sur le bouton radio "Statut ouvert".

Modifier 1:

Et en cliquant sur le bouton "OK", je veux obtenir la position, le texte de la vue de liste textview1 et textview2, car je veux enregistrer ce texte dans la base de données SQLite dans deview.

Veuillez me guider quelles étapes dois-je suivre. Je suis au milieu de ma candidature. Vos précieux conseils sont nécessaires.

19
Manoj Fegde

Voici les idées clés

  • quand un RadioButton est coché nous devons appeler notifyDataSetChanged(), pour que toutes les vues soient mises à jour.
  • lorsqu'un RadioButton est coché, nous devons définir un selectedPosition, pour garder une trace de laquelle RadioButton est sélectionné
  • Views sont recyclés dans ListViews. Par conséquent, leur position absolue change dans le ListView. Par conséquent, à l'intérieur de ListAdapter#getView(), nous devons appeler setTag() sur chaque RadioButton. Cela nous permet de déterminer la position actuelle de RadioButton dans la liste lorsque vous cliquez sur RadioButton.
  • RadioButton#setChecked() doit être mis à jour dans getView() pour les Views nouveaux ou préexistants.

Voici un exemple d'ArrayAdapter que j'ai écrit et testé afin de démontrer ces idées

public class MainActivity extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // I do no use these values anywhere inside the ArrayAdapter. I could, but don't.
        final Integer[] values = new Integer[] {1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,};

        ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(this, R.layout.row, R.id.textview, values) {

            int selectedPosition = 0;

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View v = convertView;
                if (v == null) {
                    LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    v = vi.inflate(R.layout.row, null);
                    RadioButton r = (RadioButton)v.findViewById(R.id.radiobutton);
                }
                TextView tv = (TextView)v.findViewById(R.id.textview);
                tv.setText("Text view #" + position);
                RadioButton r = (RadioButton)v.findViewById(R.id.radiobutton);
                r.setChecked(position == selectedPosition);
                r.setTag(position);
                r.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        selectedPosition = (Integer)view.getTag();
                        notifyDataSetChanged();
                    }
                });
                return v;
            }

        };
        setListAdapter(adapter);
    }
}
69
Brian Attwell

Essayez ci-dessous l'adaptateur:

public class ChooseAdapter extends ArrayAdapter<LinkedHashMap<String, String>> {
private ArrayList<LinkedHashMap<String, String>> listMenu;

int position_id;

private LayoutInflater inflater;
Context context;

public ChooseAdapter(Activity activity,
        ArrayList<LinkedHashMap<String, String>> listMenu, int type) {

    super(activity, R.layout.choose_single_item, listMenu);
    this.listMenu = listMenu;

    context = activity.getApplicationContext();
    inflater = LayoutInflater.from(context);

}

public int getCount() {
    return listMenu.size();
}

public long getItemId(int position) {
    return position;

}

public static class ViewHolder

{
    public CheckBox chk;

}

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

    if (convertView == null) {

        view = new ViewHolder();

        convertView = inflater.inflate(R.layout.choose_single_item, null);
        view.chk = (CheckBox) convertView
                .findViewById(R.id.selection_checkbox);

        view.chk.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {
                // TODO Auto-generated method stub
                if (isChecked) {

                    listMenu.get((Integer) buttonView.getTag()).put(
                            "checked", "true");
                    for (int i = 0; i < listMenu.size(); i++) {
                        if (i != (Integer) buttonView.getTag()) {
                            if (listMenu.get(i).containsKey("checked"))
                                listMenu.get(i).remove("checked");
                        }
                    }
                } else {
                    listMenu.get((Integer) buttonView.getTag()).remove(
                            "checked");
                }

                notifyDataSetChanged();
            }
        });

        convertView.setTag(R.id.selection_checkbox, view.chk);
        convertView.setTag(view);

    }

    else {
        view = (ViewHolder) convertView.getTag();
    }
    view.chk.setTag(position);

    view.chk.setText(listMenu.get(position).get("name"));

    if (listMenu.get(position).containsKey("checked")) {
        view.chk.setChecked(true);
    } else
        view.chk.setChecked(false);

    return convertView;

}
}

Et la disposition que je gonfle est:

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

<CheckBox
    Android:id="@+id/selection_checkbox"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:layout_margin="10dp"
    Android:text="abc"
    Android:textColor="#8C8C8C"
    Android:textSize="16sp" />

</LinearLayout>

Ici, j'ai utilisé la case à cocher, vous pouvez également utiliser le radiobutton à la place, rien d'autre n'est nécessaire pour changer.

J'espère que ça aide!

2
Priyank Joshi