BaseAdapter.notifyDatasetChanged () ne met pas à jour ListView
pourquoi mon listview pas à jour quand je l'appelle notifyDatasetChanged() ?
la seule façon que je peux le faire afficher les données sont, à l'appel setAdatper() dans la liste de nouveau... j'ai aussi essayé de l'appeler via runOnUIThread() qui n'a pas changer quoi que ce soit
L'Adaptateur
/**
* Adapter to provide the data for the online scores
*
* @author soh#zolex
*
*/
public class OnlineScoresAdapter extends BaseAdapter {
private Context context;
private List<ScoreItem> scores = new ArrayList<ScoreItem>();
/**
* Constructor
*
* @param Context context
*/
public OnlineScoresAdapter(Context context) {
this.context = context;
}
/**
* Add an item to the adapter
*
* @param item
*/
public void addItem(ScoreItem item) {
this.scores.add(item);
}
/**
* Get the number of scores
*
* @return int
*/
public int getCount() {
return this.scores.size();
}
/**
* Get a score item
*
* @param int pos
* @return Object
*/
public Object getItem(int pos) {
return this.scores.get(pos);
}
/**
* Get the id of a score
*
* @param in pos
* @retrn long
*/
public long getItemId(int pos) {
return 0;
}
/**
* Get the type of an item view
*
* @param int pos
* @return int
*/
public int getItemViewType(int arg0) {
return arg0;
}
/**
* Create the view for a single list item.
* Load it from an xml layout.
*
* @param int pos
* @param View view
* @param ViewGroup viewGroup
* @return View
*/
public View getView(int pos, View view, ViewGroup group) {
LinearLayout layout;
if (view == null) {
layout = (LinearLayout)View.inflate(this.context, R.layout.scoreitem, null);
} else {
layout = (LinearLayout)view;
}
TextView position = (TextView)layout.findViewById(R.id.pos);
TextView time = (TextView)layout.findViewById(R.id.time);
TextView player = (TextView)layout.findViewById(R.id.player);
TextView createdAt = (TextView)layout.findViewById(R.id.created_at);
ScoreItem item = (ScoreItem)getItem(pos);
player.setText(item.player);
position.setText(String.valueOf(new Integer(item.position)) + ".");
time.setText(String.format("%.4f", item.time));
createdAt.setText(item.created_at);
return layout;
}
/**
* Get the number of different views
*
* @return int
*/
public int getViewTypeCount() {
return 1;
}
/**
* Return wheather the items have stable IDs or not
*
* @return boolean
*/
public boolean hasStableIds() {
return false;
}
/**
* Return wheather the list is empty or not
*
* @return boolean
*/
public boolean isEmpty() {
return this.scores.size() == 0;
}
/**
* No need of a data observer
*
* @param DataSetObserver arg0
* @return void
*/
public void registerDataSetObserver(DataSetObserver arg0) {
}
/**
* No need of a data observer
*
* @param DataSetObserver arg0
* @return void
*/
public void unregisterDataSetObserver(DataSetObserver arg0) {
}
/**
* No item should be selectable
*
* @return boolean
*/
public boolean areAllItemsEnabled() {
return false;
}
/**
* No item should be selectable
*
* @param int pos
* @return boolean
*/
public boolean isEnabled(int arg0) {
return false;
}
}
L'Activité
La XMLLoaderThread fonctionne très bien, c'est juste notifyDatasetChanged semble ne rien faire...
/**
* Obtain and display the online scores
*
* @author soh#zolex
*
*/
public class OnlineScoresDetails extends ListActivity {
WakeLock wakeLock;
OnlineScoresAdapter adapter;
boolean isLoading = false;
int chunkLimit = 50;
int chunkOffset = 0;
@Override
/**
* Load the scores and initialize the pager and adapter
*
* @param Bundle savedInstanceState
*/
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
this.wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "racesow");
adapter = new OnlineScoresAdapter(this);
setListAdapter(adapter);
this.loadData();
setContentView(R.layout.listview);
getListView().setOnScrollListener(new OnScrollListener() {
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (totalItemCount > 0 && visibleItemCount > 0 && firstVisibleItem + visibleItemCount >= totalItemCount) {
if (!isLoading) {
loadData();
}
}
}
});
}
public void loadData() {
final ProgressDialog pd = new ProgressDialog(OnlineScoresDetails.this);
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.setMessage("Obtaining scores...");
pd.setCancelable(false);
pd.show();
isLoading = true;
String mapName = getIntent().getStringExtra("map");
XMLLoaderThread t = new XMLLoaderThread("http://racesow2d.warsow-race.net/map_positions.php?name=" + mapName + "&offset=" + this.chunkOffset + "&limit=" + this.chunkLimit, new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
//network error
case 0:
new AlertDialog.Builder(OnlineScoresDetails.this)
.setMessage("Could not obtain the maplist.\nCheck your network connection and try again.")
.setNeutralButton("OK", new OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
finish();
overridePendingTransition(0, 0);
}
})
.show();
break;
//maplist received
case 1:
pd.dismiss();
InputStream xmlStream;
try {
xmlStream = new ByteArrayInputStream(msg.getData().getString("xml").getBytes("UTF-8"));
XMLParser parser = new XMLParser();
parser.read(xmlStream);
NodeList positions = parser.doc.getElementsByTagName("position");
int numPositions = positions.getLength();
for (int i = 0; i < numPositions; i++) {
Element position = (Element)positions.item(i);
ScoreItem score = new ScoreItem();
score.position = Integer.parseInt(parser.getValue(position, "no"));
score.player = parser.getValue(position, "player");
score.time = Float.parseFloat(parser.getValue(position, "time"));
score.created_at = parser.getValue(position, "created_at");
adapter.addItem(score);
}
adapter.notifyDataSetChanged();
chunkOffset += chunkLimit;
isLoading = false;
} catch (UnsupportedEncodingException e) {
new AlertDialog.Builder(OnlineScoresDetails.this)
.setMessage("Internal error: " + e.getMessage())
.setNeutralButton("OK", null)
.show();
}
break;
}
pd.dismiss();
}
});
t.start();
}
/**
* Acquire the wakelock on resume
*/
public void onResume() {
super.onResume();
this.wakeLock.acquire();
}
/**
* Release the wakelock when leaving the activity
*/
public void onDestroy() {
super.onDestroy();
this.wakeLock.release();
}
/**
* Disable animations when leaving the activity
*/
public void onBackPressed() {
this.finish();
this.overridePendingTransition(0, 0);
}
}
source d'informationauteur Andreas Linden
Vous devez vous connecter pour publier un commentaire.
Un peu de retard, mais la réponse est que vous ne devez pas mettre en œuvre
J'ai juste eu un simple
BaseAdapter
de travail que prévu, qui ont arrêté de travailler après l'ajout de ces deux méthodes. J'asume que "quelqu'un" besoin d'observer les modifications des données et de tel 🙂Je ne suis pas vraiment sûr si votre mise en œuvre de la Coutume BaseAdapter est correct.
Essayez de changer
à
J'ai aussi trouvé ce simple tutoriel qui pourraient être utiles sur la façon de mettre en œuvre BaseAdapter. Après vous obtenez ce vers le bas, vous pouvez essayer de notifyDataSetChanged() de nouveau.
Vous devriez appeler
adapter.notifyDataSetChanged()
après chaque manipulation de votre jeu de données. Si vous êtes en train d'ajouter des éléments dans un batch (par exemple, unfor
en boucle), cela signifie que vous devez mettre .notifyDataSetChanged dans votre boucle, comme ceci:Assurez-vous que vous appelez
adapter.notifyDataSetChanged()
à partir de votre INTERFACE utilisateur-fil.Si vous mettez à jour votre carte une fois, stocker vos
ScoreItem
s dans unArrayList
et après la boucle d'appel:Mais encore une fois, autant que je sache, il n'y a vraiment aucune raison de le faire.