3

I have a custom ArrayAdapter for a listview. When I set the list adapter, the getView is not being called. I have returned the count from and the count is as it should be (not 0). I have also logged different item positions to ensure that the adapter has data to display however the getview is still not called. I set the list adapter in the postExecute() of an async task. It seems as if everything but the getView is being called. Here is the code

private class StableArrayAdapter extends ArrayAdapter<String> {

        private final Context context;
        private List<String> viewString;
        private ImageView image;
        private TextView addToCalendarButton;
        private TextView eventTitle;
        private ImageView eventImage;
        private TextView likesTV;
        private TextView planToAttendTV;

        public StableArrayAdapter(Context context, List<String> strings) {
            super(context, R.layout.post_layout, strings);
            this.context = context;
            this.viewString = strings;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View postLayout = inflater.inflate(R.layout.post_layout, parent, false);

            TextView unameTV = (TextView)postLayout.findViewById(R.id.postUnameTv);
            unameTV.setText(viewString.get(0));

            image = (ImageView)postLayout.findViewById(R.id.postProfPic);
            DisplayImageOptions options = initiateDisplayImageOptions();
            ImageLoader imageloader = ImageLoader.getInstance();
            initImageLoader(getActivity());
            imageloader.displayImage(viewString.get(1), image, options);


            addToCalendarButton = (TextView)postLayout.findViewById(R.id.addToCalendarButton);
            addToCalendarButton.setText(viewString.get(2));

            eventTitle = (TextView)postLayout.findViewById(R.id.postTitleTV);
            eventTitle.setText(viewString.get(3));

            eventImage = (ImageView)postLayout.findViewById(R.id.eventImage);
            imageloader.displayImage(viewString.get(4), eventImage, options);


            likesTV = (TextView)postLayout.findViewById(R.id.likesTV);
            likesTV.setText(""+viewContent.get(5));

            planToAttendTV = (TextView)postLayout.findViewById(R.id.planToAttendTV);
            planToAttendTV.setText(viewString.get(6));

            Log.d("Adapter", ""+viewString.get(6));



            return postLayout;
        }


        @Override
        public int getCount()
        {
            return viewString.size();
        }

