Je suis nouveau sur Android. J'ai créé un listview
avec un textbox
et checkbox
.
Lorsque je vérifie le checkbox
et le fait défiler vers le bas pour vérifier certains autres éléments dans la liste, les plus anciens ne sont pas cochés.
Comment éviter ce problème dans un listview
? Veuillez me guider avec mon code.
Voici le code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent">
<TextView
Android:id="@+id/TextView01"
Android:layout_height="wrap_content"
Android:text="List of items"
Android:textStyle="normal|bold"
Android:gravity="center_vertical|center_horizontal"
Android:layout_width="fill_parent"/>
<ListView
Android:id="@+id/ListView01"
Android:layout_height="250px"
Android:layout_width="fill_parent"/>
<Button
Android:text="Save"
Android:id="@+id/btnSave"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"/>
</LinearLayout>
Voici la page XML que j'ai utilisée pour créer une ligne de liste dynamique:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_height="wrap_content"
Android:gravity="left|center"
Android:layout_width="wrap_content"
Android:paddingBottom="5px"
Android:paddingTop="5px"
Android:paddingLeft="5px">
<TextView
Android:id="@+id/TextView01"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:gravity="center"
Android:textColor="#FFFF00"
Android:text="hi"/>
<TextView
Android:text="hello"
Android:id="@+id/TextView02"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginLeft="10px"
Android:textColor="#0099CC"/>
<EditText
Android:id="@+id/txtbox"
Android:layout_width="120px"
Android:layout_height="wrap_content"
Android:textSize="12sp"
Android:layout_x="211px"
Android:layout_y="13px"/>
<CheckBox
Android:id="@+id/chkbox1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"/>
</LinearLayout>
Ceci est ma classe d'activité.
public class CustomListViewActivity extends Activity {
ListView lstView;
static Context mContext;
Button btnSave;
private static class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return country.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.listview, parent,
false);
holder = new ViewHolder();
holder.text = (TextView) convertView
.findViewById(R.id.TextView01);
holder.text2 = (TextView) convertView
.findViewById(R.id.TextView02);
holder.txt = (EditText) convertView.findViewById(R.id.txtbox);
holder.cbox = (CheckBox) convertView.findViewById(R.id.chkbox1);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(curr[position]);
holder.text2.setText(country[position]);
holder.txt.setText("");
holder.cbox.setChecked(false);
return convertView;
}
public class ViewHolder {
TextView text;
TextView text2;
EditText txt;
CheckBox cbox;
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lstView = (ListView) findViewById(R.id.ListView01);
lstView.setAdapter(new EfficientAdapter(this));
btnSave = (Button)findViewById(R.id.btnSave);
mContext = this;
btnSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// I want to print the text which is in the listview one by one.
// Later I will insert it in the database.
//
// Toast.makeText(getBaseContext(), "EditText Value, checkbox value and other values", Toast.LENGTH_SHORT).show();
for (int i = 0; i < lstView.getCount(); i++) {
View listOrderView;
listOrderView = lstView.getChildAt(i);
try{
EditText txtAmt = (EditText)listOrderView.findViewById(R.id.txtbox);
CheckBox cbValue = (CheckBox)listOrderView.findViewById(R.id.chkbox1);
if(cbValue.isChecked()== true){
String amt = txtAmt.getText().toString();
Toast.makeText(getBaseContext(), "Amount is :"+amt, Toast.LENGTH_SHORT).show();
}
}
catch (Exception e) {
// TODO: handle exception
}
}
}
});
}
private static final String[] country = { "item1", "item2", "item3",
"item4", "item5", "item6","item7", "item8", "item9",
"item10", "item11", "item12" };
private static final String[] curr = { "1", "2", "3", "4", "5", "6","7", "8", "9", "10", "11", "12" };
}
Veuillez m'aider à résoudre ce problème.
J'ai évoqué ce problème à de nombreux endroits. Mais je n'ai pas pu obtenir de réponse appropriée pour résoudre ce problème.
Veuillez me fournir le code pour éviter de décocher la case lorsque vous faites défiler vers le haut ou vers le bas.
Dans l'appel de l'adaptateur listview personnalisé setChecked après appel setOnCheckedChangeListener.
De cette façon, vous séparez le lien vers l'ancien écouteur de la vue recyclée.
Vous pouvez utiliser le code d'adaptateur suivant pour exécuter parfaitement une case à cocher dans un ListView.
Une démo détaillée est ici: Listview With Checkbox Android
Voir le lien de démonstration détaillé pour des informations détaillées. Il montre également comment envoyer des informations vérifiées à l'activité suivante.
import Android.content.Context;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.BaseAdapter;
import Android.widget.CheckBox;
import Android.widget.TextView;
import Android.widget.Toast;
import Java.util.ArrayList;
public class CustomAdapter extends BaseAdapter {
private Context context;
public static ArrayList<Model> modelArrayList;
public CustomAdapter(Context context, ArrayList<Model> modelArrayList) {
this.context = context;
this.modelArrayList = modelArrayList;
}
@Override
public int getViewTypeCount() {
return getCount();
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public int getCount() {
return modelArrayList.size();
}
@Override
public Object getItem(int position) {
return modelArrayList.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder(); LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.lv_item, null, true);
holder.checkBox = (CheckBox) convertView.findViewById(R.id.cb);
holder.tvAnimal = (TextView) convertView.findViewById(R.id.animal);
convertView.setTag(holder);
}
else {
// The getTag returns the viewHolder object set as a tag to the view
holder = (ViewHolder)convertView.getTag();
}
holder.checkBox.setText("Checkbox " + position);
holder.tvAnimal.setText(modelArrayList.get(position).getAnimal());
holder.checkBox.setChecked(modelArrayList.get(position).getSelected());
holder.checkBox.setTag(R.integer.btnplusview, convertView);
holder.checkBox.setTag( position);
holder.checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
View tempview = (View) holder.checkBox.getTag(R.integer.btnplusview);
TextView tv = (TextView) tempview.findViewById(R.id.animal);
Integer pos = (Integer) holder.checkBox.getTag();
Toast.makeText(context, "Checkbox " + pos + " clicked!", Toast.LENGTH_SHORT).show();
if (modelArrayList.get(pos).getSelected()){
modelArrayList.get(pos).setSelected(false);
}
else {
modelArrayList.get(pos).setSelected(true);
}
}
});
return convertView;
}
private class ViewHolder {
protected CheckBox checkBox;
private TextView tvAnimal;
}
}
Model
est
public class Model {
private boolean isSelected;
private String animal;
public String getAnimal() {
return animal;
}
public void setAnimal(String animal) {
this.animal = animal;
}
public boolean getSelected() {
return isSelected;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
}
Dans votre getView()
vous avez la ligne suivante
holder.cbox.setChecked(false);
qui désactive CheckBox à chaque appel de getView()
(lorsque vous faites défiler votre liste, par exemple)
Blockquote
** Dans la méthode getView () latérale, il suffit d'appeler comme ceci >>
check.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton arg0, boolean arg1)
{
if(check.isChecked())
{
//checked
chkArray[position]=true;
}
else
{ //uncheck
chkArray[position]=false;
}
}
});
//check condition for checkboxes
if(chkArray.length>0)
{
for (int i = 0; i < chkArray.length; i++)
{
if(chkArray[position]!=null && chkArray[position])
{
check.setChecked(true);
}
}
}
enfin je suis arrivé à la solution quelques heures plus tard, c'est par
à l'intérieur de la méthode getView comme suit:
if(marray!=null) { //if myarray class object has data
holder.name.setText(marray.getName());
.
.
holder.checkbox.setChecked(marray.isChecked());//get the checkbox state
}
donnez la valeur à la variable booléenne dans la méthode holder.checkbox.setOnClickListener comme:
holder.checkbox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (allReport.UserSelection.contains(
Integer.parseInt(marrays.get(position)
.getIdd()))) // check if id selected before
{
marray.setChecked(false);// marray is the object from myArray class
allReport.UserSelection.remove(new Integer(Integer.parseInt(marrays.get(position).getIdd())));//remove id
}else{
allReport.UserSelection.add(Integer.parseInt
(marrays.get(position).getIdd()));//save the selection
marray.setChecked(true);//save the boolean to true}
c'est résoudre le problème pour moi j'espère que cela fait toute aide
J'ai également eu ce problème avant. Android fait cela pour économiser de l'espace; seuls les éléments que vous voyez actuellement sont chargés, et c'est ce que j'ai découvert.
Si vous êtes en bas de votre liste, l'ID 1 est peut-être en position 5. J'ai cherché sur le Web et je l'ai déjà découvert.
Mais ceci vous aidera: D
Considérer:
holder.cbox.setChecked(false);
Supprimez cette ligne. Lorsque vous faites défiler la vue de liste à chaque fois, la méthode getView () est appelée.