Asker Asker - 5 months ago 331
Android Question

Data from Asynctask won't carry over to onCreateView for RecyclerView

So my problem is that I can generate the data in the AsyncTask, but I can't get the data to transfer back to the onCreateView. This is my first dive into fragments. Sorry if my code's ugly, I'm just trying to get this to work, and also I'm quite new to Android programming, so sorry if I made a stupid mistake somewhere. I'm not sure if I need to post my global variables. And I know some of my variables are weirdly named.

onCreateView portion

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_news,
container, false);
pb = (ProgressBar) getActivity().findViewById(R.id.progressBar2);
gv = (RecyclerView) view.findViewById(R.id.expandableListView);
swp = (SwipeRefreshLayout) getActivity().findViewById(R.id.activity_main_swipe_refresh_layout);

gv.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
gv.setLayoutManager(layoutManager);

swp.setEnabled(false);

hadapter = new NewsExpandableAdapter(getActivity(), m_hparts);

System.out.println(m_hparts.size());
gv.setAdapter(hadapter);
return view;
}


RecyclerView adapter

public class NewsExpandableAdapter extends RecyclerView.Adapter<NewsExpandableAdapter.ViewHolder> {

private Context context;

public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView nameTextView;
public ImageView messageButton;

public ViewHolder(View itemView) {
super(itemView);

nameTextView = (TextView) itemView.findViewById(R.id.title);
messageButton = (ImageView) itemView.findViewById(R.id.image);
}
}

private ArrayList<Model> mContacts;

public NewsExpandableAdapter(Context c, ArrayList<Model> contacts) {

this.context = c;
mContacts = (ArrayList<Model>) contacts;
}

@Override
public NewsExpandableAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);

View contactView = inflater.inflate(R.layout.expandable_list_item, parent, false);

ViewHolder viewHolder = new ViewHolder(contactView);
return viewHolder;
}

@Override
public void onBindViewHolder(NewsExpandableAdapter.ViewHolder viewHolder, int position) {
Model contact = mContacts.get(position);

TextView textView = viewHolder.nameTextView;
textView.setText(contact.getTitle());

ImageView image= viewHolder.messageButton;

Picasso.with(viewHolder.itemView.getContext())
.load(contact.getLink())
.into(image);


}

@Override
public int getItemCount() {
return mContacts.size();
}
}


Fragment XML

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.sample">

<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="100dp"
android:id="@+id/expandableListView">
</android.support.v7.widget.RecyclerView>

</RelativeLayout>


RecyclerView XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="8dp">


<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/image"/>

<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/title"/>

</LinearLayout>


AsyncTask

public class Directory extends AsyncTask<Void, Void, String> {
String desc;

@Override
protected String doInBackground(Void... params) {

try {
Document document = Jsoup.connect(url + dateFormatYear.format(date)).get();

listing_latest = document.select(".title.page_title");

for (Element listing0 : listing_latest) {

Element hmonth = listing0.select("h3").first();
if(hmonth.text().equals(dateFormatMonth.format(date))){
month = hmonth.text();
hname = hmonth.parent().parent().parent().nextElementSibling();
releaseList = hname.select(".base_header.tc.m6");
for(Element block : releaseList){
name = block.select(".one_line.fs11 a").first();
image = block.select(".base_inner.h244.loading a img").first();
if(name != null){
hn = name.attr("title");
}
if(image != null){
hi = image.attr("abs:src");
}
m_hparts.add(new Model(hi));
}
}
}
} catch (IOException e1) {
e1.printStackTrace();
}
return null;
}

@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
hadapter.notifyDataSetChanged();
m_hparts.add(new Model(hi));
}
}


Edit: I put the
new Directory().execute();
in the
onCreate()
Still could not get data.

Answer

You need to add all of the new items to the data source, and then call notifyDataSetChanged() after the data source has been updated.

Make the return value of doInBackground() a list of your items, and return it to onPostExecute(). You will need to change the parameters of the AsyncTask generics and the parameter passed into onPostExecute() as well.

Assuming your data source looks like this:

List<Model> m_hparts = new ArrayList<>();

You could do something like this:

public class Directory extends AsyncTask<Void, Void, List<Model>> {
    String desc;

    @Override
    protected List<Model> doInBackground(Void... params) {
        //added:
        List<Model> parts = new ArrayList<>();

        try {
            Document document = Jsoup.connect(url + dateFormatYear.format(date)).get();

            listing_latest = document.select(".title.page_title");

            for (Element listing0 : listing_latest) {

                Element hmonth = listing0.select("h3").first();
                if(hmonth.text().equals(dateFormatMonth.format(date))){
                    month = hmonth.text();
                    hname = hmonth.parent().parent().parent().nextElementSibling();
                    releaseList = hname.select(".base_header.tc.m6");
                    for(Element block : releaseList){
                        name = block.select(".one_line.fs11 a").first();
                        image = block.select(".base_inner.h244.loading a img").first();
                        if(name != null){
                            hn = name.attr("title");
                        }
                        if(image != null){
                            hi = image.attr("abs:src");
                        }
                        //m_hparts.add(new Model(hi));
                        //do this instead:
                        parts.add(new Model(hi));
                    }
                }
            }
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        //return null;
        //do this instead:
        return parts;
    }

    @Override
    protected void onPostExecute(List<Model> parts) {
        super.onPostExecute(result);
        for (Model h: parts) {
            m_hparts.add(h);
        }

        hadapter.notifyDataSetChanged();
    }
}