        @Override
        public String getItem(int position) {
            return viewString.get(position);
        }

    }

}`

I am unsure if this may be a reason but here is how i set the list adapter in the postExecute

            getActivity().runOnUiThread(new Runnable() {
            public void run() {


                /**
                 * Updating parsed JSON data into ListView
                 * */

                StableArrayAdapter adapter = new StableArrayAdapter(getActivity(), viewContent);
                // updating listview

                lv.setAdapter(adapter);
                adapter.notifyDataSetChanged();


            }
        });

EDIT Here is the async task Im using to get the data

class LoadAllProducts extends AsyncTask<String, String, String> {

    /**
     * Before starting background thread Show Progress Dialog
     * */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();

    }

    /**
     * getting All products from url
     * */
    protected String doInBackground(String... args) {
        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        // getting JSON string from URL
        JSONObject json = jParser.makeHttpRequest(url_get_events, "GET", params);

        // Check your log cat for JSON reponse
        Log.d("Loading Events: ", "Loading Events...");

        try {
            // Checking for SUCCESS TAG
            int success = json.getInt(TAG_SUCCESS);

            if (success == 1) {

                // products found
                // Getting Array of Products
                products = json.getJSONArray(TAG_PRODUCTS);


                // looping through All Products
                for (int i = 0; i < products.length(); i++) {

                    JSONObject c = products.getJSONObject(i);

                    // Storing each json item in variable
                    int id = c.getInt("id");
                    String name = c.getString("name");
                    String radius = c.getString("radius");

                    String centerlat = c.getString("centerlat");
                    String centerlng = c.getString("centerlng");

                    String topleftcornerlat = c.getString("topleftcornerlat");
                    String topleftcornerlng = c.getString("topleftcornerlng");

                    String bottomleftcornerlat = c.getString("bottomleftcornerlat");
                    String bottomleftcornerlng = c.getString("bottomleftcornerlng");

                    String bottomrightcornerlat = c.getString("bottomrightcornerlat");
                    String bottomrightcornerlng = c.getString("bottomrightcornerlng");




                    String startmonth = c.getString("startmonth");
                    String endmonth = c.getString("endmonth");

                    String startday= c.getString("startday");
                    String endday = c.getString("endday");

                    String startyear = c.getString("startyear");
                    String endyear = c.getString("endyear");

                    String starthour = c.getString("starthour");
                    String endhour= c.getString("endhour");

                    String startmins = c.getString("startmins");
                    String endmins= c.getString("endmins");




                    String attending_future = c.getString("attending_future");
                    String attending_now = c.getString("attending_now");

                    String likes = c.getString("likes");
                    String image = c.getString("image");

                    String profile = c.getString("profile");

                    String userprofilepic = c.getString("userprofpic");
                    String username = c.getString("username");


                    viewContent.add(username);


                    viewContent.add(userprofilepic);


                    String date = getMonth(Integer.parseInt(startmonth)) + " " + startday + ", " + startyear;

                    viewContent.add(date);


                    viewContent.add(name);


                    viewContent.add(image);
                    viewContent.add(""+likes);


                    viewContent.add(attending_future + " people plan to attend.");



                }
            } else {
                // no products found
                // Launch Add New product Activity
                /*
                Intent i = new Intent(getApplicationContext(),
                        NewProductActivity.class);
                // Closing all previous activities
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(i);
                */
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * After completing background task Dismiss the progress dialog
     * **/
    protected void onPostExecute(String file_url) {
        Log.d("Loading Events: ", "Events Loaded");
        // dismiss the dialog after getting all products
        // updating UI from Background Thread


        getActivity().runOnUiThread(new Runnable() {
            public void run() {


                /**
                 * Updating parsed JSON data into ListView
                 * */

                StableArrayAdapter adapter = new StableArrayAdapter(getActivity(), viewContent);
                // updating listview

                lv.setAdapter(adapter);
                adapter.notifyDataSetChanged();


            }
        });

    }

EDIT

Here is the entire code

public class MainFeed extends Fragment {

// Progress Dialog
private ProgressDialog pDialog;

// Creating JSON Parser object
JSONParser jParser = new JSONParser();
static List<String> viewContent = new ArrayList<>();

static Bundle bundle;
ArrayList<HashMap<String, String>> productsList;

// url to get all products list
private static String url_get_events = "http://127.0.0.1/get_events.php";

// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_PRODUCTS = "products";
private static final String TAG_PID = "pid";
private static final String TAG_NAME = "name";

// products JSONArray
JSONArray products = null;
private ListView lv;

/* (non-Javadoc)
 * @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
 */
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    bundle = savedInstanceState;

    inflater = getLayoutInflater(savedInstanceState);
    View view=inflater.inflate(R.layout.main_feed_layout, null);

    // Loading products in Background Thread
    new LoadAllProducts().execute();

    // Get listview
    lv = (ListView) view.findViewById(R.id.listView);


    // on seleting single product
    // launching Edit Product Screen
    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

            /*
            String pid = ((TextView) view.findViewById(R.id.pid)).getText()
                    .toString();

            // Starting new intent
            Intent in = new Intent(getApplicationContext(),
                    EditProductActivity.class);
            // sending pid to next activity
            in.putExtra(TAG_PID, pid);

            // starting new activity and expecting some response back
            startActivityForResult(in, 100);
            */
        }
    });

    ImageLoadingListener progressListener = new ImageLoadingListener() {
        @Override
        public void onLoadingStarted(String s, View view) {
            Log.i("Start", "Start");
        }

        @Override
        public void onLoadingFailed(String s, View view, FailReason failReason) {
            Log.i("Start", "Failed");

        }

        @Override
        public void onLoadingComplete(String s, View view, Bitmap bitmap) {
        }

        @Override
        public void onLoadingCancelled(String s, View view) {
            Log.i("Start", "Cancelled");

        }
    };




    if (container == null) {

        return null;
    }
    return (RelativeLayout) inflater.inflate(R.layout.main_feed_layout, container, false);

}

// Response from Edit Product Activity
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    // if result code 100
    if (resultCode == 100) {
        // if result code 100 is received
        // means user edited/deleted product
        // reload this screen again
        Intent intent = data;
        //finish();
        startActivity(intent);
    }

}

class LoadAllProducts extends AsyncTask<String, String, String> {

    /**
     * Before starting background thread Show Progress Dialog
     * */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();

    }

    /**
     * getting All products from url
     * */
    protected String doInBackground(String... args) {
        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        // getting JSON string from URL
        JSONObject json = jParser.makeHttpRequest(url_get_events, "GET", params);

        // Check your log cat for JSON reponse
        Log.d("Loading Events: ", "Loading Events...");

        try {
            // Checking for SUCCESS TAG
            int success = json.getInt(TAG_SUCCESS);

            if (success == 1) {

                // products found
                // Getting Array of Products
                products = json.getJSONArray(TAG_PRODUCTS);


                // looping through All Products
                for (int i = 0; i < products.length(); i++) {

                    JSONObject c = products.getJSONObject(i);

                    // Storing each json item in variable
                    int id = c.getInt("id");
                    String name = c.getString("name");
                    String radius = c.getString("radius");

                    String centerlat = c.getString("centerlat");
                    String centerlng = c.getString("centerlng");

                    String topleftcornerlat = c.getString("topleftcornerlat");
                    String topleftcornerlng = c.getString("topleftcornerlng");

                    String bottomleftcornerlat = c.getString("bottomleftcornerlat");
                    String bottomleftcornerlng = c.getString("bottomleftcornerlng");

                    String bottomrightcornerlat = c.getString("bottomrightcornerlat");
                    String bottomrightcornerlng = c.getString("bottomrightcornerlng");




                    String startmonth = c.getString("startmonth");
                    String endmonth = c.getString("endmonth");

                    String startday= c.getString("startday");
                    String endday = c.getString("endday");

                    String startyear = c.getString("startyear");
                    String endyear = c.getString("endyear");

                    String starthour = c.getString("starthour");
                    String endhour= c.getString("endhour");

                    String startmins = c.getString("startmins");
                    String endmins= c.getString("endmins");




                    String attending_future = c.getString("attending_future");
                    String attending_now = c.getString("attending_now");

                    String likes = c.getString("likes");
                    String image = c.getString("image");

                    String profile = c.getString("profile");

                    String userprofilepic = c.getString("userprofpic");
                    String username = c.getString("username");


                    viewContent.add(username);


                    viewContent.add(userprofilepic);


                    String date = getMonth(Integer.parseInt(startmonth)) + " " + startday + ", " + startyear;

                    viewContent.add(date);


                    viewContent.add(name);


                    viewContent.add(image);
                    viewContent.add(""+likes);


                    viewContent.add(attending_future + " people plan to attend.");



                }
            } else {
                // no products found
                // Launch Add New product Activity
                /*
                Intent i = new Intent(getApplicationContext(),
                        NewProductActivity.class);
                // Closing all previous activities
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(i);
                */
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * After completing background task Dismiss the progress dialog
     * **/
    protected void onPostExecute(String file_url) {
        Log.d("Loading Events: ", "Events Loaded");
        // dismiss the dialog after getting all products
        // updating UI from Background Thread



         /**
          * Updating parsed JSON data into ListView
          * */
         StableArrayAdapter adapter = new StableArrayAdapter(getActivity(), viewContent);
         // updating listview
         lv.setAdapter(adapter);
         adapter.notifyDataSetChanged();




    }








    private class StableArrayAdapter extends ArrayAdapter<String> {

        private final Context context;
        private List<String> viewString;
        private ImageView image;
        private TextView addToCalendarButton;
        private TextView eventTitle;
        private ImageView eventImage;
        private TextView likesTV;
        private TextView planToAttendTV;

        public StableArrayAdapter(Context context, List<String> strings) {
            super(context, R.layout.post_layout, strings);
            this.context = context;
            this.viewString = strings;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View postLayout = inflater.inflate(R.layout.post_layout, parent, false);

            TextView unameTV = (TextView)postLayout.findViewById(R.id.postUnameTv);
            unameTV.setText(viewString.get(0));

            image = (ImageView)postLayout.findViewById(R.id.postProfPic);
            DisplayImageOptions options = initiateDisplayImageOptions();
            ImageLoader imageloader = ImageLoader.getInstance();
            initImageLoader(getActivity());
            imageloader.displayImage(viewString.get(1), image, options);


            addToCalendarButton = (TextView)postLayout.findViewById(R.id.addToCalendarButton);
            addToCalendarButton.setText(viewString.get(2));

            eventTitle = (TextView)postLayout.findViewById(R.id.postTitleTV);
            eventTitle.setText(viewString.get(3));

            eventImage = (ImageView)postLayout.findViewById(R.id.eventImage);
            imageloader.displayImage(viewString.get(4), eventImage, options);


            likesTV = (TextView)postLayout.findViewById(R.id.likesTV);
            likesTV.setText(""+viewContent.get(5));

            planToAttendTV = (TextView)postLayout.findViewById(R.id.planToAttendTV);
            planToAttendTV.setText(viewString.get(6));

            Log.d("Adapter", ""+viewString.get(6));



            return postLayout;
        }


        @Override
        public int getCount()
        {
            Log.d("Adapter", ""+viewString.size());
            return viewString.size();
        }

        @Override
        public String getItem(int position) {
            return viewString.get(position);
        }

    }

}











public DisplayImageOptions initiateDisplayImageOptions()
{
    DisplayImageOptions options = new DisplayImageOptions.Builder()
            .cacheInMemory(true)
            .cacheOnDisc(true)
            .bitmapConfig(Bitmap.Config.RGB_565)
            .build();

    return options;
}


protected void initImageLoader(Context context) {
    // This configuration tuning is custom. You can tune every option, you may tune some of them,
    // or you can create default configuration by
    //  ImageLoaderConfiguration.createDefault(this);
    // method.
    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
            .threadPriority(Thread.NORM_PRIORITY - 2)
            .denyCacheImageMultipleSizesInMemory()
            .diskCacheFileNameGenerator(new Md5FileNameGenerator())
            .tasksProcessingOrder(QueueProcessingType.LIFO)
            .writeDebugLogs() // Remove for release app
            .build();

    // Initialize ImageLoader with configuration.
    ImageLoader.getInstance().init(config);
}

public String getMonth(int mon)
{
    String month;

    if(mon == 1)
    {
        month = "January";
    }
    else if (mon == 2)
    {
        month = "February";
    }
    else if (mon == 3)
    {
        month = "March";
    }
    else if (mon == 4)
    {
        month = "April";
    }
    else if (mon == 5)
    {
        month = "May";
    }
    else if (mon == 6)
    {
        month = "June";
    }
    else if (mon == 7)
    {
        month = "July";
    }
    else if (mon == 8)
    {
        month = "August";
    }
    else if (mon == 9)
    {
        month = "September";
    }
    else if (mon == 10)
    {
        month = "October";
    }
    else if (mon == 11)
    {
        month = "November";
    }
    else
    {
        month = "December";
    }


    return month;
}

}

superuserdo
  • 1,637
  • 3
  • 21
  • 33

4 Answers4

2

Try to change this line

// Get listview
lv = (ListView) view.findViewById(R.id.listView);

to

lv = (ListView) getActivity().findViewById(R.id.listView);

See ListFragment Not Rendering and getView() in Adapter Not Being Called

Community
  • 1
  • 1
Davide
  • 622
  • 4
  • 10
2

To all those who may face a similar problem. The reason getView() was never called was because in my onCreateView() of my fragment, I was inflating a new layout at the end when i returned the view. My problem was that I was modifying the views in the inflated layout then I was returning a new view therefore getView did not have time to be called, and even if it did, it would not have displayed any results since I was inflating a brand new layout. To solve I removed return (RelativeLayout)inflater.inflate(R.layout.main_feed_layout, container, false); and instead put return view;. This solved my problem immediately.

superuserdo
  • 1,637
  • 3
  • 21
  • 33
1

I am not sure you need to have

 getActivity().runOnUiThread(new Runnable() {
            public void run() {

}

inside onPostExecute(). It automatically does everything on UI thread. Please remove it and see.

hrishitiwari
  • 634
  • 7
  • 15
0

Your doInBackground() is populating a variable called 'viewContent' which is static. As doInBackground() happens in a background thread and as you use it on onPostExecute() that runs in a different thread, it will fail because of Thread visibility issue, in other words, a variable is changed by one thread is not visible by the other thread, UNLESS if you do it in a synchronized region. Doing it in a synchronized region would make your code work, but it's not the Android way of using a AsyncTask.

What you should do is: remove make your doInBackground() return a copy of this list, and on your onPostExecute() you will receive this list as parameter then you can bypass it to the adapter. Forget about this static List viewContent = new ArrayList<>(); unless if you wanna cache the result, BUT use it with caution.

Solution example is below:

class LoadAllProducts extends AsyncTask<String, String, List<String>> {

  protected List<String> doInBackground(String... args) {
    List<String> allData = ....
    return allData;
  }


  protected void onPostExecute(List<String> allData) {
    Log.d("Loading Events: ", "Events Loaded");

     StableArrayAdapter adapter = new StableArrayAdapter(getActivity(), allData);
     // updating listview
     lv.setAdapter(adapter);
     adapter.notifyDataSetChanged();
   }

}

other adjacent problem on the Adapter:

Your adapter has a list of strings..OK. BUT the Adapter was design to call getView() for each item of the list. In your get view you call all the positions in your list, that defeats the purpose.

In your getView() you should call:

 String currentItem = getItem(position);
 // note that 'position' is one of the given parameters for the getView().

Please read the getView() api for deeper understanding of each parameter.

Alécio Carvalho
  • 13,481
  • 5
  • 68
  • 74
  • 1
    Correct. I don't know what `.get(0-6)` in `getView()` is all about. Also check whether you really load any items during adapter initialization. Number of list item views displayed depends on `getCount()`. – Michal Aug 15 '14 at 21:18
  • What the idea behind this is supposed to be is that it is supposed to get multiple arrays from a jsonobject. Once it gets the array, its supposed to populate the views of the postLayout with the appropriate string. The reason I call .get(0-6) is because the list im using has these strings in that specific spot. – superuserdo Aug 15 '14 at 21:34
  • Even when I use this way, getView is not called. Even when I delete all code in getView. – superuserdo Aug 15 '14 at 21:43