J'ai essayé de regarder autour de moi mais je n'arrive pas à trouver une réponse qui pourrait le résoudre. Voici le processus de ce que je fais:
1: Les utilisateurs saisissent des données dans une boîte de dialogue d'alerte
2: Les données sont envoyées dans sql.
3: L'adaptateur s'exécute, prend des données et les met dans une vue de carte.
4: La vue de carte est affichée (empile en fonction du nombre d'entrées effectuées).
Ce qui ne fonctionne pas comme prévu, les données en cours sortie écrase toutes les entrées précédentes et met à jour toutes les vues de carte avec les dernières informations.
EG: Entrée 1: Test 1, Entrée 2: Test 2. La sortie sera 2 vues de carte du Test 2.
Activité des contacts<?xml version="1.0" encoding="utf-8"?> <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/list_layout" android:layout_width="match_parent" android:layout_height="wrap_content" app:cardBackgroundColor="#FFEAB8" app:cardCornerRadius="15dp" app:cardElevation="5dp" app:cardUseCompatPadding="true"> <androidx.cardview.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" app:cardBackgroundColor="#00ACEE" app:cardCornerRadius="5dp" app:cardElevation="15dp" app:cardUseCompatPadding="true"> <LinearLayout android:id="@+id/contact_layout_name" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="10dp" android:orientation="horizontal"> <TextView android:layout_width="120dp" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:text="Name" android:textAlignment="center" android:textColor="#E6E6E6" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:text=":" android:textSize="20sp" /> <TextView android:id="@+id/contact_list_name_item" android:layout_width="190dp" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:text="Name" android:textColor="#FFFF00" android:textSize="20sp" /> </LinearLayout> <LinearLayout android:id="@+id/contact_layout_number" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="35dp" android:orientation="horizontal"> <TextView android:layout_width="120dp" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:layout_marginTop="5dp" android:text="Number" android:textAlignment="center" android:textColor="#E6E6E6" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginTop="5dp" android:text=":" android:textSize="20sp" /> <TextView android:id="@+id/contact_list_number_item" android:layout_width="190dp" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginTop="5dp" android:text="Number" android:textColor="#FFFF00" android:textSize="20sp" /> </LinearLayout> <LinearLayout android:id="@+id/contact_layout_relation" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="60dp" android:layout_marginBottom="15dp" android:orientation="horizontal"> <TextView android:layout_width="120dp" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:layout_marginTop="10dp" android:text="Relationship" android:textAlignment="center" android:textColor="#E6E6E6" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginTop="10dp" android:text=":" android:textSize="20sp" /> <TextView android:id="@+id/contact_list_relation_item" android:layout_width="190dp" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginTop="10dp" android:text="Relationship" android:textColor="#FFFF00" android:textSize="20sp" /> </LinearLayout> </androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>
Adaptateur de contact
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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:background="@drawable/contact_background" tools:context=".Contact.Contacts"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/contact_recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/contact_button" android:layout_marginTop="10dp" android:scrollbars="vertical"> </androidx.recyclerview.widget.RecyclerView> <Button android:id="@+id/contact_button" android:layout_width="150dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="10sp" android:layout_marginBottom="10sp" android:background="#43464B" android:text="New Contact" android:textAlignment="center" android:textColor="#FFFFFF" android:textSize="18sp" /> </LinearLayout> </ScrollView> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
Base de données de contacts
import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class ContactDatabaseHelper extends SQLiteOpenHelper { public static String DATABASE_NAME = "contactlist.db"; private static final int SCHEMA_VERSION = 1; public ContactDatabaseHelper(Context context) { super(context, DATABASE_NAME, null, SCHEMA_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE contact_table( name TEXT, number TEXT , relation TEXT);"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } // Adds data into Contact database public void insertContactDatabase (String contact_name, String contact_number, String contact_relation) { ContentValues cv = new ContentValues(); cv.put("name", contact_name); cv.put("number", contact_number); cv.put("relation", contact_relation); getWritableDatabase().insert("contact_table", "name", cv); } // Read Contact database public Cursor getContactDatabase() { return (getReadableDatabase().rawQuery( "SELECT name, number, relation FROM contact_table ORDER BY + name", null)); } // Delete Contact database public Integer deleteContactDatabase () { SQLiteDatabase db = this.getWritableDatabase(); return db.delete("contact_table",null,null); } public String getContactName (Cursor c){ return (c.getString(0)); } public String getContactNumber (Cursor c){ return (c.getString(1)); } public String getContactRelation (Cursor c){ return (c.getString(2)); } }
contacts
import android.content.Context; import android.database.Cursor; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.recyclerview.widget.RecyclerView; import com.sp.R; public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.MyHolder>{ private Context mContext; private Cursor c; private ContactDatabaseHelper helper; public ContactAdapter(Context context,Cursor cursor) { mContext = context; c = cursor; helper = new ContactDatabaseHelper(mContext); } public static class MyHolder extends RecyclerView.ViewHolder{ private TextView contact_name; private TextView contact_number; private TextView contact_relation; public MyHolder(View itemView) { super(itemView); contact_name = itemView.findViewById(R.id.contact_list_name_item); contact_number = itemView.findViewById(R.id.contact_list_number_item); contact_relation = itemView.findViewById(R.id.contact_list_relation_item); } } @Override public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(mContext).inflate(R.layout.contact_list,parent,false); return new MyHolder(view); } @Override public void onBindViewHolder(MyHolder holder, final int position) { c.moveToFirst(); holder.contact_name.setText(helper.getContactName(c)); holder.contact_number.setText(helper.getContactNumber(c)); holder.contact_relation.setText(helper.getContactRelation(c)); } @Override public int getItemCount() { return c.getCount(); } public void swapCursor(Cursor newCursor){ if (c != null){ c.close(); } c = newCursor; if (newCursor != null){ notifyDataSetChanged(); } } }
contact_list (Cardview)
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.database.Cursor; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import com.sp.R; public class Contacts extends AppCompatActivity { private Button newContact; private AlertDialog.Builder builder; private AlertDialog dialog; private RecyclerView recyclerView; private ContactDatabaseHelper helper; private ContactAdapter mAdapter; private EditText new_contact_name; private EditText new_contact_number; private EditText new_contact_relation; private Button button_create_contact; private Button button_cancel_create; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.contacts); helper = new ContactDatabaseHelper(this); recyclerView = findViewById(R.id.contact_recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); mAdapter = new ContactAdapter(this,getAllItems()); recyclerView.setAdapter(mAdapter); newContact = findViewById(R.id.contact_button); // New Contact Button newContact.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { builder = new AlertDialog.Builder(Contacts.this); builder.setTitle("Create New Contact"); builder.setCancelable(false); View view = LayoutInflater.from(Contacts.this).inflate(R.layout.new_contact_dialog,null,false); CreateDialog(view); builder.setView(view); dialog = builder.create(); dialog.show(); } }); } private void CreateDialog(View view) { // ContactDialog ID's new_contact_name = view.findViewById(R.id.new_contact_name); new_contact_number = view.findViewById(R.id.new_contact_number); new_contact_relation = view.findViewById(R.id.new_contact_relation); button_create_contact = view.findViewById(R.id.button_create_contact); button_cancel_create = view.findViewById(R.id.button_cancel_create); button_create_contact.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Get String of Name, Number, Relationship String contactNameStr = new_contact_name.getText().toString(); String contactNumberStr = new_contact_number.getText().toString(); String contactRelationStr = new_contact_relation.getText().toString(); // Insert into ContactTable helper.insertContactDatabase(contactNameStr,contactNumberStr,contactRelationStr); mAdapter.swapCursor(getAllItems()); // Outputs a Toast Toast.makeText(Contacts.this, "Contact Created", Toast.LENGTH_SHORT).show(); dialog.dismiss(); } }); button_cancel_create.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { dialog.dismiss(); } }); } private Cursor getAllItems(){ return helper.getContactDatabase(); } }
4 Réponses :
Je n'ai pas lu et compris tout votre code, mais ces lignes me semblent erronées:
holder.contact_name.setText(helper.getContactName(c)); holder.contact_number.setText(helper.getContactNumber(c)); holder.contact_relation.setText(helper.getContactRelation(c));
essayez peut-être d'utiliser la position
Impossible d'utiliser la position avec le code que j'ai publié. Merci d'avoir essayé
Déboguez-vous votre code? Qu'en est-il de la méthode
public void swapCursor(Cursor newCursor){ if (c != null){ c.close(); } c = newCursor; if (newCursor != null){ notifyDataSetChanged(); } }
notifyDataSetChanged ()
est la méthode que vous devez appeler.
Essayez de copier tous les éléments dans arrayList (uniquement pour le test), puis récupérez l'élément par position dans onBindViewHolder
Je pense à votre problème - c.moveToFirst (); dans onBindViewHolder
Il y a des problèmes dans votre code. Je commencerais par le curseur qui reste ouvert tandis que la vue de recyclage est le recyclage des vues. Ce n'est pas bon, et de plus, vous le faites dans UI Thread, et cela ralentira beaucoup votre interface utilisateur.
Je vous suggère de lire toutes les données et de les transmettre à votre adaptateur. C'est à cela que servent les adaptateurs: ils sont un moyen d'accéder à vos données, mais ils n'ont rien à savoir sur la façon dont vos données sont accessibles. La première chose à faire est donc de changer l'assistant db, en ajoutant une méthode qui parcourra toutes les données de votre base de données et retournera une liste:
public void onBindViewHolder(MyHolder holder, final int position) { holder.contact_name.setText(this.contacts.get(position).getName()); holder.contact_number.setText(this.contacts.get(position).getNumber()); holder.contact_relation.setText(this.contacts.get(position).getContactRelation()); }
Classe de contact, avec un constructeur public.
Ensuite, je modifierais l'adaptateur, pour recevoir une liste de contacts, au lieu du curseur:
public ContactAdapter(Context context,List<Contact> contacts) { mContext = context; this.contacts = contacts; }
Vous n'aurez plus besoin de l'assistant db dans l'adaptateur, car vous avez déjà toute la liste et le curseur, maintenant, est déjà fermé, améliorant les performances de toute l'interface utilisateur. De plus, vous aurez besoin d'un attribut de classe nommé contacts, de type List.
Vous pouvez maintenant accéder à la valeur de la seule ligne par position, donc dans votre onBindViewHolder, vous aurez:
public List<Contact> readAllContacts() { List<Contact> contacts = new ArrayList(); Cursor cursor = this.getContactDatabase(); if (cursor.moveToFirst()){ do { contacts.add(new Contact(cursor.getString(0), cursor.getString(1), cursor.getString(2))); } while(cursor.moveToNext()); } cursor.close(); }
Cela fonctionnera déjà. En plus de tout cela, je vous suggère chaleureusement de commencer à utiliser Room au lieu d'écrire votre propre aide de base de données.
Est-ce que cela est enregistré dans SQL? Parce qu'au début, j'ai essayé de le faire avec ArrayList, mais je n'ai pas pu le stocker dans une base de données.
la question a été renvoyée à la liste, je n'ai donc examiné que les questions liées à la liste et non à l'encart. Ce sont deux opérations différentes, donc je suppose qu'il y a peut-être autre chose dans le code que vous utilisez pour stocker des données.
Je n'ai pas suivi exactement ce que vous avez fait mais la création d'un tableau et la récupération des informations du tableau ont résolu ce problème. Je vais regarder autour de moi et ouvrir une autre question si j'ai besoin de sauvegarder les données.