À l'aide du Curseur avec ListView adaptateur pour une grande quantité de données

je suis en utilisant une mesure CursorAdapter pour obtenir des données à partir d'une base de données SQLite et l'afficher dans un contrôle listview. Cette base de données contient 2 colonnes avec environ 8.000 lignes. donc, je suis à la recherche d'un moyen d'interroger et de montrer toutes les données aussi rapidement que possible. je l'ai fait avec asyncTask voici le code:

private class PrepareAdapter extends AsyncTask<Void,Void,CustomCursorAdapter > {

 @Override
 protected void onPreExecute() {
     dialog.setMessage("Wait");
     dialog.setIndeterminate(true);
     dialog.setCancelable(false);
     dialog.show();


     Log.e("TAG","Posle nov mAdapter");
 }

 @Override
 protected CustomCursorAdapter doInBackground(Void... unused) {

   Cursor cursor =  myDbNamesHelper.getCursorQueryWithAllTheData();
   mAdapter.changeCursor(cursor);
   startManagingCursor(cursor);
   Log.e("TIME","posle start managing Cursor" + String.valueOf(SystemClock.elapsedRealtime()-testTime)+ " ms");
     testTime=SystemClock.elapsedRealtime();

     mAdapter.initIndexer(cursor);
     return mAdapter;
 }

 protected void onPostExecute(CustomCursorAdapter result) {

     TabFirstView.this.getListView().setAdapter(result);
     Log.e("TIME","posle adapterSet" + String.valueOf(SystemClock.elapsedRealtime()-testTime)+ " ms");
    testTime=SystemClock.elapsedRealtime();
     dialog.dismiss();
 }

}

cela fonctionne bien sauf la partie quand j'ai besoin de mettre le résultat dans un adaptateur. j'ai fait quelques tests de temps et il faut environ 700 ms pour faire passé le startManagingCursor. le problème est que cela prend environ 7 secondes pour le faire passé le setAdapter(suite) et c'est en cours d'exécution dans le thread de l'INTERFACE utilisateur de sorte qu'il rend mon application ne répond pas (la boîte de dialogue de progression se fige et ne sont, parfois, de l'application). comment puis-je faire de ce temps? puis-je faire cela aussi s'exécuter en arrière-plan ou un moyen d'augmenter la réactivité?

tnx.

public class CustomCursorAdapter extends SimpleCursorAdapter implements OnClickListener,SectionIndexer,Filterable,
android.widget.AdapterView.OnItemClickListener{
private Context context;
private int layout;
private AlphabetIndexer alphaIndexer;
public CustomCursorAdapter (Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
this.context = context;
this.layout = layout;
}
public void initIndexer(Cursor c){
alphaIndexer=new AlphabetIndexer(c, c.getColumnIndex(DataBaseNamesHelper.COLUMN_NAME), " ABCDEFGHIJKLMNOPQRSTUVWXYZ");
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
Cursor c = getCursor();
final LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(layout, parent, false);
int nameCol = c.getColumnIndex(DataBaseNamesHelper.COLUMN_NAME);
String name = c.getString(nameCol);
/**
* Next set the name of the entry.
*/
TextView name_text = (TextView) v.findViewById(R.id.name_entry);
if (name_text != null) {
name_text.setText(name);
}
int favCol = c.getColumnIndex(DataBaseNamesHelper.COLUMN_FAVOURITED);
int fav = c.getInt(favCol);
int idCol = c.getColumnIndex(DataBaseNamesHelper.COLUMN_ID);
Button button = (Button) v.findViewById(R.id.Button01);
button.setOnClickListener(this);
button.setTag(c.getInt(idCol));
if(fav==1){
button.setVisibility(View.INVISIBLE);
}
else button.setVisibility(View.VISIBLE);
return v;
}
@Override
public void bindView(View v, Context context, Cursor c) {
int nameCol = c.getColumnIndex(DataBaseNamesHelper.COLUMN_NAME);
String name = c.getString(nameCol);
/**
* Next set the name of the entry.
*/
TextView name_text = (TextView) v.findViewById(R.id.name_entry);
if (name_text != null) {
name_text.setText(name);
}
int favCol = c.getColumnIndex(DataBaseNamesHelper.COLUMN_FAVOURITED);
int fav = c.getInt(favCol);
Button button = (Button) v.findViewById(R.id.Button01);
button.setOnClickListener(this);
int idCol = c.getColumnIndex(DataBaseNamesHelper.COLUMN_ID);
button.setTag(c.getInt(idCol));
// Log.e("fav",String.valueOf(fav));
if(fav==1){
button.setVisibility(View.INVISIBLE);
} else button.setVisibility(View.VISIBLE);
}
@Override
public int getPositionForSection(int section) {
return alphaIndexer.getPositionForSection(section);
}
@Override
public int getSectionForPosition(int position) {
return alphaIndexer.getSectionForPosition(position);
}
@Override
public Object[] getSections() {
return alphaIndexer.getSections();
}
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Log.e("item Click", arg1.toString()+ " position> " +arg2);
}
@Override
public void onClick(View v) {
if(v.getId()==R.id.Button01){
//Log.e("Button Click", v.toString()+ " position> " +v.getTag().toString());
v.setVisibility(View.INVISIBLE);
DataBaseNamesHelper dbNames = new DataBaseNamesHelper(context);
dbNames.setFavouritesFlag(v.getTag().toString());
}
}
}
Vos utilisateurs veulent vraiment faire défiler 8000 lignes dans une liste? Est-il un moyen pour eux de filtrer la liste en premier?
j'ai un fastscroll avec l'indexation mis en œuvre. et je vais ajouter une option de recherche plus tard à filtre.
En tout cas, on POURRAIT faire la requête dans un thread séparé et à l'attribuer à la carte, mais qui laisserait de votre application noir pendant 7 secondes. Sauf si vous avez un moyen de divertir l'utilisateur pendant 7 secondes?
bien le point de l'ensemble de l'application est d'avoir cette quantité de données. L'utilisateur doit être capable de faire défiler librement et ensuite choisir quelque chose de le filtrer pour plus d'info pertinente, et comme je l'ai dit, l'option de recherche vont le faire aussi. mais il doit être capable de faire défiler afin qu'il puisse se faire une idée de ce qu'il faut rechercher.
Je suis en train de faire quelque chose de similaire ICI stackoverflow.com/questions/10224233/...

OriginalL'auteur DArkO | 2010-12-02