Пользовательский адаптер массива Android getView принимает неправильный идентификатор (следующий в listview)

#android #listview #adapter

#Android #listview #адаптер

Вопрос:

Всем привет,

Возможно, это простая и / или глупая проблема, но поскольку она сводит меня с ума, я публикую ее.

У меня есть Listview с пользовательским ArrayAdapter в классе с именем CoursFindAdapter, а getView выглядит так:

 @Override
public View getView(int position, View convertView, ViewGroup parent) {
this.parent = parent;

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


final Cours cours = getItem(position);
telephone = cours.getTelephone();
email = cours.getEmail();
latitude = (long)cours.getLatitude();
longitude = (long)cours.getLongitude();
code = cours.getCode();
id_cours = cours.getId();
tarif = String.valueOf(cours.getTarif());
specialite = cours.getSpecialite();
prenom = cours.getPrenom();
nom = cours.getNom();
titre = cours.getTitre();
description = cours.getDescription();
reserve = cours.getReserve();



SharedPreferences prefs = getContext().getSharedPreferences(
        "com.learnys.android", Context.MODE_PRIVATE);

String container = "com.learnys.android.id";
id_etudiant = prefs.getString(container, "0");




CoursViewHolder viewHolder = (CoursViewHolder) convertView.getTag();
if(viewHolder == null){
    viewHolder = new CoursViewHolder();
    viewHolder.titre = (TextView) convertView.findViewById(R.id.titre);
    viewHolder.description = (TextView) convertView.findViewById(R.id.description);
    viewHolder.codepostal = (TextView) convertView.findViewById(R.id.codepostal);
    viewHolder.ville = (TextView) convertView.findViewById(R.id.ville);
    viewHolder.tarif = (TextView) convertView.findViewById(R.id.tarif);
    viewHolder.nom = (TextView) convertView.findViewById(R.id.nom);
    viewHolder.prenom = (TextView) convertView.findViewById(R.id.prenom);
    viewHolder.specialite = (TextView) convertView.findViewById(R.id.specialite);
    viewHolder.distance = (TextView) convertView.findViewById(R.id.distance);
    viewHolder.choice = (Button) convertView.findViewById(R.id.choice);

    convertView.setTag(viewHolder);
}else {
    viewHolder = (CoursViewHolder) convertView.getTag();
}


viewHolder.titre.setText(Html.fromHtml("<html><body><font size=10 color=red>Cours: </font> "   cours.getTitre()   " </body><html>"));
viewHolder.description.setText(Html.fromHtml("<html><body><font size=10 color=red>Description: </font> " cours.getDescription() " </body><html>"));
viewHolder.codepostal.setText(Html.fromHtml("<html><body><font size=10 color=red>Code Postal: </font> " String.valueOf(cours.getCodepostal()) " </body><html>"));
viewHolder.ville.setText(Html.fromHtml("<html><body><font size=10 color=red>Ville: </font> " cours.getVille() " </body><html>"));
viewHolder.tarif.setText(Html.fromHtml("<html><body><font size=10 color=red>Tarif: </font> " String.valueOf(cours.getTarif()) " </body><html>"));
viewHolder.nom.setText(Html.fromHtml("<html><body><font size=10 color=red>Nom Professeur: </font> " cours.getNom() " </body><html>"));
viewHolder.prenom.setText(Html.fromHtml("<html><body><font size=10 color=red>Prénom Professeur: </font> "   cours.getPrenom()   " </body><html>"));
viewHolder.specialite.setText(Html.fromHtml("<html><body><font size=10 color=red>Spécialité Professeur: </font> " cours.getSpecialite() " </body><html>"));
viewHolder.distance.setText(Html.fromHtml("<html><body><font size=10 color=red>Distance: </font> "   cours.getDistance()   " <font size=10 color=red>Temps: </font> "   cours.getTime()    " </body><html>"));


if (cours.getEtudiant() == Integer.valueOf(id_etudiant)){
    viewHolder.choice.setText("Cours réservé");
    viewHolder.choice.setTextColor(Color.BLACK);
    ///viewHolder.code.setClickable(false);
    viewHolder.choice.setEnabled(false);
}else {

    viewHolder.choice.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            Activity origin = (Activity) getContext();
            Intent myIntent = new Intent(origin, PayPalActivity.class);
            myIntent.putExtra("id_cours", id_cours);
            myIntent.putExtra("id_etudiant", id_etudiant);
            myIntent.putExtra("tarif", tarif);
            myIntent.putExtra("specialite", specialite);
            myIntent.putExtra("description", description);
            myIntent.putExtra("prenom", prenom);
            myIntent.putExtra("nom", nom);
            myIntent.putExtra("telephone", telephone);
            myIntent.putExtra("email", email);
            myIntent.putExtra("titre", titre);
            myIntent.putExtra("code", code);
            myIntent.putExtra("cours", cours);
            getContext().startActivity(myIntent);


        }


    });

}

