ListView cannot show a List retrieved from URL

peppe :

I'm new to Android Studio. I'm trying to custom a Fragment automatically created by the IDE using the option create -> new Fragment (List). I'm not able to show the List retrieved from an http page, but if I manually add items to my list, the emulator let me see it. How can I solve this problem?

municipioFragment.java

package com.example.is2_app.ui.municipio;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.is2_app.R;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class municipioFragment extends Fragment {

    // TODO: Customize parameters
    private int mColumnCount = 1;
    private List<News> lstNews;

    private OnListFragmentInteractionListener mListener;

    public municipioFragment() {
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        lstNews = new ArrayList<>();   
        getURL();


    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_municipio_list, container, false);

        // Set the adapter
        if (view instanceof RecyclerView) {
            Context context = view.getContext();
            RecyclerView recyclerView = (RecyclerView) view;
            if (mColumnCount <= 1) {
                recyclerView.setLayoutManager(new LinearLayoutManager(context));
            } else {
                recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
            }
            recyclerView.setAdapter(new MymunicipioRecyclerViewAdapter(lstNews, mListener));
        }
        return view;
    }


    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnListFragmentInteractionListener) {
            mListener = (OnListFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnListFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p/>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */

    public interface OnListFragmentInteractionListener {
        // TODO: Update argument type and name
        void onListFragmentInteraction(News item);
    }

    public void getURL() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                final StringBuilder builder = new StringBuilder();
                try {
                    Document doc = Jsoup.connect("http://www.comune.candida.av.it").get();
                    Element content = doc.getElementById("b370");
                    Elements subcontent = content.getElementsByTag("p");
                    String Text = null;
                    String Href = null;
                    int i = 0;
                    for (Element link : subcontent) {
                        Href = link.attr("href");
                        Text = link.text();
                        builder.append("\n").append(Text);
                        i = i + 1;
                        lstNews.add(new News(Integer.toString(i), Text));
                    }


                } catch (IOException e) {
                    builder.append("Error: ").append(e.getMessage()).append("\n");
                }
            }
        }).start();
    }
}

MunicipioRecyclerViewAdapter.java

package com.example.is2_app.ui.municipio;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

import com.example.is2_app.R;
import com.example.is2_app.ui.municipio.municipioFragment.OnListFragmentInteractionListener;

import java.util.List;


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


    private final OnListFragmentInteractionListener mListener;
    List<News> mData;

    public MymunicipioRecyclerViewAdapter(List<News> mData, OnListFragmentInteractionListener listener) {
        this.mData = mData;
        this.mListener = listener;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.fragment_municipio, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        //holder.mIdView.setText(mValues.get(position).id);
        holder.mContentView.setText(mData.get(position).getId());
        holder.mContentView.setText(mData.get(position).getContent());


    }

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

    public class ViewHolder extends RecyclerView.ViewHolder {
        public final View mView;
        public final TextView mIdView;
        public final TextView mContentView;

        public ViewHolder(View view) {
            super(view);
            mView = view;
            mIdView = (TextView) view.findViewById(R.id.item_number);
            mContentView = (TextView) view.findViewById(R.id.content);
        }

        @Override
        public String toString() {
            return super.toString() + " '" + mContentView.getText() + "'";
        }
    }
}

fragment_municipio.xml

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

    <TextView
        android:id="@+id/item_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/text_margin"
        android:textAppearance="?attr/textAppearanceListItem" />

    <TextView
        android:id="@+id/content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/text_margin"
        android:textAppearance="?attr/textAppearanceListItem" /> </LinearLayout>

fragment_municipio_list.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/list"
    android:name="com.example.is2_app.ui.municipioFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    app:layoutManager="LinearLayoutManager"
    tools:context=".ui.municipio.municipioFragment"
    tools:listitem="@layout/fragment_municipio" />
Nizar :

So getUrl() is running in a Thread. In addition, getting the Document with JSoup is gonna need some time. This means that onCreateView will probably run before your lstNews is filled with the data you are scraping from the Document.

So you want to update your dataset; then, you want to notify your Adapter that your dataset changed.

Add this method to your Adapter

public void updateData(List<News> mData) {
    this.mData = mData;
    this.notifyDataSetChanged();
}

And after the for loop in getUrl(), you want to do the following:

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        recyclerViewAdapter.updateData(lstNews);
    }
});

Where, recyclerViewAdapter is defined alongside recyclerView and initialized in the onCreateView. So the following line:

recyclerView.setAdapter(new MymunicipioRecyclerViewAdapter(lstNews, mListener));

Will become:

recyclerViewAdapter = new MymunicipioRecyclerViewAdapter(lstNews, mListener);
recyclerView.setAdapter(recyclerViewAdapter);

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=357220&siteId=1