Android 适配器只获取最后输入的数据
Android Adapter only fetching the last entered data
我试着环顾四周,但似乎找不到可以解决问题的答案。
这是我正在做的过程:
1: 用户在警告对话框中输入数据
2:数据发送到 sql。
3: Adapter 运行,获取数据并放入 cardview。
4:显示卡片视图(根据输入的数量堆叠)。
没有计划的,正在输出的数据会覆盖所有先前的输入,并使用最新信息更新所有卡片视图。
EG:输入 1:测试 1,输入 2:测试 2。输出将是测试 2 的 2 个卡片视图。
联系Activity
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();
}
}
接触适配器
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();
}
}
}
联系数据库
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)); }
}
联系人
<?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>
contact_list (Cardview)
<?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>
我没有通读并理解您的所有代码,但我觉得这些行不对:
holder.contact_name.setText(helper.getContactName(c));
holder.contact_number.setText(helper.getContactNumber(c));
holder.contact_relation.setText(helper.getContactRelation(c));
也许可以尝试使用 position
你在调试你的代码吗?方法呢
public void swapCursor(Cursor newCursor){
if (c != null){
c.close();
}
c = newCursor;
if (newCursor != null){
notifyDataSetChanged();
}
}
notifyDataSetChanged()
是您应该调用的方法。
尝试将所有项目复制到arrayList(仅用于测试),然后在onBindViewHolder中按位置获取项目
我在想你的问题 - c.moveToFirst();在 onBindViewHolder
您的代码中存在一些问题。
我将从在 recyclerview 回收视图时保持打开状态的 Cursor 开始。这不好,而且,您在 UI 线程中执行此操作,这会大大降低您的 UI 速度。
我建议您阅读所有数据并将其传递给您的适配器。这就是适配器的用途:它们是访问数据的一种方式,但它们不必知道有关如何访问数据的任何信息。所以第一件事是改变数据库助手,添加一个循环遍历数据库中所有数据的方法和returns一个列表:
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();
}
您还需要使用 public 构造函数创建联系人 class。
然后,我将修改适配器,以接收联系人列表,而不是光标:
public ContactAdapter(Context context,List<Contact> contacts) {
mContext = context;
this.contacts = contacts;
}
您将不再需要适配器中的 db 助手,因为您已经拥有整个列表并且游标现在已经关闭,从而提高了整个 UI 的性能。此外,您还需要一个名为 contacts 的 class 属性,类型为 List。
现在您可以按位置访问单行的值,因此在您的 onBindViewHolder 中您将拥有:
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());
}
这已经可以工作了。最重要的是,我热烈建议您开始使用 Room 而不是编写自己的数据库助手。
我试着环顾四周,但似乎找不到可以解决问题的答案。 这是我正在做的过程:
1: 用户在警告对话框中输入数据
2:数据发送到 sql。
3: Adapter 运行,获取数据并放入 cardview。
4:显示卡片视图(根据输入的数量堆叠)。
没有计划的,正在输出的数据会覆盖所有先前的输入,并使用最新信息更新所有卡片视图。
EG:输入 1:测试 1,输入 2:测试 2。输出将是测试 2 的 2 个卡片视图。
联系Activity
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();
}
}
接触适配器
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();
}
}
}
联系数据库
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)); }
}
联系人
<?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>
contact_list (Cardview)
<?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>
我没有通读并理解您的所有代码,但我觉得这些行不对:
holder.contact_name.setText(helper.getContactName(c));
holder.contact_number.setText(helper.getContactNumber(c));
holder.contact_relation.setText(helper.getContactRelation(c));
也许可以尝试使用 position
你在调试你的代码吗?方法呢
public void swapCursor(Cursor newCursor){
if (c != null){
c.close();
}
c = newCursor;
if (newCursor != null){
notifyDataSetChanged();
}
}
notifyDataSetChanged()
是您应该调用的方法。
尝试将所有项目复制到arrayList(仅用于测试),然后在onBindViewHolder中按位置获取项目
我在想你的问题 - c.moveToFirst();在 onBindViewHolder
您的代码中存在一些问题。 我将从在 recyclerview 回收视图时保持打开状态的 Cursor 开始。这不好,而且,您在 UI 线程中执行此操作,这会大大降低您的 UI 速度。
我建议您阅读所有数据并将其传递给您的适配器。这就是适配器的用途:它们是访问数据的一种方式,但它们不必知道有关如何访问数据的任何信息。所以第一件事是改变数据库助手,添加一个循环遍历数据库中所有数据的方法和returns一个列表:
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();
}
您还需要使用 public 构造函数创建联系人 class。
然后,我将修改适配器,以接收联系人列表,而不是光标:
public ContactAdapter(Context context,List<Contact> contacts) {
mContext = context;
this.contacts = contacts;
}
您将不再需要适配器中的 db 助手,因为您已经拥有整个列表并且游标现在已经关闭,从而提高了整个 UI 的性能。此外,您还需要一个名为 contacts 的 class 属性,类型为 List。
现在您可以按位置访问单行的值,因此在您的 onBindViewHolder 中您将拥有:
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());
}
这已经可以工作了。最重要的是,我热烈建议您开始使用 Room 而不是编写自己的数据库助手。