-1

Please help me. My Home Fragment is blank. I cant print JSON array to my Home Fragment. i want the ListView show data from Json array from API, how i can place the array data from Json using fragment. Sory for my english.

I'm using Fragment:

public class HomeFragment extends Fragment implements OnFeedListener{
ListView listView;
FeedAdapter adapter;
ArrayList<Post> posts;


 View myView;



 @Override

   public View onCreateView(LayoutInflater inflater,  ViewGroup container,  Bundle savedInstanceState) {
        myView = inflater.inflate(R.layout.home, container, false);
       return myView;
    }
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

@Override
public void onFeed(JSONArray array) {
    posts = new ArrayList<>();
    int lenght = array.length();
    for(int i = 0; i < lenght; i++)
    {
        JSONObject object = array.optJSONObject(i);
        Post post = new Post(object.optString("title"), object.optString("excerpt"), object.optString("thumbnail"));

        posts.addAll(posts);
    }
    adapter.addAll(posts);
    adapter.notifyDataSetChanged();
    listView.setAdapter(adapter);
    FeedTask task = new FeedTask(this);
    task.execute("http://indo-coc.com/api/get_recent_posts/");

}

public class FeedTask extends AsyncTask<String, Void, JSONArray>
{
    private OnFeedListener listener;
    public FeedTask(OnFeedListener listener)
    {
        this.listener = listener;
    }
    @Override
    protected JSONArray doInBackground(String... params)
    {
        String url = params[0];
        OkHttpClient client = new OkHttpClient();
        Request.Builder builder = new Request.Builder();
        Request request = builder.url(url).build();
        try {
            Response response = client.newCall(request).execute();
            String json = response.body().string();

            try
            {
                JSONObject object = new JSONObject(json);
                JSONArray array = object.optJSONArray("posts");
                return array;
            }
            catch (JSONException e)
            {
                e.printStackTrace();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(JSONArray array) {
        super.onPostExecute(array);
        if(null == array)
            return;
        if(null != listener )
            listener.onFeed(array);
    }
}

public class FeedAdapter extends ArrayAdapter<Post>
{
    private int resource;

    public FeedAdapter(Context context, int resource) {
        super(context, resource);
       this.resource = resource;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // Convert View -> Reuse
        if (null==convertView)
        {

            LayoutInflater inflater = LayoutInflater.from(getContext());
            convertView = inflater.inflate(resource, null);
        }
        // Binding Data
        Post post = getItem(position);
        TextView title = (TextView) convertView.findViewById(R.id.title);
        TextView desc = (TextView) convertView.findViewById(R.id.description);

        title.setText(post.title);
        desc.setText(post.description);



        return convertView;
    }
}
public class Post
{
    public String title;
    public String description;
    public String thumbnail; //URL

    public Post(String title, String desc, String thumbnail)
    {
        this.title = title;
        this.description = desc;
        this.thumbnail = thumbnail;
    }
}

}

3 Answers3

0

Declare FeedAdapter adapter and ArrayList<Post> posts as global variable in your public class. They must be declared outside public void onActivityCreated(Bundle savedInstanceState)

alevee
  • 25
  • 1
  • 4
0

what's going on here:

  • in onActivityCreated you declare local variables without assigning a value to them. Because they are local, they are gone as soon as the method terminates. Declare the variables above the method as a class variable to be able to access them later in onFeed
  • you do not assign a value to the variables listView and adapter. I assume somewhere else, common practice is doing this in onViewCreated, you set a main view for the fragment. If you don't know how to do this, see this question. Then you can load the listView using findViewById assuming the listView is in the layout you inflate in the fragment. Then you have to create a new FeedAdapter and assign it to the listView using listView.setAdapter(adapter)

Good luck!

Community
  • 1
  • 1
Phocacius
  • 1,127
  • 1
  • 13
  • 23
0

try this:

class MyFragment extends Fragment{
ListView listView;
FeedAdapter adapter;
ArrayList<Post> posts;


public void onCreate(Bundle b){
   super.onCreate(b);
   //My bad listview will only be assigned properly in onCreateView once the view is inflated
   posts = new ArrayList<>();
   adapter=new FeedAdapter(getActivity(),R.id.yourresouceid,posts); // which ever way your adapter is defined
   listView.setAdapter(adapter);
}


public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);


}
public void onFeed(JSONArray array) {

int lenght = array.length();
for (int i = 0; i < lenght; i++)
{
    JSONObject object = array.optJSONObject(i);
    posts.add(post);
}
//adapter.addAll(posts); //you don't need to do this, already done when creating your adapter
adapter.notifyDataSetChanged();

 }

}

Explanation: The scope of onActivityCreated is only till its closing bracket. Anything declared inside that will not be visible to any outer functions. See scope resolution in java for more details on how this works.

Also you have to initialize things before using them. just declaring it and trying to use it will give NullPointerExceptions

Kushan
  • 5,855
  • 3
  • 31
  • 45