return convertView;
}
 

Класс держателя представления:

 public class CoursViewHolder{
public TextView titre;
public TextView description;
public TextView codepostal;
public TextView ville;
public TextView tarif;
public TextView nom;
public TextView prenom;
public TextView specialite;
public String email;
public String telephone;
public long latitude;
public long longitude;
public String code;
public Button choice;
public TextView distance;
}
 

Заполняется другим классом, подобным этому:

 CoursFindAdapter adapter = new CoursFindAdapter(getActivity(),  
cours,getActivity(), page);
adapter.setContext(getActivity());
listView.setAdapter(adapter);
 

XML пользовательского адаптера:

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
>
<TextView
    android:id="@ id/titre"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@android:color/black"
    tools:text="Titre"
    android:layout_alignParentTop="true"
    android:layout_alignRight="@ id/description"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />
<TextView
    android:id="@ id/description"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@android:color/black"
    tools:text="Description"
    android:layout_below="@ id/titre"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />

<TextView
    android:id="@ id/ville"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@android:color/black"
    tools:text="Ville"
    android:layout_below="@ id/description"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />
<TextView
    android:id="@ id/tarif"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@android:color/black"
    tools:text="Tarif"
    android:layout_below="@ id/codepostal"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />

<TextView
    android:id="@ id/nom"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@android:color/black"
    tools:text="Nom"
    android:layout_below="@ id/tarif"
    android:layout_alignLeft="@ id/tarif"
    android:layout_alignStart="@ id/tarif" />

<TextView
    android:id="@ id/prenom"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@android:color/black"
    tools:text="Prenom"
    android:layout_below="@ id/nom"
    android:layout_alignLeft="@ id/nom"
    android:layout_alignStart="@ id/nom" />

<TextView
    android:id="@ id/specialite"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@android:color/black"
    tools:text="Specialité"
    android:layout_below="@ id/prenom"
    android:layout_alignLeft="@ id/prenom"
    android:layout_alignStart="@ id/prenom" />

<TextView
    android:id="@ id/distance"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@android:color/black"
    tools:text="Distance"
    android:layout_below="@ id/specialite"
    android:layout_alignLeft="@ id/specialite"
    android:layout_alignStart="@ id/specialite" />

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Choisir"
    android:id="@ id/choice"
    style="@style/MaterialButton"
    android:layout_below="@ id/distance"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_marginTop="25dp" />
<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:layout_below="@ id/choice"
    android:background="@android:color/darker_gray"/>

<TextView
    tools:text="Code Postal"
    android:id="@ id/codepostal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@android:color/black"
    android:layout_below="@ id/ville"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />

</RelativeLayout>
 

И каждый раз, когда я нажимаю на кнопку с именем choice внутри элемента списка, данные, отправляемые в класс PayPalActivity, всегда являются данными, относящимися к следующему идентификатору в списке. Иногда, но не очень часто, он берет правильные данные (только по первому элементу списка).

