0

I would like to populate my Listview using a loop, I have recently attempted to populate it in a very inefficient way by making multiple calls for the data from SQL. When I realized just how inefficient it was I began to pull the data from the server in one go by making use of arrays. I am having trouble changing my code for this to work.

What I need to do is find a way of looping through the below array of JSONArrays (Which is not the hard part for me), but to do so I need to have my GetSocietyDataASyncTask return the above array and find a way of passing it to the OnCreate/done method in SocietySearch.java (Alot of the Society objects in my code can be ignored and somehow replaced with List societies)

Now I believe that I have included all of the relevant code but if you need to see anything else please do not hesitate to ask me.

The data that is received by Java from my database looks like this:

[{"society_id":1,"name":"TestName1","email":"Test@email1","description":"TestDes1"},
{"society_id":2,"name":"TestName2","email":"Test@email2","description":"TestDes2"}]

SocietySearch Class:

public class SocietySearch extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_society_search);


    Society society = new Society(-1, null, null, null);
    ServerRequests serverRequest1 = new ServerRequests(SocietySearch.this);
    serverRequest1.GetSocietyDataAsyncTask(society, new GetSocietyCallback() {
        @Override
        public void done(final Society returnedSociety) {
            ListView lv = (ListView) findViewById(R.id.ListView);
            List<ListViewItem> items = new ArrayList<>();
            items.add(new ListViewItem() {{
                ThumbnailResource = R.drawable.test;
                Title = returnedSociety.socName;
                Subtitle = returnedSociety.socDes;
            }});
            CustomListViewAdapter adapter = new CustomListViewAdapter(SocietySearch.this, items);
            lv.setAdapter(adapter);
        }
    });
}


class ListViewItem {
    public int ThumbnailResource;
    public String Title;
    public String Subtitle;
}

Relevant Part Of ServerRequests Class:

public class getSocietyDataAsyncTask extends AsyncTask<Void, Void, Society> {
        Society society;
        GetSocietyCallback societyCallback;

        public getSocietyDataAsyncTask(Society society, GetSocietyCallback societyCallback) {
            this.society = society;
            this.societyCallback = societyCallback;
        }

