将对象传递给 CursorAdapter 得到 null
Passing object to CursorAdapter getting null
我在主 activity 中收到一个回调,它正在传递一个来自 ListView 单击的值对象。如果我敬酒,敬酒会显示键值对。我想将其添加到 TopListCursorAdapter 以填充新行。我在 topAdapter.notifyDataSetChanged();
上得到空值
不确定如何将 mEmployee 添加到适配器,我已尝试
@Override
public void onBottomListClick(Employee e) {
mEmployee.add(e);
dbHandler.addEmployee(e);
SQLiteDatabase db = dbHandler.getWritableDatabase();
final Cursor clickedEmployee = db.rawQuery("SELECT * FROM " + "employees" + " WHERE " +
"Employee_number" + "=" + e.getEmployee_number(), null);
// change the adapter's Cursor
topAdapter.changeCursor(clickedEmployee);
}
但我不想传递游标,而 TopListCursorAdapter 想要一个。我只想将 mEmployee 添加到 TopListCursorAdapter 中的现有列表中。
public class MainActivity extends FragmentActivity implements BottomListViewAdapter.BottomListClickListener {
private ProgressBar mProgressBar;
EmployeeDBHandler dbHandler;
private TopListCursorAdapter topAdapter;
private BottomListViewAdapter bottomAdapter;
private ArrayList mEmployee;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
dbHandler = new EmployeeDBHandler(getApplicationContext());
mProgressBar.setVisibility(View.VISIBLE);
getXMLData();
//GUI for seeing android SQLite Database in Chrome Dev Tools
Stetho.InitializerBuilder inBuilder = Stetho.newInitializerBuilder(this);
inBuilder.enableWebKitInspector(Stetho.defaultInspectorModulesProvider(this));
Stetho.Initializer in = inBuilder.build();
Stetho.initialize(in);
}
public void getXMLData() {
OkHttpClient client = getUnsafeOkHttpClient();
Request request = new Request.Builder()
.url(getString(R.string.API_FULL_URL))
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
final String responseData = response.body().string();
final InputStream stream = new ByteArrayInputStream(responseData.getBytes());
final XMLPullParserHandler parserHandler = new XMLPullParserHandler();
final ArrayList<Employee> employees = (ArrayList<Employee>) parserHandler.parse(stream);
for (Employee e : employees) {
dbHandler.addEmployee(e);
}
runOnUiThread(new Runnable() {
@Override
public void run() {
mProgressBar.setVisibility(View.GONE);
displayTopList();
displayBottomList();
}
});
}
});
}
public void displayTopList() {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.topFragment, new TopFragment());
fragmentTransaction.commit();
}
public void displayBottomList() {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.bottomFragment, new BottomFragment());
fragmentTransaction.commit();
}
@Override
public void onBottomListClick(Employee e) {
mEmployee.add(e);
dbHandler.addEmployee(e);
SQLiteDatabase db = dbHandler.getWritableDatabase();
final Cursor clickedEmployee = db.rawQuery("SELECT * FROM " + "employees" + " WHERE " +
"Employee_number" + "=" + e.getEmployee_number(), null);
// change the adapter's Cursor
topAdapter.changeCursor(clickedEmployee);
}
}
TopListCursorAdapter
public class TopListCursorAdapter extends CursorAdapter {
private EmployeeDBHandler dbHandler;
private Activity activityRef;
public TopListCursorAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
activityRef = (Activity) context;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.contact_cardview_layout, parent, false);
}
@Override
public void bindView(View view, final Context context, final Cursor cursor) {
dbHandler = new EmployeeDBHandler(context);
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.mCardView = (CardView) view.findViewById(R.id.home_screen_cardView);
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);
}
activityRef.runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
final int position = cursor.getPosition();
holder.mDetailsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cursor.moveToPosition(position);
String mEmployeeNumber = cursor.getString(1);
String mEmail = cursor.getString(8);
String mFirstName = cursor.getString(2);
String mLastName = cursor.getString(3);
String mPhoneMobile = cursor.getString(4);
String mPhoneOffice = cursor.getString(5);
String mCostCenter = cursor.getString(10);
String mHasDirectReports = cursor.getString(7);
String mTitle = cursor.getString(6);
String mPic = cursor.getString(9);
Intent mIntent = new Intent(context, EmployeeFullInfo.class);
mIntent.putExtra("Employee_number", mEmployeeNumber);
mIntent.putExtra("Email", mEmail);
mIntent.putExtra("First_name", mFirstName);
mIntent.putExtra("Last_name", mLastName);
mIntent.putExtra("Phone_mobile", mPhoneMobile);
mIntent.putExtra("Phone_office", mPhoneOffice);
mIntent.putExtra("Cost_center_id", mCostCenter);
mIntent.putExtra("Has_direct_reports", mHasDirectReports);
mIntent.putExtra("Payroll_title", mTitle);
mIntent.putExtra("ThumbnailData", mPic);
mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
v.getContext().startActivity(mIntent);
}
});
}
public static class ViewHolder {
TextView tvFirstName;
TextView tvLastName;
TextView tvTitle;
ImageView mPeepPic;
ImageButton mDetailsButton;
CardView mCardView;
}
}
I do not want to pass a cursor and the TopListCursorAdapter wants one
当然可以。你有一个 DBHandler
可以给你一个 Cursor
。
dbHandler = new EmployeeDBHandler(getApplicationContext());
你有一个 addEmployee
方法。
dbHandler.addEmployee(e);
所以问题是 - 你是如何创建 TopListCursorAdapter
而没有 Cursor
因为它是必需的?
无论如何,你不应该在适配器中插入 EmployeeDBHandler
。
它只需要 Cursor
。另外,你似乎从来没有在那里使用 class 。
public class TopListCursorAdapter extends CursorAdapter {
// private EmployeeDBHandler dbHandler; // ** Not needed
private Context mContext; // Don't need an Activity
public TopListCursorAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
mContext = context; // Just a Context, no Activity
}
并且您永远不需要在第一次创建后创建 new TopListAdapter
,您可以直接在现有适配器上调用 changeCursor
。
@Override
public void onBottomListClick(Employee e) {
mEmployee.add(e);
dbHandler.addEmployee(e);
// topAdapter = new TopListCursorAdapter(); // ** Nope
Cursor newCursor = dbHandler.getEmployees(); // TODO: Implement this
topAdapter.changeCursor(newCursor); // Updates the UI itself
Intent employeeDetail = new Intent(MainActivity.this, EmployeeFullInfo.class);
employeeDetail.putExtra("Employee_number", e.getNumber());
...
startActivity(employeeDetail);
}
注意:如果您 use Parcelable
Employee
对象,则不需要在 Intents 上使用一堆 putExtra
和 getExtra
方法。
此外,您可以将 Employee 对象存储为 ViewHolder 的一部分,以简化数据管理。这样,您只需要将数据从 Cursor
提取到 Employee
,然后 ViewHolder 可以维护它,因为您在 onClick
中重复工作以获得 Cursor
数据。
public static class ViewHolder {
Employee employee; // See here
TextView tvFirstName;
TextView tvLastName;
TextView tvTitle;
ImageView mPeepPic;
ImageButton mDetailsButton;
CardView mCardView;
}
我在主 activity 中收到一个回调,它正在传递一个来自 ListView 单击的值对象。如果我敬酒,敬酒会显示键值对。我想将其添加到 TopListCursorAdapter 以填充新行。我在 topAdapter.notifyDataSetChanged();
上得到空值不确定如何将 mEmployee 添加到适配器,我已尝试
@Override
public void onBottomListClick(Employee e) {
mEmployee.add(e);
dbHandler.addEmployee(e);
SQLiteDatabase db = dbHandler.getWritableDatabase();
final Cursor clickedEmployee = db.rawQuery("SELECT * FROM " + "employees" + " WHERE " +
"Employee_number" + "=" + e.getEmployee_number(), null);
// change the adapter's Cursor
topAdapter.changeCursor(clickedEmployee);
}
但我不想传递游标,而 TopListCursorAdapter 想要一个。我只想将 mEmployee 添加到 TopListCursorAdapter 中的现有列表中。
public class MainActivity extends FragmentActivity implements BottomListViewAdapter.BottomListClickListener {
private ProgressBar mProgressBar;
EmployeeDBHandler dbHandler;
private TopListCursorAdapter topAdapter;
private BottomListViewAdapter bottomAdapter;
private ArrayList mEmployee;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
dbHandler = new EmployeeDBHandler(getApplicationContext());
mProgressBar.setVisibility(View.VISIBLE);
getXMLData();
//GUI for seeing android SQLite Database in Chrome Dev Tools
Stetho.InitializerBuilder inBuilder = Stetho.newInitializerBuilder(this);
inBuilder.enableWebKitInspector(Stetho.defaultInspectorModulesProvider(this));
Stetho.Initializer in = inBuilder.build();
Stetho.initialize(in);
}
public void getXMLData() {
OkHttpClient client = getUnsafeOkHttpClient();
Request request = new Request.Builder()
.url(getString(R.string.API_FULL_URL))
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
final String responseData = response.body().string();
final InputStream stream = new ByteArrayInputStream(responseData.getBytes());
final XMLPullParserHandler parserHandler = new XMLPullParserHandler();
final ArrayList<Employee> employees = (ArrayList<Employee>) parserHandler.parse(stream);
for (Employee e : employees) {
dbHandler.addEmployee(e);
}
runOnUiThread(new Runnable() {
@Override
public void run() {
mProgressBar.setVisibility(View.GONE);
displayTopList();
displayBottomList();
}
});
}
});
}
public void displayTopList() {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.topFragment, new TopFragment());
fragmentTransaction.commit();
}
public void displayBottomList() {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.bottomFragment, new BottomFragment());
fragmentTransaction.commit();
}
@Override
public void onBottomListClick(Employee e) {
mEmployee.add(e);
dbHandler.addEmployee(e);
SQLiteDatabase db = dbHandler.getWritableDatabase();
final Cursor clickedEmployee = db.rawQuery("SELECT * FROM " + "employees" + " WHERE " +
"Employee_number" + "=" + e.getEmployee_number(), null);
// change the adapter's Cursor
topAdapter.changeCursor(clickedEmployee);
}
}
TopListCursorAdapter
public class TopListCursorAdapter extends CursorAdapter {
private EmployeeDBHandler dbHandler;
private Activity activityRef;
public TopListCursorAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
activityRef = (Activity) context;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.contact_cardview_layout, parent, false);
}
@Override
public void bindView(View view, final Context context, final Cursor cursor) {
dbHandler = new EmployeeDBHandler(context);
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.mCardView = (CardView) view.findViewById(R.id.home_screen_cardView);
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);
}
activityRef.runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
final int position = cursor.getPosition();
holder.mDetailsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cursor.moveToPosition(position);
String mEmployeeNumber = cursor.getString(1);
String mEmail = cursor.getString(8);
String mFirstName = cursor.getString(2);
String mLastName = cursor.getString(3);
String mPhoneMobile = cursor.getString(4);
String mPhoneOffice = cursor.getString(5);
String mCostCenter = cursor.getString(10);
String mHasDirectReports = cursor.getString(7);
String mTitle = cursor.getString(6);
String mPic = cursor.getString(9);
Intent mIntent = new Intent(context, EmployeeFullInfo.class);
mIntent.putExtra("Employee_number", mEmployeeNumber);
mIntent.putExtra("Email", mEmail);
mIntent.putExtra("First_name", mFirstName);
mIntent.putExtra("Last_name", mLastName);
mIntent.putExtra("Phone_mobile", mPhoneMobile);
mIntent.putExtra("Phone_office", mPhoneOffice);
mIntent.putExtra("Cost_center_id", mCostCenter);
mIntent.putExtra("Has_direct_reports", mHasDirectReports);
mIntent.putExtra("Payroll_title", mTitle);
mIntent.putExtra("ThumbnailData", mPic);
mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
v.getContext().startActivity(mIntent);
}
});
}
public static class ViewHolder {
TextView tvFirstName;
TextView tvLastName;
TextView tvTitle;
ImageView mPeepPic;
ImageButton mDetailsButton;
CardView mCardView;
}
}
I do not want to pass a cursor and the TopListCursorAdapter wants one
当然可以。你有一个 DBHandler
可以给你一个 Cursor
。
dbHandler = new EmployeeDBHandler(getApplicationContext());
你有一个 addEmployee
方法。
dbHandler.addEmployee(e);
所以问题是 - 你是如何创建 TopListCursorAdapter
而没有 Cursor
因为它是必需的?
无论如何,你不应该在适配器中插入 EmployeeDBHandler
。
它只需要 Cursor
。另外,你似乎从来没有在那里使用 class 。
public class TopListCursorAdapter extends CursorAdapter {
// private EmployeeDBHandler dbHandler; // ** Not needed
private Context mContext; // Don't need an Activity
public TopListCursorAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
mContext = context; // Just a Context, no Activity
}
并且您永远不需要在第一次创建后创建 new TopListAdapter
,您可以直接在现有适配器上调用 changeCursor
。
@Override
public void onBottomListClick(Employee e) {
mEmployee.add(e);
dbHandler.addEmployee(e);
// topAdapter = new TopListCursorAdapter(); // ** Nope
Cursor newCursor = dbHandler.getEmployees(); // TODO: Implement this
topAdapter.changeCursor(newCursor); // Updates the UI itself
Intent employeeDetail = new Intent(MainActivity.this, EmployeeFullInfo.class);
employeeDetail.putExtra("Employee_number", e.getNumber());
...
startActivity(employeeDetail);
}
注意:如果您 use Parcelable
Employee
对象,则不需要在 Intents 上使用一堆 putExtra
和 getExtra
方法。
此外,您可以将 Employee 对象存储为 ViewHolder 的一部分,以简化数据管理。这样,您只需要将数据从 Cursor
提取到 Employee
,然后 ViewHolder 可以维护它,因为您在 onClick
中重复工作以获得 Cursor
数据。
public static class ViewHolder {
Employee employee; // See here
TextView tvFirstName;
TextView tvLastName;
TextView tvTitle;
ImageView mPeepPic;
ImageButton mDetailsButton;
CardView mCardView;
}