#android #android-listview
#Android #android-listview
Вопрос:
Я получил этот ListView, который заполняется из данных JSON в Интернете. Но когда я обновил запись JSON, например, добавив новую запись, ListView не обновляется. Он не показывает новую запись в списке, хотя я уже вызвал notifyDataSetChanged().
Вот мой код:
public class ProjectsList extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.projects_list);
Intent serviceIntent = new Intent(this, LooserSync.class);
startService(serviceIntent);
ListView listView = (ListView) findViewById(R.id.lstText);
MySimpleCursorAdapter projectAdapter = new MySimpleCursorAdapter(this, R.layout.listitems,
managedQuery(Uri.withAppendedPath(LooserProvider.CONTENT_URI,
Database.Project.NAME), new String[] { BaseColumns._ID,
Database.Project.C_PROJECTTITLE, Database.Project.C_SMALLIMAGE }, null, null,
null), new String[] { Database.Project.C_PROJECTTITLE, Database.Project.C_SMALLIMAGE }, new int[] {
R.id.txt_title, R.id.image });
listView.setAdapter(projectAdapter);
projectAdapter.notifyDataSetChanged();
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent i = new Intent(ProjectsList.this, DetailsActivity.class);
i.setData(Uri.withAppendedPath(Uri.withAppendedPath(
LooserProvider.CONTENT_URI, Database.Project.NAME), Long
.toString(id)));
i.putExtra("spendino.de.ProjectDetail.position",position);
startActivity(i);
}
});
}
class MySimpleCursorAdapter extends SimpleCursorAdapter {
public MySimpleCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
loader = new ImageLoaderCache(context);
this.context = context;
}
Activity activity= ProjectsList.this;
Context context=null;
ImageLoaderCache loader = null;
public void setViewImage(ImageView v, String value) {
v.setTag(value);
loader.displayImage(value, activity, v);
}
}
}
ОБНОВЛЕНО вот LooserSync.java
public class LooserSync extends IntentService {
public LooserSync() {
super("LooserSyncService");
}
@Override
protected void onHandleIntent(Intent intent) {
Database.OpenHelper dbhelper = new Database.OpenHelper(getBaseContext());
SQLiteDatabase db = dbhelper.getWritableDatabase();
DefaultHttpClient httpClient = new DefaultHttpClient();
db.beginTransaction();
HttpGet request = new HttpGet(
"http://liebenwald.spendino.net/admanager/dev/android/projects.json");
try {
HttpResponse response = httpClient.execute(request);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
InputStream instream = response.getEntity().getContent();
BufferedReader r = new BufferedReader(new InputStreamReader(
instream), 8000);
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line);
}
instream.close();
String bufstring = total.toString();
JSONArray arr = new JSONArray(bufstring);
Database.Tables tab = Database.Tables.AllTables.get(Database.Project.NAME);
tab.DeleteAll(db);
for (int i = 0; i < arr.length(); i ) {
tab.InsertJSON(db, (JSONObject) arr.get(i));
}
db.setTransactionSuccessful();
}
} catch (Exception e) {
e.printStackTrace();
}
db.endTransaction();
db.close();
}
}
Комментарии:
1. вы забыли ‘getContentResolver().notifyChange( Uri.withAppendedPath(LooserProvider. CONTENT_URI, база данных. Project.NAME ), null);’ в моем последнем примере есть меню под названием sync, чтобы показать, как обновить данные
2. Итак, я установил это: ‘ListView.setAdapter(проектный адаптер); getContentResolver().notifyChange(Uri.с добавленным путем (LooserProvider. CONTENT_URI, база данных. Project.NAME ), null);’ но все же я не знаю, почему новая запись в моем списке не читается?
Ответ №1:
Поскольку вы используете курсор для заполнения списка, вам нужно получить новый или запросить старый после того, как вы что-то изменили (добавили, отредактировали или удалили) в своей модели.
Когда вы получите новый курсор, вы можете передать его адаптеру, вызвав changeCursor().
Обновить
Следующий код будет получать новый курсор при каждом вызове onResume(). Итак, ваш список должен быть актуальным. Конечно, изменения в модели, которые вносятся во время отображения списка, не обновляются до списка. Если вы хотите оперативное обновление списка, вы должны реализовать какой-то шаблон наблюдателя. Таким образом, ваша активность будет получать уведомления при изменении модели.
public class ProjectsList extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.projects_list);
Intent serviceIntent = new Intent(this, LooserSync.class);
startService(serviceIntent);
ListView listView = (ListView) findViewById(R.id.lstText);
final String[] from = new String[] { Database.Project.C_PROJECTTITLE, Database.Project.C_SMALLIMAGE };
final int[] to = new int[] {R.id.txt_title, R.id.image};
MySimpleCursorAdapter projectAdapter = new MySimpleCursorAdapter(this, R.layout.listitems, null, from, to);
listView.setAdapter(projectAdapter);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent i = new Intent(ProjectsList.this, DetailsActivity.class);
i.setData(Uri.withAppendedPath(Uri.withAppendedPath(
LooserProvider.CONTENT_URI, Database.Project.NAME), Long
.toString(id)));
i.putExtra("spendino.de.ProjectDetail.position",position);
startActivity(i);
}
});
}
public void onResume(){
Cursor cursor = managedQuery(Uri.withAppendedPath(LooserProvider.CONTENT_URI,
Database.Project.NAME), new String[] { BaseColumns._ID,
Database.Project.C_PROJECTTITLE, Database.Project.C_SMALLIMAGE }, null, null, null);
ListView listView = (ListView) findViewById(R.id.lstText);
((CursorAdapter)listView.getAdapter()).changeCursor(cursor);
}
Комментарии:
1. Да, но не могли бы вы сначала сказать мне, где происходит обновление данных, тогда я могу сказать вам, где вы должны получить новый курсор или запросить старый.
2. Я думаю, что это здесь намерение serviceIntent = новое намерение (это, LooserSync.class ); startService(serviceIntent);, Я только что обновил свой вопрос. Пожалуйста, взгляните. Спасибо
3. Хорошо, вы используете сервис. Но как происходит поток управления? Может ли модель измениться в любое время или только за пределами действия ProjectsList? Лучший способ — запросить и привязать курсор к адаптеру в методе onResume (), чтобы вы получали обновленные данные каждый раз, когда обновляется onResume().
4. Хорошо, можете ли вы предоставить мне пример с моим кодом выше? Это было бы очень полезно и понятно 🙂
5. Большое спасибо, но мне интересно, почему я получил ошибку в этой строке: ((CursorAdapter)getListAdapter()).changeCursor(курсор);
Ответ №2:
projectAdapter.notifyDataSetChanged();
замените приведенную выше строку на заданную строку blow, тогда вы получите решение своей проблемы.
((MySimpleCursorAdapter)(ProjectsList.listView.getAdapter())).notifyDataSetChanged();
Ошибка: Вы должны получить адаптер для просмотра списка после того, как вы уведомите адаптер о списке.
Комментарии:
1. Хорошо, пожалуйста, укажите любое событие для уведомления адаптера, такое как событие OnClick или любое другое событие, и поместите его в строку с в событие и удалите форму там.
2. Я действительно не понимаю, что вы имеете в виду, можете ли вы предоставить мне код для решения вместо этого? Спасибо