0
votes


I'm trying to use a ListActivity on my Android App but it isn't working the way it should.
Here is my Activity :

public class MainActivity extends ListActivity {

    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_terminals_list); //The special layout

        TerminalsArrayAdapter adapter = new TerminalsArrayAdapter(this); // A custom adapter
        setListAdapter(adapter);
        RequestTask task = new RequestTask(adapter); // An Async task
        task.execute("/terminals/all");
    }
}

Here is my layout :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ListView 
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

    <TextView
        android:id="@android:id/empty"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Loading..." />
</LinearLayout>

Here is my custom adapter :

public class TerminalsArrayAdapter extends ArrayAdapter<String[]> {

    private Activity mContext;
    private ArrayList<String[]> mObjects = new ArrayList<String[]>();

    public TerminalsArrayAdapter(Activity context) {
        super(context, R.layout.terminals_listview_item);
        this.mContext = context;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View elementView;

        if(convertView==null){
            LayoutInflater inflater = mContext.getLayoutInflater();
            elementView = inflater.inflate(R.layout.terminals_listview_item, parent);
            ...
            // Some things with my view

        } else {
            elementView = convertView;
        }

        ...
        // Some things with my view
        return elementView;
    }

    public void updateTerminals(ArrayList<String[]> newObject){
        mObjects.clear();
        mObjects.addAll(newObject);
        notifyDataSetChanged();
        Log.d("TerminalsArrayAdapter", "Dataset Changed !");
    }
}

And here is my Async task :

public class RequestTask extends AsyncTask<String, Void, ArrayList<String[]>>{

    private final TerminalsArrayAdapter mAdapter;

    public RequestTask(TerminalsArrayAdapter adapter) {
        mAdapter = adapter;
    }

    @Override
    protected ArrayList<String[]> doInBackground(String... params) {

        ...
        // retrieve some data from my server
        return response;
    }

    @Override
    protected void onPostExecute(ArrayList<String[]> response) {
        Log.d("response_server","GOT IT !");
        mAdapter.updateTerminals(response);
    }
}


As I understood, the ListView will be shown only if the adapter is not empty. If it is empty, it will be the TextView which will be displayed.

This is the way my app should work :

  1. The app creates an empty adapter. This will display the "Loading..." TextView
  2. The app creates a new Async task which will retrieve some needed data from my server
  3. When the Async task finishes, it will call the .updateTerminals() method
  4. This method will update the entries of the custom adapter and call notifyDataSetChanged()
  5. The app should now display the ListView with the freshly retrieved data
The steps 1 to 4 are working fine. The problem occurs on step 5 : Even if the data has been updated, my app doesn't refresh the screen to show me the ListView and stays on the "Loading..." TextView.

I tried to figure out what was wrong with my code, but I wasn't able to. I'd love to hear your suggestions/solutions ! Thanks !

PS: Tell me if you need any thing to understand my issue better.
2
|Remove TerminalsArrayAdapter adapter = new TerminalsArrayAdapter(this); // A custom adapter setListAdapter(adapter); fom onCreate and put it in onPostExecute. Add the objects directly in onPostExecute. Remove mAdapter.updateTerminals(response) from onPost|EExecute.greenapps
try to use invalidate method on the list viewBlaze Tama

2 Answers

0
votes

Your ListView height should be match_parent.

Try to play around with setVisibility(View.GONE) and setVisibility(View.VISIBLE) to:

  • show TextView & hide ListView
  • show ListView & hide TextView
0
votes
public class MainActivity extends ListActivity {

    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_terminals_list); //The special layout
        // create your list with specific method to be able call her many time
        // prefer to create then refresh with new data
         CreateList(Passanydata);
         RequestTask task = new RequestTask(adapter); // An Async task
            task.execute("/terminals/all");

    }
}

public void CreateList(ArrayList<String[]> response){
 TerminalsArrayAdapter adapter = new TerminalsArrayAdapter(this,response); // A custom adapter
            setListAdapter(adapter);

}



 @Override
    protected void onPostExecute(ArrayList<String[]> response) {
        Log.d("response_server","GOT IT !");
      // after you got your new data , pass it to your list 
       CreateList(response);
    }




public class TerminalsArrayAdapter extends ArrayAdapter<String[]> {

    private Activity mContext;
    private ArrayList<String[]> mObjects = new ArrayList<String[]>();

    public TerminalsArrayAdapter(Activity context,ArrayList<String[]> objects) {
        super(context, R.layout.terminals_listview_item);
        this.mContext = context;
        // when you have your data it will be able to use it here 
        this.mObjects  = objects;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View elementView;

        if(convertView==null){
            LayoutInflater inflater = mContext.getLayoutInflater();
            elementView = inflater.inflate(R.layout.terminals_listview_item, parent);
            ...
            // Some things with my view

        } else {
            elementView = convertView;
        }

        ...
        // Some things with my view
        return elementView;
    }


}