Я уверен, что я делаю что-то не так; реализация, XML или что-то еще, я не могу понять это, потому что я использую аналогичный код для другого действия, и, как и ожидалось, он работает нормально:-(

Я перепробовал много вещей, включая удаление всех данных с удалением этой части кода, но безуспешно:

 if (Integer.valueOf(reserve) == 1 amp;amp; cours.getEtudiant() != Integer.valueOf(id_etudiant)) {
    convertView.setVisibility(View.INVISIBLE);
}
else if (cours.getEtudiant() == Integer.valueOf(id_etudiant)){
    viewHolder.choice.setText("Cours réservé");
    viewHolder.choice.setTextColor(Color.BLACK);
    ///viewHolder.code.setClickable(false);
    viewHolder.choice.setEnabled(false);
}
 

Я застрял в своей глупости, и я не знаю, что теперь делать, любая помощь была бы очень признательна.

[РЕДАКТИРОВАТЬ] Я замечаю, что если я нахожусь в определенной позиции (не отображаю ни одного пикселя следующего элемента в списке), результат в порядке, но я думаю, что это неправильное поведение: правильное поведение должно быть: «выбор элемента с помощью одной кнопки» должен управлять настройкой всего элемента.данные, даже если элемент отображается не полностью (важна кнопка, связанная с элементом) С уважением ко всем и спасибо за чтение этой проблемы 🙂

Комментарии:

1. Вы не добавили код из getItem() , похоже, проблема есть.

2. похоже, эта невидимая строка вносит путаницу в ваш список. Вместо этого я предлагаю вам вычесть на единицу возвращаемое значение getCount() и ввести логику скрытия, getItem() чтобы элемент, который вы хотите скрыть, никогда не возвращался

3. Но я удаляю исключение, и поведение становится похожим. Но вы правы, я должен удалить его из набора данных, а не из представления после…

4. @Abbas Я не понял вашего ответа, не могли бы вы быть более конкретными?

5. Я удалил «if (Integer.valueOf(reserve) == 1 amp;amp; cours.getEtudiant() != Integer.valueOf(id_etudiant)) { convertView.setVisibility(Просмотр. НЕВИДИМЫЙ); }» и та же проблема. Когда я играю со свитком, я могу выбрать правильный после неправильного, и это зависит от позиции, обычно это не должно так работать!

Ответ №1:

Ваша проблема проста: вы используете устаревшие данные в своем onClickListener() .

Итак, все, что вам нужно сделать, это

 viewHolder.choice.setTag(position);
viewHolder.choice.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {

        Cours c = getItem((int) view.getTag());
        Activity origin = (Activity) getContext();
        Intent myIntent = new Intent(origin, PayPalActivity.class);
        myIntent.putExtra("id_cours", c.getId());
        myIntent.putExtra("id_etudiant", id_etudiant);
        myIntent.putExtra("tarif", String.valueOf(c.getTarif()));
        myIntent.putExtra("specialite", c.getSpecialite());
        myIntent.putExtra("description", c.getDescription());
        .
        .
        .
        myIntent.putExtra("cours", c);
        getContext().startActivity(myIntent);
    }
});
 

Происходит то, что ваши данные обновляются при каждом getView() вызове, т.Е. До тех пор, пока не будут выложены все представления. При нажатии на элемент значения изменяются. Таким образом, вы получаете последние значения из getView() итерации.

Также вместо получения всех полей cours , которые вы, возможно, захотите использовать cours.getId() , и т. Д. я уверен, что это не сильно влияет на вашу производительность.

Комментарии:

1. @exaju Если ответ помог вам, пожалуйста, отметьте его как правильный, чтобы другие могли найти правильный ответ.

2. Вот оно. Я не понял, что 1 не равно принять решение… Большое спасибо в другой раз 🙂