addRow 第一次正确地添加到 listView 的顶部,然后添加到列表的底部
addRow adds to top of listView correctly first time, then adds to bottom of the list
我正在从屏幕下半部分的列表视图中取出光标并将其添加到上半部分列表视图。这并没有像预期的那样 100% 地工作。我第一次单击底行时,它会将该行正确添加到位置 0 的顶部列表视图中,并在其下方显示该行(该行在应用程序打开时存在)。太好了,这就是我想要的,除非我单击 bottomList 中的另一行。该行添加到 2 的位置,基本上不会变为 0 并将其他 2 向下推。
现在,这不符合我的要求,我相信这总是搞乱我的 onClick 事件,因为从被点击的 topList 传递的数据现在是错误的。不确定两者是否相关,所以尝试至少让 topList 正确显示然后我可以调试更多并查看为什么传递的数据不正确。
这是我使用从 bottomList 传递的光标更新 topList 的代码
public class TopFragment extends Fragment {
public Cursor mTopCursor;
EmployeeDBHandler dbHandler;
ListView mTopListView;
public static MatrixCursor customCursor1;
int flag = 0;
TopListCursorAdapter mTopAdapter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_top_list, container, false);
String table = "employees";
customCursor1 = new MatrixCursor(new String[]{"_id", "Employee_number", "First_name",
"Last_name", "Payroll_title", "ThumbnailData", "Email", "Phone_mobile", "Phone_office", "Cost_center_id",
"Has_direct_reports", "Manager_employee_number"});
dbHandler = EmployeeDBHandler.getInstance(getContext());
SQLiteDatabase db = dbHandler.getWritableDatabase();
int mStartingEmployeeID = mStartingNumber;
mTopCursor = db.rawQuery("SELECT * FROM " + table + " WHERE " + "Employee_number" + "=" + mStartingEmployeeID, null);
mTopListView = (ListView) view.findViewById(R.id.mTopList);
mTopAdapter = new TopListCursorAdapter(getContext(), mTopCursor);
mTopListView.setAdapter(mTopAdapter);
customCursor1.close();
db.close();
return view;
}
public void update(Cursor cursor) {
if (cursor.moveToFirst()) {
customCursor1.addRow(new Object[]{cursor.getInt(0), cursor.getString(cursor.getColumnIndex("Employee_number")), cursor.getString(2),
cursor.getString(3), cursor.getString(6), cursor.getString(9), cursor.getString(8), cursor.getString(4),
cursor.getString(5), cursor.getString(10), cursor.getString(7), cursor.getString(11)});
if (flag == 0) {
customCursor1.addRow(new Object[]{mTopCursor.getInt(0), mTopCursor.getString(cursor.getColumnIndex("Employee_number")), mTopCursor.getString(2),
mTopCursor.getString(3), mTopCursor.getString(6), mTopCursor.getString(9),
mTopCursor.getString(8), mTopCursor.getString(4), mTopCursor.getString(5),
mTopCursor.getString(10), mTopCursor.getString(7), mTopCursor.getString(11)});
flag++;
} else {
flag = 1;
}
mTopAdapter.changeCursor(customCursor1);
customCursor1.close();
}
}
}
public class TopListCursorAdapter extends CursorAdapter {
public interface TopListClickListener {
void onTopListClick(Cursor cursor);
}
private TopListClickListener mCallback;
public TopListCursorAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
if(!(context instanceof TopListClickListener)) {
throw new ClassCastException("Content must implement BottomListClickListener");
}
this.mCallback = (TopListClickListener) context;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.contact_cardview_top, parent, false);
}
@Override
public void bindView(View view, final Context context, final Cursor cursor) {
ViewHolder holder;
holder = new ViewHolder();
holder.tvFirstName = (TextView) view.findViewById(R.id.personFirstName);
holder.tvLastName = (TextView) view.findViewById(R.id.personLastName);
holder.tvTitle = (TextView) view.findViewById(R.id.personTitle);
holder.mPeepPic = (ImageView) view.findViewById(R.id.person_photo);
holder.mDetailsButton = (ImageButton) view.findViewById(R.id.fullDetailButton);
holder.mTopCardView = (CardView) view.findViewById(R.id.mTopHomeScreenCV);
String mFirstName = cursor.getString(cursor.getColumnIndexOrThrow("First_name"));
String mLastName = cursor.getString(cursor.getColumnIndexOrThrow("Last_name"));
String mPayrollTitle = cursor.getString(cursor.getColumnIndexOrThrow("Payroll_title"));
String mThumbnail = cursor.getString(cursor.getColumnIndexOrThrow("ThumbnailData"));
holder.tvFirstName.setText(mFirstName);
holder.tvLastName.setText(mLastName);
holder.tvTitle.setText(mPayrollTitle);
if (mThumbnail != null) {
byte[] imageAsBytes = Base64.decode(mThumbnail.getBytes(), Base64.DEFAULT);
Bitmap parsedImage = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length);
holder.mPeepPic.setImageBitmap(parsedImage);
} else {
holder.mPeepPic.setImageResource(R.drawable.img_place_holder_adapter);
}
final int position = cursor.getPosition();
holder.mDetailsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cursor.moveToPosition(position);
String mEmployeeNumber = cursor.getString(cursor.getColumnIndex("Employee_number"));
String mFirstName = cursor.getString(cursor.getColumnIndex("First_name"));
String mLastName = cursor.getString(cursor.getColumnIndex("Last_name"));
String mTitle = cursor.getString(cursor.getColumnIndex("Payroll_title"));
String mPic = cursor.getString(cursor.getColumnIndex("ThumbnailData"));
String mEmail = cursor.getString(cursor.getColumnIndex("Email"));
String mPhoneMobile = cursor.getString(cursor.getColumnIndex("Phone_mobile"));
String mPhoneOffice = cursor.getString(cursor.getColumnIndex("Phone_office"));
String mCostCenter = cursor.getString(cursor.getColumnIndex("Cost_center_id"));
String mHasDirectReports = cursor.getString(cursor.getColumnIndex("Has_direct_reports"));
String mManagerNumber = cursor.getString(cursor.getColumnIndex("Manager_employee_number"));
Intent mIntent = new Intent(context, EmployeeFullInfo.class);
mIntent.putExtra("Employee_number", mEmployeeNumber);
mIntent.putExtra("First_name", mFirstName);
mIntent.putExtra("Last_name", mLastName);
mIntent.putExtra("Payroll_title", mTitle);
mIntent.putExtra("ThumbnailData", mPic);
mIntent.putExtra("Email", mEmail);
mIntent.putExtra("Phone_mobile", mPhoneMobile);
mIntent.putExtra("Phone_office", mPhoneOffice);
mIntent.putExtra("Cost_center_id", mCostCenter);
mIntent.putExtra("Has_direct_reports", mHasDirectReports);
mIntent.putExtra("Manager_employee_number", mManagerNumber);
mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
v.getContext().startActivity(mIntent);
}
});
holder.mTopCardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mCallback != null) {
mCallback.onTopListClick(cursor);
Log.i("FROMCLICK", DatabaseUtils.dumpCursorToString(cursor));
}
}
});
}
public static class ViewHolder {
TextView tvFirstName;
TextView tvLastName;
TextView tvTitle;
ImageView mPeepPic;
ImageButton mDetailsButton;
CardView mTopCardView;
}
}
@Override
public void onTopListClick(Cursor cursor) {
Log.i("FistClickBeforePassing", DatabaseUtils.dumpCursorToString(cursor));
BottomFragment bottomFragment = (BottomFragment) getSupportFragmentManager().findFragmentById(R.id.bottomFragment);
bottomFragment.refreshList(cursor);
}
您无需在每次更新游标时都创建新的适配器。使用 mTopAdapter
作为在 onCreateView()
中初始化的成员,然后使用 update()
方法更新光标:
mTopAdapter.changeCursor(customCursor1);
mtopAdapter.notifyDataSetChanged();
更新:始终将 mTopCursor
中的行保留为最后一行
基于 this answer, you can use MergeCursor
将您的 customCursor1
和 mTopCursor
合并为一个供适配器使用的新游标:
public void update(Cursor cursor) {
if (cursor.moveToFirst()) {
customCursor1.addRow(new Object[]{cursor.getInt(0), cursor.getString(cursor.getColumnIndex("Employee_number")), cursor.getString(2),
cursor.getString(3), cursor.getString(6), cursor.getString(9), cursor.getString(8), cursor.getString(4),
cursor.getString(5), cursor.getString(10), cursor.getString(7), cursor.getString(11)});
MergeCursor newCursor = new MergeCursor(new Cursor[] {customCursor1, mTopCursor});
mTopAdapter.swapCursor(newCursor);
mtopAdapter.notifyDataSetChanged();
customCursor1.close();
}
}
您是否在适配器上尝试过 notifyDataSetChanged?
在我的自定义适配器中,它看起来像这样:
public void removeAllItems(MyDbHelper dbHelper)
{
//Go ahead and delete everything
...
notifyDataSetChanged();
}
对于变化不大的其他类似选项,如下所示:
notifyItemInserted(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mInjections.size());
我正在从屏幕下半部分的列表视图中取出光标并将其添加到上半部分列表视图。这并没有像预期的那样 100% 地工作。我第一次单击底行时,它会将该行正确添加到位置 0 的顶部列表视图中,并在其下方显示该行(该行在应用程序打开时存在)。太好了,这就是我想要的,除非我单击 bottomList 中的另一行。该行添加到 2 的位置,基本上不会变为 0 并将其他 2 向下推。
现在,这不符合我的要求,我相信这总是搞乱我的 onClick 事件,因为从被点击的 topList 传递的数据现在是错误的。不确定两者是否相关,所以尝试至少让 topList 正确显示然后我可以调试更多并查看为什么传递的数据不正确。
这是我使用从 bottomList 传递的光标更新 topList 的代码
public class TopFragment extends Fragment {
public Cursor mTopCursor;
EmployeeDBHandler dbHandler;
ListView mTopListView;
public static MatrixCursor customCursor1;
int flag = 0;
TopListCursorAdapter mTopAdapter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_top_list, container, false);
String table = "employees";
customCursor1 = new MatrixCursor(new String[]{"_id", "Employee_number", "First_name",
"Last_name", "Payroll_title", "ThumbnailData", "Email", "Phone_mobile", "Phone_office", "Cost_center_id",
"Has_direct_reports", "Manager_employee_number"});
dbHandler = EmployeeDBHandler.getInstance(getContext());
SQLiteDatabase db = dbHandler.getWritableDatabase();
int mStartingEmployeeID = mStartingNumber;
mTopCursor = db.rawQuery("SELECT * FROM " + table + " WHERE " + "Employee_number" + "=" + mStartingEmployeeID, null);
mTopListView = (ListView) view.findViewById(R.id.mTopList);
mTopAdapter = new TopListCursorAdapter(getContext(), mTopCursor);
mTopListView.setAdapter(mTopAdapter);
customCursor1.close();
db.close();
return view;
}
public void update(Cursor cursor) {
if (cursor.moveToFirst()) {
customCursor1.addRow(new Object[]{cursor.getInt(0), cursor.getString(cursor.getColumnIndex("Employee_number")), cursor.getString(2),
cursor.getString(3), cursor.getString(6), cursor.getString(9), cursor.getString(8), cursor.getString(4),
cursor.getString(5), cursor.getString(10), cursor.getString(7), cursor.getString(11)});
if (flag == 0) {
customCursor1.addRow(new Object[]{mTopCursor.getInt(0), mTopCursor.getString(cursor.getColumnIndex("Employee_number")), mTopCursor.getString(2),
mTopCursor.getString(3), mTopCursor.getString(6), mTopCursor.getString(9),
mTopCursor.getString(8), mTopCursor.getString(4), mTopCursor.getString(5),
mTopCursor.getString(10), mTopCursor.getString(7), mTopCursor.getString(11)});
flag++;
} else {
flag = 1;
}
mTopAdapter.changeCursor(customCursor1);
customCursor1.close();
}
}
}
public class TopListCursorAdapter extends CursorAdapter {
public interface TopListClickListener {
void onTopListClick(Cursor cursor);
}
private TopListClickListener mCallback;
public TopListCursorAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
if(!(context instanceof TopListClickListener)) {
throw new ClassCastException("Content must implement BottomListClickListener");
}
this.mCallback = (TopListClickListener) context;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.contact_cardview_top, parent, false);
}
@Override
public void bindView(View view, final Context context, final Cursor cursor) {
ViewHolder holder;
holder = new ViewHolder();
holder.tvFirstName = (TextView) view.findViewById(R.id.personFirstName);
holder.tvLastName = (TextView) view.findViewById(R.id.personLastName);
holder.tvTitle = (TextView) view.findViewById(R.id.personTitle);
holder.mPeepPic = (ImageView) view.findViewById(R.id.person_photo);
holder.mDetailsButton = (ImageButton) view.findViewById(R.id.fullDetailButton);
holder.mTopCardView = (CardView) view.findViewById(R.id.mTopHomeScreenCV);
String mFirstName = cursor.getString(cursor.getColumnIndexOrThrow("First_name"));
String mLastName = cursor.getString(cursor.getColumnIndexOrThrow("Last_name"));
String mPayrollTitle = cursor.getString(cursor.getColumnIndexOrThrow("Payroll_title"));
String mThumbnail = cursor.getString(cursor.getColumnIndexOrThrow("ThumbnailData"));
holder.tvFirstName.setText(mFirstName);
holder.tvLastName.setText(mLastName);
holder.tvTitle.setText(mPayrollTitle);
if (mThumbnail != null) {
byte[] imageAsBytes = Base64.decode(mThumbnail.getBytes(), Base64.DEFAULT);
Bitmap parsedImage = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length);
holder.mPeepPic.setImageBitmap(parsedImage);
} else {
holder.mPeepPic.setImageResource(R.drawable.img_place_holder_adapter);
}
final int position = cursor.getPosition();
holder.mDetailsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cursor.moveToPosition(position);
String mEmployeeNumber = cursor.getString(cursor.getColumnIndex("Employee_number"));
String mFirstName = cursor.getString(cursor.getColumnIndex("First_name"));
String mLastName = cursor.getString(cursor.getColumnIndex("Last_name"));
String mTitle = cursor.getString(cursor.getColumnIndex("Payroll_title"));
String mPic = cursor.getString(cursor.getColumnIndex("ThumbnailData"));
String mEmail = cursor.getString(cursor.getColumnIndex("Email"));
String mPhoneMobile = cursor.getString(cursor.getColumnIndex("Phone_mobile"));
String mPhoneOffice = cursor.getString(cursor.getColumnIndex("Phone_office"));
String mCostCenter = cursor.getString(cursor.getColumnIndex("Cost_center_id"));
String mHasDirectReports = cursor.getString(cursor.getColumnIndex("Has_direct_reports"));
String mManagerNumber = cursor.getString(cursor.getColumnIndex("Manager_employee_number"));
Intent mIntent = new Intent(context, EmployeeFullInfo.class);
mIntent.putExtra("Employee_number", mEmployeeNumber);
mIntent.putExtra("First_name", mFirstName);
mIntent.putExtra("Last_name", mLastName);
mIntent.putExtra("Payroll_title", mTitle);
mIntent.putExtra("ThumbnailData", mPic);
mIntent.putExtra("Email", mEmail);
mIntent.putExtra("Phone_mobile", mPhoneMobile);
mIntent.putExtra("Phone_office", mPhoneOffice);
mIntent.putExtra("Cost_center_id", mCostCenter);
mIntent.putExtra("Has_direct_reports", mHasDirectReports);
mIntent.putExtra("Manager_employee_number", mManagerNumber);
mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
v.getContext().startActivity(mIntent);
}
});
holder.mTopCardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mCallback != null) {
mCallback.onTopListClick(cursor);
Log.i("FROMCLICK", DatabaseUtils.dumpCursorToString(cursor));
}
}
});
}
public static class ViewHolder {
TextView tvFirstName;
TextView tvLastName;
TextView tvTitle;
ImageView mPeepPic;
ImageButton mDetailsButton;
CardView mTopCardView;
}
}
@Override
public void onTopListClick(Cursor cursor) {
Log.i("FistClickBeforePassing", DatabaseUtils.dumpCursorToString(cursor));
BottomFragment bottomFragment = (BottomFragment) getSupportFragmentManager().findFragmentById(R.id.bottomFragment);
bottomFragment.refreshList(cursor);
}
您无需在每次更新游标时都创建新的适配器。使用 mTopAdapter
作为在 onCreateView()
中初始化的成员,然后使用 update()
方法更新光标:
mTopAdapter.changeCursor(customCursor1);
mtopAdapter.notifyDataSetChanged();
更新:始终将 mTopCursor
中的行保留为最后一行
基于 this answer, you can use MergeCursor
将您的 customCursor1
和 mTopCursor
合并为一个供适配器使用的新游标:
public void update(Cursor cursor) {
if (cursor.moveToFirst()) {
customCursor1.addRow(new Object[]{cursor.getInt(0), cursor.getString(cursor.getColumnIndex("Employee_number")), cursor.getString(2),
cursor.getString(3), cursor.getString(6), cursor.getString(9), cursor.getString(8), cursor.getString(4),
cursor.getString(5), cursor.getString(10), cursor.getString(7), cursor.getString(11)});
MergeCursor newCursor = new MergeCursor(new Cursor[] {customCursor1, mTopCursor});
mTopAdapter.swapCursor(newCursor);
mtopAdapter.notifyDataSetChanged();
customCursor1.close();
}
}
您是否在适配器上尝试过 notifyDataSetChanged?
在我的自定义适配器中,它看起来像这样:
public void removeAllItems(MyDbHelper dbHelper)
{
//Go ahead and delete everything
...
notifyDataSetChanged();
}
对于变化不大的其他类似选项,如下所示:
notifyItemInserted(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mInjections.size());