使用 CursorAdapter 中的新数据更新相同的 ListView
Update same ListView with new data in CursorAdapter
我真的卡住了,不知道该怎么办。我已经研究了 startActivityForResult
和内容提供商,但我不知道如何为这个应用程序实现它们中的任何一个。
我没有看到如何从数据库中获取数据并使用相同的 listview
更新 displayBottomList
,因此我不必将用户重定向到新的 layout/activity .不确定我是否可以调用新查询并将其设置为不同的游标并在它们之间切换。我已经看到 swapCursor
但使用相同的适配器时它如何工作?
我有一个 ListView
,当用户单击列表中的一行时,我想用 Web 服务调用的新数据刷新它。我正在使用 CursorAdapter
。我可以正确获取行的数据onClick
。
我被卡住的地方是如何更新 listView
以重新填充来自 database/response 的新信息而不将我发送到另一个 Activity。我希望用户保持在同一屏幕上,但只需使用新数据更新 listView
。
当 onClick
在适配器中时,不确定如何让适配器通知适配器更新和填充新的 ListView
,但正在创建 ListView
MainActivity
。
BottomListView
的适配器,单击某行时我想更新的适配器。
public class BottomListViewAdapter extends CursorAdapter {
private String mEmployeeNumber;
private EmployeeDBHandler dbHandler;
public BottomListViewAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
@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 mTitle = cursor.getString(cursor.getColumnIndexOrThrow("Payroll_title"));
String mThumbnail = cursor.getString(cursor.getColumnIndexOrThrow("ThumbnailData"));
holder.tvFirstName.setText(mFirstName);
holder.tvLastName.setText(mLastName);
holder.tvTitle.setText(mTitle);
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 view) {
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);
view.getContext().startActivity(mIntent);
}
});
holder.mCardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cursor.moveToPosition(position);
mEmployeeNumber = cursor.getString(1);
Toast.makeText(context, mEmployeeNumber, Toast.LENGTH_SHORT).show();
callNewDirectReport();
notifyDataSetChanged();
}
});
}
public static class ViewHolder {
TextView tvFirstName;
TextView tvLastName;
TextView tvTitle;
ImageView mPeepPic;
ImageButton mDetailsButton;
CardView mCardView;
}
private void callNewDirectReport() {
String mDirectReportUrl = "mURL";
HttpUrl.Builder urlBuilder = HttpUrl.parse(mDirectReportUrl).newBuilder();
urlBuilder.addQueryParameter("manager_employee_number", mEmployeeNumber);
String url = urlBuilder.build().toString();
OkHttpClient client = getUnsafeOkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, 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);
}
}
});
}
@Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
}
My MainActivity 正在调用适配器
public class MainActivity extends AppCompatActivity {
private ProgressBar mProgressBar;
private BottomListViewAdapter mBottomAdapter;
private View mDividerView;
EmployeeDBHandler dbHandler;
private int mStartingEmployeeID = mStartingID;
private String table = "employees";
private static final int LOADER_INTEGER = 1;
private Cursor mBottomCursor, mTopCursor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
mDividerView = findViewById(R.id.divider);
dbHandler = new EmployeeDBHandler(getApplicationContext());
mProgressBar.setVisibility(View.VISIBLE);
mDividerView.setVisibility(View.GONE);
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);
mDividerView.setVisibility(View.VISIBLE);
displayTopList();
displayBottomList();
}
});
}
});
}
public void displayTopList() {
SQLiteDatabase db = dbHandler.getWritableDatabase();
mTopCursor = db.rawQuery("SELECT * FROM " + table + " WHERE " + "Employee_number" + "=" + mStartingEmployeeID, null);
ListView mTopListView = (ListView) findViewById(R.id.mTopList);
TopListCursorAdapter topAdapter = new TopListCursorAdapter(this, mTopCursor);
mTopListView.setAdapter(topAdapter);
}
public void displayBottomList() {
SQLiteDatabase db = dbHandler.getWritableDatabase();
mBottomCursor = db.rawQuery("SELECT * FROM " + table + " WHERE " +
"Employee_number" + "!=" + mStartingEmployeeID + " AND " +
"Manager_employee_number" + "=" + mStartingEmployeeID + " ORDER BY " +
"Last_name" + " ASC", null);
ListView mBottomListView = (ListView) findViewById(R.id.mDirectReportList);
mBottomAdapter = new BottomListViewAdapter(this, mBottomCursor);
mBottomListView.setAdapter(mBottomAdapter);
mBottomAdapter.notifyDataSetChanged();
}
}
您可以使用 startActivityForResult 接收来自 activity 的回调,这里有一个说明如何使用它的教程:https://developer.android.com/training/basics/intents/result.html
当您在onActivityResult 中收到回调时,您可以更新您的数据并调用notifyDatasetChanged。
您不能从另一个 activity 调用代码,因为活动由 android 处理。 Android 可能会终止您尝试调用的 activity,并会在必要时重新创建它。
现在您在 callNewDirectReport()
中的代码发出 API 请求并将结果存储在数据库中。这不会更新适配器以显示新项目,而是您需要重新查询数据库并获取更新的 Cursor。以下是您如何操作的示例:
public class BottomListViewAdapter extends CursorAdapter {
private String mEmployeeNumber;
private EmployeeDBHandler dbHandler;
private Activity activityRef;
public BottomListViewAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
// keep a reference to the activity
activityRef = (Activity) context;
}
//...
private void callNewDirectReport() {
//...
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, 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);
}
// the new items are in the database so requery the database to get a new fresher Cursor:
SQLiteDatabase db = dbHandler.getWritableDatabase();
Cursor fresherCursor = db.rawQuery("SELECT * FROM " + table + " WHERE " +
"Employee_number" + "!=" + mStartingEmployeeID + " AND " +
"Manager_employee_number" + "=" + mStartingEmployeeID + " ORDER BY " +
"Last_name" + " ASC", null);
//change the adapter's Cursor
activityRef.runOnUiThread(new Runnable() {
public void run() {
swapCursor(freshedCursor);
}
});
}
});
}
}
我真的卡住了,不知道该怎么办。我已经研究了 startActivityForResult
和内容提供商,但我不知道如何为这个应用程序实现它们中的任何一个。
我没有看到如何从数据库中获取数据并使用相同的 listview
更新 displayBottomList
,因此我不必将用户重定向到新的 layout/activity .不确定我是否可以调用新查询并将其设置为不同的游标并在它们之间切换。我已经看到 swapCursor
但使用相同的适配器时它如何工作?
我有一个 ListView
,当用户单击列表中的一行时,我想用 Web 服务调用的新数据刷新它。我正在使用 CursorAdapter
。我可以正确获取行的数据onClick
。
我被卡住的地方是如何更新 listView
以重新填充来自 database/response 的新信息而不将我发送到另一个 Activity。我希望用户保持在同一屏幕上,但只需使用新数据更新 listView
。
当 onClick
在适配器中时,不确定如何让适配器通知适配器更新和填充新的 ListView
,但正在创建 ListView
MainActivity
。
BottomListView
的适配器,单击某行时我想更新的适配器。
public class BottomListViewAdapter extends CursorAdapter {
private String mEmployeeNumber;
private EmployeeDBHandler dbHandler;
public BottomListViewAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
@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 mTitle = cursor.getString(cursor.getColumnIndexOrThrow("Payroll_title"));
String mThumbnail = cursor.getString(cursor.getColumnIndexOrThrow("ThumbnailData"));
holder.tvFirstName.setText(mFirstName);
holder.tvLastName.setText(mLastName);
holder.tvTitle.setText(mTitle);
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 view) {
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);
view.getContext().startActivity(mIntent);
}
});
holder.mCardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cursor.moveToPosition(position);
mEmployeeNumber = cursor.getString(1);
Toast.makeText(context, mEmployeeNumber, Toast.LENGTH_SHORT).show();
callNewDirectReport();
notifyDataSetChanged();
}
});
}
public static class ViewHolder {
TextView tvFirstName;
TextView tvLastName;
TextView tvTitle;
ImageView mPeepPic;
ImageButton mDetailsButton;
CardView mCardView;
}
private void callNewDirectReport() {
String mDirectReportUrl = "mURL";
HttpUrl.Builder urlBuilder = HttpUrl.parse(mDirectReportUrl).newBuilder();
urlBuilder.addQueryParameter("manager_employee_number", mEmployeeNumber);
String url = urlBuilder.build().toString();
OkHttpClient client = getUnsafeOkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, 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);
}
}
});
}
@Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
}
My MainActivity 正在调用适配器
public class MainActivity extends AppCompatActivity {
private ProgressBar mProgressBar;
private BottomListViewAdapter mBottomAdapter;
private View mDividerView;
EmployeeDBHandler dbHandler;
private int mStartingEmployeeID = mStartingID;
private String table = "employees";
private static final int LOADER_INTEGER = 1;
private Cursor mBottomCursor, mTopCursor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
mDividerView = findViewById(R.id.divider);
dbHandler = new EmployeeDBHandler(getApplicationContext());
mProgressBar.setVisibility(View.VISIBLE);
mDividerView.setVisibility(View.GONE);
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);
mDividerView.setVisibility(View.VISIBLE);
displayTopList();
displayBottomList();
}
});
}
});
}
public void displayTopList() {
SQLiteDatabase db = dbHandler.getWritableDatabase();
mTopCursor = db.rawQuery("SELECT * FROM " + table + " WHERE " + "Employee_number" + "=" + mStartingEmployeeID, null);
ListView mTopListView = (ListView) findViewById(R.id.mTopList);
TopListCursorAdapter topAdapter = new TopListCursorAdapter(this, mTopCursor);
mTopListView.setAdapter(topAdapter);
}
public void displayBottomList() {
SQLiteDatabase db = dbHandler.getWritableDatabase();
mBottomCursor = db.rawQuery("SELECT * FROM " + table + " WHERE " +
"Employee_number" + "!=" + mStartingEmployeeID + " AND " +
"Manager_employee_number" + "=" + mStartingEmployeeID + " ORDER BY " +
"Last_name" + " ASC", null);
ListView mBottomListView = (ListView) findViewById(R.id.mDirectReportList);
mBottomAdapter = new BottomListViewAdapter(this, mBottomCursor);
mBottomListView.setAdapter(mBottomAdapter);
mBottomAdapter.notifyDataSetChanged();
}
}
您可以使用 startActivityForResult 接收来自 activity 的回调,这里有一个说明如何使用它的教程:https://developer.android.com/training/basics/intents/result.html
当您在onActivityResult 中收到回调时,您可以更新您的数据并调用notifyDatasetChanged。
您不能从另一个 activity 调用代码,因为活动由 android 处理。 Android 可能会终止您尝试调用的 activity,并会在必要时重新创建它。
现在您在 callNewDirectReport()
中的代码发出 API 请求并将结果存储在数据库中。这不会更新适配器以显示新项目,而是您需要重新查询数据库并获取更新的 Cursor。以下是您如何操作的示例:
public class BottomListViewAdapter extends CursorAdapter {
private String mEmployeeNumber;
private EmployeeDBHandler dbHandler;
private Activity activityRef;
public BottomListViewAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
// keep a reference to the activity
activityRef = (Activity) context;
}
//...
private void callNewDirectReport() {
//...
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, 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);
}
// the new items are in the database so requery the database to get a new fresher Cursor:
SQLiteDatabase db = dbHandler.getWritableDatabase();
Cursor fresherCursor = db.rawQuery("SELECT * FROM " + table + " WHERE " +
"Employee_number" + "!=" + mStartingEmployeeID + " AND " +
"Manager_employee_number" + "=" + mStartingEmployeeID + " ORDER BY " +
"Last_name" + " ASC", null);
//change the adapter's Cursor
activityRef.runOnUiThread(new Runnable() {
public void run() {
swapCursor(freshedCursor);
}
});
}
});
}
}