        @Override
        protected Society doInBackground(Void... params) {
            BufferedReader reader = null;
            Society returnedSociety = null;
            List<Society> societies = new ArrayList<>();
            try {
                URL url = new URL(SERVER_ADDRESS + "/getsocietydata.php");

                HttpURLConnection con = (HttpURLConnection) url.openConnection();

                con.setConnectTimeout(CONNECTION_TIMEOUT);
                con.setReadTimeout(CONNECTION_TIMEOUT);

                con.setRequestMethod("POST");

                con.setDoOutput(true);

                StringBuilder sb = new StringBuilder();
                reader = new BufferedReader(new InputStreamReader(con.getInputStream()));

                String line;
                while ((line = reader.readLine()) != null) { //Read until there is something available
                    sb.append(line + "\n");     //Read and save line by line
                }
                line = sb.toString();           //Saving complete data received in string

                //Check values received in Logcat
                Log.i("custom_check", "The values received in the store part are as follows:");
                Log.i("custom_check", line);


                JSONArray ja = new JSONArray(line);
                if (ja != null && ja.length() == 0) {
                    returnedSociety = null;
                } else {
                    for (int i = 0; i <ja.length(); i++) {
                        JSONObject json = ja.optJSONObject(i);
                        //Storing each Json in a variable
                        int society_id = json.getInt("society_id");
                        String socName = json.getString("name");
                        String socEmail = json.getString("email");
                        String socDes = json.getString("description");
                        returnedSociety = new Society(society_id, socName, socEmail, socDes);
                        societies.add(returnedSociety);
                    }
                    return returnedSociety;
                }


            } catch (Exception e) {
                e.printStackTrace();
                Log.d("Sample", "Error has occurred!\n" + e.toString());

            }


            finally {

                if (reader != null) {
                    try {
                        reader.close();     //Closing the
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

            }
            return returnedSociety;
        }

        @Override
        protected void onPostExecute(Society returnedSociety) {
            super.onPostExecute(returnedSociety);
            progressDialog.dismiss();
            societyCallback.done(returnedSociety);
        }
    }

CustomListViewAdapter.java:

public class CustomListViewAdapter extends BaseAdapter {

    LayoutInflater inflater;
    List<SocietySearch.ListViewItem> items;

    public CustomListViewAdapter(Activity context, List<SocietySearch.ListViewItem> items) {
        super();

        this.items = items;
        this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        //Auto-generated method stub
        return items.size(); // TODO Maybe this can be my sql count?
    }

    @Override
    public Object getItem(int position) {
        //Auto-generated method stub
        return null;
    }

    @Override
    public long getItemId(int position) {
        //Auto-generated method stub
        return 0;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        //Auto-generated method stub

        ListViewItem item = items.get(position);

        View vi = convertView;

        if (convertView == null)
            vi = inflater.inflate(R.layout.item_row, null);

        ImageView test = (ImageView) vi.findViewById(R.id.imgThumbnail);
        TextView txtTitle = (TextView) vi.findViewById(R.id.txtTitle);
        TextView txtSubTitle = (TextView) vi.findViewById(R.id.txtSubTitle);

        test.setImageResource(item.ThumbnailResource);
        txtTitle.setText(item.Title);
        txtSubTitle.setText(item.Subtitle);


        return vi;
    }
}

ListView Layour file (item_row.xml):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/relativeLayout1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="5dip">

    <ImageView
        android:id="@+id/imgThumbnail"
        android:layout_width="78dip"
        android:layout_height="78dip"
        android:layout_alignParentLeft="true"
        android:layout_centerInParent="true"
        android:layout_marginLeft="-3dip"
        android:scaleType="centerInside"></ImageView>

    <TextView
        android:id="@+id/txtTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="6dip"
        android:layout_marginTop="6dip"
        android:layout_toRightOf="@+id/imgThumbnail"
        android:text="TextView"
        android:textAppearance="?android:attr/textAppearanceLarge"></TextView>

    <TextView
        android:id="@+id/txtSubTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/txtTitle"
        android:layout_marginLeft="6dip"
        android:layout_marginTop="3dip"
        android:layout_toRightOf="@+id/imgThumbnail"
        android:text="TextView"></TextView>

</RelativeLayout>
kmil
  • 243
  • 3
  • 13

1 Answers1

1

Take a look at ArrayAdapter and specifically #notifyDataSetChanged. (notifyDataSetChanged example). You can setup the ListView in #onCreate like you have and store off a reference to the underlying Adapter. Initially the Adapter will be empty, but when data comes in simply add it to the Adapter and call #notifyDataSetChanged as guided in the example.

Community
  • 1
  • 1
Scott Tomaszewski
  • 1,009
  • 8
  • 27
  • I've just came across the ArrayAdapter and am trying my hand at it right now, not super successful with my skills at this point but hopefully I will get there. Do you think that you would be able to post a bit of code to point me in the right direction? – kmil Mar 08 '16 at 19:39
  • https://github.com/codepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListView for general usage and http://stackoverflow.com/a/33890027/608347 for updating the adapter with new data – Scott Tomaszewski Mar 08 '16 at 19:42
  • Still not having much luck, should I be getting my getSocietyDataAsyncTask to return a Society or a List? – kmil Mar 08 '16 at 20:20
  • If your `InputStream` contains multiple Societies then your `doInBackground` should return all of them (so, a `List`). Then your `#onPostExecute` should call `arrayAdapter#addAll(listOfSocieties)` – Scott Tomaszewski Mar 08 '16 at 20:30
  • I would also recommend looking into Guava's `CharStreams#readLines` (http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/io/CharStreams.html#readLines(java.lang.Readable)) to ease all that IO handling: `List lines = CharStreams.readLines(new InputStreamReader(inputStream));`. You can even go a step further and check out using a `LineProcessor` (http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/io/CharStreams.html#readLines(java.lang.Readable,%20com.google.common.io.LineProcessor)) – Scott Tomaszewski Mar 08 '16 at 20:31
  • ok so my onPostExecute should be: `protected void onPostExecute(ArrayAdapter societies) { super.onPostExecute(societies); progressDialog.dismiss(); societyCallback.done(societies); }` Is that correct? – kmil Mar 08 '16 at 20:35
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/105736/discussion-between-kmil-and-scotty). – kmil Mar 08 '16 at 20:37
  • Hey, did this work out? Accept if so, otherwise whats up? – Scott Tomaszewski Mar 09 '16 at 20:59
  • Sorted it about 2 hours ago. I haven't implemented #notifyDataSetChanged now that I come to think of it, though I just made a note on it. Cheers for your help with this though, really appreciate it. – kmil Mar 09 '16 at 22:05