0

I have a tablayout in ProfileActivity. And one of the tablayout will display recycleview of userlist that I retrieve from database using asynctask. I use getter method to return the userlist from asynctask class

My recycleview is in activity_user_view.xml and I set the adapter in the class that extends the fragments. I got no error however the tablayout doesn't appear in the view pager.

Here is my code

FragmentFriends.java (class that extends fragment)

public class FragmentFriends extends Fragment {
ArrayList<UserList> aList = new ArrayList<>();
RecyclerView recyclerView;
RecyclerView.Adapter adapter;
RecyclerView.LayoutManager layoutManager;
@Nullable
@Override

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View rootview = inflater.inflate(R.layout.activity_user_view,container,false);// The activity that contains recyclerview

    PHPUserList phpUserList = new PHPUserList(getActivity());
    phpUserList.execute();
    aList = phpUserList.getArrayList();
    recyclerView = (RecyclerView) rootview.findViewById(R.id.RVUserList);
    layoutManager = new LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setHasFixedSize(true);
    adapter = new RecyclerAdapter(aList);
    recyclerView.setAdapter(adapter);

    return rootview;
}

}

PHPUserList.java (asynctask class)

public class PHPUserList extends AsyncTask<Void,UserList,Void> {

private Context context;
ArrayList<UserList> arrayList = new ArrayList<>();

PHPUserList(Context ctx){

    this.context = ctx;
}
@Override
protected Void doInBackground(Void... params) {
    try {
        URL url = new URL("http://njtwicomp.pe.hu/listuser.php");
        HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
        InputStream inputStream = httpURLConnection.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuilder stringBuilder = new StringBuilder();
        String line;

        while ((line = bufferedReader.readLine())!=null)
        {
            stringBuilder.append(line+"\n");
        }

        httpURLConnection.disconnect();
        String json_string = stringBuilder.toString().trim();
        JSONObject jsonObject = new JSONObject(json_string);
        JSONArray jsonArray = jsonObject.getJSONArray("server_response");
        int count = 0;
        while(count<jsonArray.length()){
            JSONObject JO = jsonArray.getJSONObject(count);
            count++;
            UserList userList = new UserList(JO.getString("Name"),JO.getString("Username"));
            publishProgress(userList);
        }
        Log.d("JSON STRING", json_string);

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

@Override
protected void onPreExecute() {
    super.onPreExecute();
}

@Override
protected void onProgressUpdate(UserList... values) {
    arrayList.add(values[0]);
}

@Override
protected void onPostExecute(Void aVoid) {
    super.onPostExecute(aVoid);
}

public ArrayList<UserList> getArrayList() {
    return arrayList;
}
}

Please help me

NatJ
  • 47
  • 10

1 Answers1

1

When items are added to a recycler view or a list view you need to notify the adapter that these changes have occurred which you aren't doing.

In onProgressUpdate you'd want to call adapter.notifyItemInserted(position) to tell the RecyclerView to refresh. To do this you'd need a callback or a listener in your AsyncTask because it doesn't have a reference to your adapter, and it shouldn't.

See here for all the notify calls you have the ability to use: https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html

Dom
  • 8,222
  • 2
  • 15
  • 19
  • So instead of returning the arraylist I should return the adapter? – NatJ May 29 '16 at 00:53
  • No, the easiest way to do it would be to create an interface eg `ItemAddedListener` with a method `itemAdded(int position)` and have your fragment implement it. Then you pass the fragment to the async task as an `ItemAddedListener` object. In `onProgressUpdate` then call `itemAddedListener.itemAdded(position);`. In you're fragment this will call `adapter.notifyItemInserted(position);`. Note that in your AsyncTask you should store the listener as a WeakReference so you don't leak memory. – Dom May 29 '16 at 00:57
  • I am really blank about that. Could you give me link to learn about that? – NatJ May 29 '16 at 01:22
  • No worries, try checking out this answer regarding the listener: http://stackoverflow.com/questions/9963691/android-asynctask-sending-callbacks-to-ui – Dom May 29 '16 at 01:27