Search code examples
androidlistviewandroid-cursoradapter

Line by line output in the ListView with ArrayAdapter


I have an adapter, which get second parameter from "while" loop, so it must show me a query result in the ListView but it only shows me the last meaning of variable "string_word" instead. But even log.d output what I want line by line. Here is the code :

public class MainActivity extends Activity implements OnClickListener {

final String LOG_TAG = "myLogs";

IdDB idh;
SynDB sqh;
SQLiteDatabase sqdb, iddb;
Button btnOk;
EditText etWord;
String eWord;
ListView lvMain;
public ArrayAdapter<String> adapter;



public String string_word;
public String[] syns;



public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    etWord = (EditText) findViewById(R.id.etWord);
    btnOk = (Button) this.findViewById(R.id.btnOk);
    lvMain = (ListView) findViewById(R.id.lvMain);
    btnOk.setOnClickListener(btnOkListener);

    //initialize our class-cover IdDB
    idh = new IdDB(this);

    // initialize our class-cover SynDB
    sqh = new SynDB(this);

    // we need db to read and write
    sqdb = sqh.getWritableDatabase();
    iddb = idh.getWritableDatabase();





}
  public void displayListView(){
      // создаем адаптер
      adapter = new ArrayAdapter<String>(this,
              android.R.layout.simple_list_item_1, syns);

  }



   public OnClickListener btnOkListener = new OnClickListener(){

        @Override
        public void onClick(View v) {

            eWord = etWord.getText().toString();



            switch (v.getId()){

                case R.id.btnOk:

                    String query = //long SQL query (return "word")

                    Log.d(LOG_TAG, query);
                    Log.d(LOG_TAG, "--- Rows in mytable: ---");

                    // query to get Cursor
                    Cursor cursor = sqdb.rawQuery(query, null);



                    int wordColIndex = cursor.getColumnIndex(SynDB.Word);
                    while (cursor.moveToNext()) {

                    string_word = cursor.getString(wordColIndex);
                    Log.d(LOG_TAG, "word = "+ string_word);
                    syns = new String[] {string_word};
                    displayListView();
                    // присваиваем адаптер списку
                    lvMain.setAdapter(adapter);

                }

                cursor.close();


                break;

                default:
                    break;
            } // close switch
        } // close onClick
    };




protected void onStop() {
    super.onStop();
    sqdb.close();
    sqh.close();
}
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}


@Override
public void onClick(View view) {

 }


}

Solution

  • What it does:

    1. Create an array with one item string_word calls displayListView and set another adapter to the ListView

    And do it everytime i gets a value from the list.

    To do what you want, you should change your logic a bit.

    1. You will create the adapter only one time.
    2. You will add every string to a List (more flexible than an array since here you don't know how many words you will have)

    So:

    Delete all displayListView method calls and add one in the onCreate. (and every lvMain.setAdapter(adapter);)

    Your displayListView should be the only one which sets the adapter to the ListView

    public void displayListView(){
        // создаем адаптер
        adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, syns);
        lvMain.setAdapter(adapter);
    }
    

    Something like:

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        etWord = (EditText) findViewById(R.id.etWord);
        btnOk = (Button) this.findViewById(R.id.btnOk);
        lvMain = (ListView) findViewById(R.id.lvMain);
        btnOk.setOnClickListener(btnOkListener);
    
        //initialize our class-cover IdDB
        idh = new IdDB(this);
    
        // initialize our class-cover SynDB
        sqh = new SynDB(this);
    
        // we need db to read and write
        sqdb = sqh.getWritableDatabase();
        iddb = idh.getWritableDatabase();
    
        displayListView();
    }
    

    Go in the top where is

    public String[] syns;
    

    and change it type to List<String> (ArrayAdapter have a constructor with List, so don't worry.)

    public List<String> syns;
    

    Here your

    int wordColIndex = cursor.getColumnIndex(SynDB.Word);
    while (cursor.moveToNext()) {
    
        string_word = cursor.getString(wordColIndex);
        Log.d(LOG_TAG, "word = "+ string_word);
        syns = new String[] {string_word};
        displayListView();
        // присваиваем адаптер списку
        lvMain.setAdapter(adapter);
    }
    

    should look like

    int wordColIndex = cursor.getColumnIndex(SynDB.Word);
    while (cursor.moveToNext()) {
    
        string_word = cursor.getString(wordColIndex);
        Log.d(LOG_TAG, "word = "+ string_word);
        syns = new String[] {string_word};
    }
    

    Now you should add to the List every word the Cursor return, so you should use .add method.

    int wordColIndex = cursor.getColumnIndex(SynDB.Word);
    while (cursor.moveToNext()) {
    
        string_word = cursor.getString(wordColIndex);
        Log.d(LOG_TAG, "word = "+ string_word);
        syns.add(string_word);
    }
    

    When ready, call adapter.notifyDataSetChanged() to notify to the Adapter that you finished to change your data and can redraw the items in the ListView