Json数据无法加载到Fragment中?

时间:2018-10-02 07:38:03

标签: android json retrofit

尊敬的开发人员, 希望大家都做得很好,我正在开发Android News应用程序,在其中我将底部导航抽屉与片段结合使用。当我单击未显示的每个项目json时,我已使用Retrofit进行网络通话。

MainActivity.java文件下面

public class MainActivity extends BottomBarHolderActivity implements AllJazeeraFragment.OnFragmentInteractionListener, BBCFragment.OnFragmentInteractionListener, CNNFragment.OnFragmentInteractionListener, CBCNewsFragment.OnFragmentInteractionListener {

        // private ApiService apiService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       // getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

        NavigationPage page1 = new NavigationPage("AllJazeera", ContextCompat.getDrawable(this, R.drawable.alljazeera), AllJazeeraFragment.newInstance());
        NavigationPage page2 = new NavigationPage("Support", ContextCompat.getDrawable(this, R.drawable.bbc_icon), CNNFragment.newInstance());
        NavigationPage page3 = new NavigationPage("Billing", ContextCompat.getDrawable(this, R.drawable.cnn_icon), AllJazeeraFragment.newInstance());
        NavigationPage page4 = new NavigationPage("Profile", ContextCompat.getDrawable(this, R.drawable.cbc_icon), CBCNewsFragment.newInstance());

        List<NavigationPage> navigationPages = new ArrayList<>();
        navigationPages.add(page1);
        navigationPages.add(page2);
        navigationPages.add(page3);
        navigationPages.add(page4);

        super.setupBottomBarHolderActivity(navigationPages);
    }


    public void onClicked() {
        Toast.makeText(this, "Clicked!", Toast.LENGTH_SHORT).show();
    }

}

在我的AllJazeeraFragment类之下 我通过改型实现了网络通话的地方

public class AllJazeeraFragment extends Fragment {


    public NewsAdapter adapter;
    public Article articleList;
    RecyclerView recyclerView;

    private AllJazeeraFragment.OnFragmentInteractionListener listener;

    public static AllJazeeraFragment newInstance() {
        return new AllJazeeraFragment();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


    }

    @Override
    public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
        final View rootView = inflater.inflate(R.layout.alljazeera_fragment, container, false);

        NewsInterface apiService = NewsClient.getApiService();
        Call <Article> call = apiService.getAllJazeera();

        call.enqueue(new Callback <Article>() {
            @Override
            public void onResponse(Call <Article> call, Response <Article> response) {

                articleList = response.body();
                recyclerView =  rootView.findViewById(R.id.recycler_view);
                adapter = new NewsAdapter((List<Article>) articleList);
                RecyclerView.LayoutManager eLayoutManager = new LinearLayoutManager(getActivity());
                recyclerView.setLayoutManager(eLayoutManager);
                recyclerView.setAdapter(adapter);

            }

            @Override
            public void onFailure(Call <Article> call, Throwable t) {

            }
        });

        return rootView;
    }

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

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

    public interface OnFragmentInteractionListener {
    }


}

在我的alljazeera_fragment.xml下面

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


    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:id="@+id/recycler_view"
        android:scrollbars="vertical"
        android:layout_height="wrap_content"/>

</LinearLayout>

在我的BBCFragment.java文件下面

public class BBCFragment extends Fragment {

    private OnFragmentInteractionListener listener;
    Article articleList;
    RecyclerView recyclerView;
    NewsAdapter adapter;
    public static BBCFragment newInstance() {
        return new BBCFragment();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       final  View rootView = inflater.inflate(R.layout.bbc_fragment, container, false);

        NewsInterface apiService = NewsClient.getApiService();
        Call <Article> call = apiService.getBBC();

        call.enqueue(new Callback <Article>() {
            @Override
            public void onResponse(Call<Article> call, Response <Article> response) {

                articleList = response.body();
                recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
                adapter = new NewsAdapter((List<Article>) articleList);
                RecyclerView.LayoutManager eLayoutManager = new LinearLayoutManager(getActivity());
                recyclerView.setLayoutManager(eLayoutManager);
                recyclerView.setAdapter(adapter);

            }

            @Override
            public void onFailure(Call<Article> call, Throwable t) {

            }
        });

        return rootView;
    }

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

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

    public interface OnFragmentInteractionListener {
    }


}

在bbc_fragment.xml以下

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent">


    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:id="@+id/recycler_view"
        android:scrollbars="vertical"
        android:layout_height="wrap_content"/>

</LinearLayout>

在我调用终点的界面下方     公共接口NewsInterface {

    @GET("v2/top-headlines?sources=al-jazeera-english&apiKey=a5cc70bd52c9436785557878f4aa49e1")
    Call <Article> getAllJazeera();

    @GET("v2/top-headlines?sources=cbc-news&apiKey=a5cc70bd52c9436785557878f4aa49e1")
    Call <Article> getCbC();

    @GET("v2/top-headlines?sources=bbc-news&apiKey=a5cc70bd52c9436785557878f4aa49e1")
    Call <Article> getBBC();

    @GET("v2/top-headlines?sources=cnn&apiKey=a5cc70bd52c9436785557878f4aa49e1")
    Call <Article> getCNN();

}

低于新闻客户端类

 public class NewsClient  {

    public static final String BASE_URL = "https://newsapi.org/";

    /**
     * Get Retrofit Instance
     */
    private static Retrofit getRetrofitInstance() {
        return new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }

    /**
     * Get API Service
     *
     * @return API Service
     */
    public static NewsInterface getApiService() {
        return getRetrofitInstance().create(NewsInterface.class);
    }
    }

低于api的json响应

{
    "status": "ok",
    "totalResults": 9,
    "articles": [
        {
            "source": {
                "id": "al-jazeera-english",
                "name": "Al Jazeera English"
            },
            "author": "Al Jazeera",
            "title": "Former Maldives leader Gayoom freed on bail a week after election",
            "description": "Former president's release came a week after half-brother Abdulla Yameen lost the presidential election.",
            "url": "http://www.aljazeera.com/news/2018/09/maldives-leader-gayoom-freed-bail-week-election-180930150231895.html",
            "urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/30/367ab1ceb832482b9db0c4b22cadf2f5_18.jpg",
            "publishedAt": "2018-09-30T16:48:00Z",
            "content": "Former Maldives president Maumoon Abdul Gayoom has been released on bail a week after his estranged half-brother Abdulla Yameen was defeated in a presidential election. Gayoom, the Indian Ocean island nation's longest-serving leader, and his legislator son Fa… [+2862 chars]"
        },
        {
            "source": {
                "id": "al-jazeera-english",
                "name": "Al Jazeera English"
            },
            "author": "Faras Ghani",
            "title": "Why are humans killing 100 million sharks every year?",
            "description": "Increasing consumption of shark fin soup and illegal fishing may lead to extinction of certain species, experts warn.",
            "url": "http://www.aljazeera.com/news/2018/09/humans-killing-100-million-sharks-year-180923150037790.html",
            "urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/23/1ebd7c07e6dc49b095a58fe7c849a872_18.jpg",
            "publishedAt": "2018-09-30T14:02:00Z",
            "content": "Humans kill an estimated 100 million sharks annually and experts have warned that certain species face extinction if the trend continues. Consumption of shark fin soup, primarily in China and Vietnam, is the biggest reason behind the massive figure, contribut… [+6786 chars]"
        },
        {
            "source": {
                "id": "al-jazeera-english",
                "name": "Al Jazeera English"
            },
            "author": "Al Jazeera",
            "title": "Real Madrid football club honours Palestine activist Ahed Tamimi",
            "description": "Palestinian activist, who spent eight months in Israeli prison, is welcomed at Bernabeu stadium by the football club.",
            "url": "http://www.aljazeera.com/news/2018/09/real-madrid-football-club-honours-palestine-activist-ahed-tamimi-180930100616622.html",
            "urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/30/fa170d306f5d41a5bafbef373f20da1b_18.jpg",
            "publishedAt": "2018-09-30T12:09:00Z",
            "content": "Palestinian activist Ahed Tamimi, whose arrest last year drew international condemnation, has been honoured by Spanish football club Real Madrid after she was released from Israeli prison. The 17-year-old was arrested in December 2017 after a video of her sla… [+2066 chars]"
        },
        {
            "source": {
                "id": "al-jazeera-english",
                "name": "Al Jazeera English"
            },
            "author": "Sheetal Dhir",
            "title": "It's time to speak about the economic cost of sexual assault",
            "description": "The Kavanaugh scandal is an opportunity to finally talk about the economic toll sexual assault takes on our society.",
            "url": "http://www.aljazeera.com/indepth/opinion/time-speak-economic-cost-sexual-assault-180930071453246.html",
            "urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/30/1cf27079db8745d0b2995f820445b739_18.jpg",
            "publishedAt": "2018-09-30T11:45:00Z",
            "content": "I recently did a straw poll of the women in my life and realised that I know more survivors of sexual assault than I do mothers. The national statistics are staggering - according to the National Sexual Violence Resource Center, \"one in three women in the US … [+9518 chars]"
        },
        {
            "source": {
                "id": "al-jazeera-english",
                "name": "Al Jazeera English"
            },
            "author": "Anumeha Yadav",
            "title": "In Jharkhand, a tribal assertion met with fierce police crackdown",
            "description": "Authorities say they are legally acquiring land to be used for 'development' projects, but villagers tell another story.",
            "url": "http://www.aljazeera.com/indepth/features/jharkhand-tribal-assertion-met-fierce-police-crackdown-180929223820429.html",
            "urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/28/619b6054917b46e3ac4f6813f60fe3cd_18.jpg",
            "publishedAt": "2018-09-30T07:41:00Z",
            "content": "Jharkhand, India: It was dusk in Uduburu, the time that farmers usually return home after working in the paddy fields, but the hamlet in the eastern Indian state of Jharkhand was deserted. The village square was empty and the mud huts were locked. After darkn… [+13300 chars]"
        },
        {
            "source": {
                "id": "al-jazeera-english",
                "name": "Al Jazeera English"
            },
            "author": "Shereena Qazi",
            "title": "How Afghanistan fell in love with cricket",
            "description": "Cricket was imported by Afghan refugees from Pakistan, banned by the Taliban and finally embraced by government.",
            "url": "http://www.aljazeera.com/news/2018/09/afghanistan-fell-love-cricket-180928141048315.html",
            "urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/28/f7c2ddb6514642a7bb60e29ea3b6a37c_18.jpg",
            "publishedAt": "2018-09-30T06:47:00Z",
            "content": "Afghanistan recently ended its 2018 Asia Cup journey in Dubai with a series of impressive performances, filling Afghans at home with joy. With victories against Sri Lanka and Bangladesh, a tie against India and a competitive effort against Pakistan, the team … [+5118 chars]"
        },
        {
            "source": {
                "id": "al-jazeera-english",
                "name": "Al Jazeera English"
            },
            "author": "Al Jazeera",
            "title": "Indonesia: Rescuers search for survivors after quake, tsunami",
            "description": "Rescuers rushing to reach people trapped by the quake and tsunami that has killed over 400 people in Palu city alone.",
            "url": "http://www.aljazeera.com/news/2018/09/indonesia-rescuers-search-survivors-quake-tsunami-180930052755793.html",
            "urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/30/59c2bcfc48a046f78ae30a9548511fcc_18.jpg",
            "publishedAt": "2018-09-30T06:44:00Z",
            "content": "Rescue teams in Indonesia have struggled to reach communities devastated by a major earthquake and tsunami on Sulawesi island, with a toll of more than 400 killed expected to rise sharply as contact is restored with remote areas. Amid the levelled trees, over… [+3207 chars]"
        },
        {
            "source": {
                "id": "al-jazeera-english",
                "name": "Al Jazeera English"
            },
            "author": "Charlotte Mitchell",
            "title": "Six months to go until Brexit: All you need to know",
            "description": "Will Brexit definitely happen? Is a trade deal expected? What will happen to migrants? How will the economy be affected?",
            "url": "http://www.aljazeera.com/news/2018/09/months-brexit-180923173227311.html",
            "urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/28/e45c2ba07b944276b369e3fe291bf21b_18.jpg",
            "publishedAt": "2018-09-29T08:17:00Z",
            "content": "Britain is due to leave the EU in six months' time, at 23:00 GMT on March 29, 2019. Here are five things to know: 1. Will Brexit definitely happen? The UK government remains committed to reaching an agreement with the EU before negotiations end in March, howe… [+9323 chars]"
        },
        {
            "source": {
                "id": "al-jazeera-english",
                "name": "Al Jazeera English"
            },
            "author": "James Rippingale",
            "title": "The toll of burying Grenfell's dead",
            "description": "For those who cared for the living and the dead after the Grenfell Tower fire, the struggle for justice continues.",
            "url": "http://www.aljazeera.com/indepth/features/toll-burying-grenfell-dead-180926072155075.html",
            "urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/28/faafdfc4216b47bbb86282cf33fca7df_18.jpg",
            "publishedAt": "2018-09-29T06:40:00Z",
            "content": "\"I'd never heard of Grenfell before. I didn't think there were that many Muslims in Chelsea,\" exclaims Abu Mumin, 48, of Eden Care, a Muslim end-of-life support charity run from a compact, green and white-walled Whitechapel office. It's a frantic Monday and t… [+9655 chars]"
        }
    ]
}

我的NewsAdapter类之下

  public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.NewsViewHolder> {


        private List<Article> articleList;

        public NewsAdapter(List<Article> articleList) {
            this.articleList = articleList;
        }


        @NonNull
        @Override
        public NewsViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
            View itemView = LayoutInflater.
                    from(viewGroup.getContext()).
                    inflate(R.layout.news_item, viewGroup, false);
            return new NewsViewHolder(itemView);
        }

        @Override
        public void onBindViewHolder(@NonNull NewsViewHolder newsViewHolder, int i) {
            Article article = articleList.get(i);
            newsViewHolder.articleAuthor.setText(article.getAuthor());
            newsViewHolder.articleTitle.setText(article.getTitle());
            newsViewHolder.articleDescription.setText(article.getDescription());
            Picasso.get().load(article.getUrlToImage()).into(newsViewHolder.articleImage);


        }


        @Override
        public int getItemCount() {

            return articleList.size();
        }

        public final static class NewsViewHolder extends RecyclerView.ViewHolder {
            // TextView articleAuthor, articleTitle, articleDescription, articleUrl;
            //  ImageView articleImage;
            @BindView(R.id.article_Image)
            ImageView articleImage;
            @BindView(R.id.article_Author)
            TextView articleAuthor;
            @BindView(R.id.article_Title)
            TextView articleTitle;

            @BindView(R.id.article_Description)
            TextView articleDescription;

            @BindView(R.id.article_Url)
            TextView articleUrl;


            public NewsViewHolder(View itemView) {
                super(itemView);
                ButterKnife.bind(this, itemView);

            }
        }
    }

在我的Article模型课程下 公共类文章{

@SerializedName("source")
@Expose
private Source source;
@SerializedName("author")
@Expose
private String author;
@SerializedName("title")
@Expose
private String title;
@SerializedName("description")
@Expose
private String description;
@SerializedName("url")
@Expose
private String url;
@SerializedName("urlToImage")
@Expose
private String urlToImage;
@SerializedName("publishedAt")
@Expose
private String publishedAt;
@SerializedName("content")
@Expose
private String content;

public Source getSource() {
    return source;
}

public void setSource(Source source) {
    this.source = source;
}

public String getAuthor() {
    return author;
}

public void setAuthor(String author) {
    this.author = author;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public String getUrl() {
    return url;
}

public void setUrl(String url) {
    this.url = url;
}

public String getUrlToImage() {
    return urlToImage;
}

public void setUrlToImage(String urlToImage) {
    this.urlToImage = urlToImage;
}

public String getPublishedAt() {
    return publishedAt;
}

public void setPublishedAt(String publishedAt) {
    this.publishedAt = publishedAt;
}

public String getContent() {
    return content;
}

public void setContent(String content) {
    this.content = content;
}

}

2 个答案:

答案 0 :(得分:0)

我发现您的代码有很多问题。

您的json有文章列表。但是您的Call <Article> getAllJazeera() api返回<Article>而不是<List<Article>>。实际上,您应该有一种ArticleListResponse模型,其中包含JSON中的文章列表和其他字段,例如

"status": "ok",
"totalResults": 9,

我看到的另一个问题是您正在执行的改造成功回调

            adapter = new NewsAdapter((List<Article>) articleList);

即使articleList甚至不是List<Article>。您创建一个Article变量,然后尝试将其转换为列表。

您需要进行所有这些更改,然后您的代码才能工作。

答案 1 :(得分:0)

您错误地创建了模型类,首先您将需要一个这样的模型类

ArticleResponse.java

    public class ArticleResponse {

@SerializedName("status")
@Expose
private String status;
@SerializedName("totalResults")
@Expose
private Integer totalResults;
@SerializedName("articles")
@Expose
private List<Article> articles = null;

public String getStatus() {
return status;
}

public void setStatus(String status) {
this.status = status;
}

public Integer getTotalResults() {
return totalResults;
}

public void setTotalResults(Integer totalResults) {
this.totalResults = totalResults;
}

public List<Article> getArticles() {
return articles;
}

public void setArticles(List<Article> articles) {
this.articles = articles;
}

}
  

现在将此public Article articleList;更改为此public ArrayList<Article> articleList=new ArrayList();

现在像这样更改您的网络通话

@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
    final View rootView = inflater.inflate(R.layout.alljazeera_fragment, container, false);

    NewsInterface apiService = NewsClient.getApiService();
    Call <ArticleResponse> call = apiService.getAllJazeera();

    call.enqueue(new Callback <ArticleResponse>() {
        @Override
        public void onResponse(Call <ArticleResponse> call, Response <ArticleResponse> response) {

            articleList = new ArrayList<>(response.body().getArticles());
            recyclerView =  rootView.findViewById(R.id.recycler_view);
            adapter = new NewsAdapter(articleList);
            RecyclerView.LayoutManager eLayoutManager = new LinearLayoutManager(getActivity());
            recyclerView.setLayoutManager(eLayoutManager);
            recyclerView.setAdapter(adapter);

        }

        @Override
        public void onFailure(Call <ArticleResponse> call, Throwable t) {

        }
    });

    return rootView;
}

现在更改界面也是如此

 @GET("v2/top-headlines?sources=al-jazeera-english&apiKey=a5cc70bd52c9436785557878f4aa49e1")
Call <ArticleResponse> getAllJazeera();

@GET("v2/top-headlines?sources=cbc-news&apiKey=a5cc70bd52c9436785557878f4aa49e1")
Call <ArticleResponse> getCbC();

@GET("v2/top-headlines?sources=bbc-news&apiKey=a5cc70bd52c9436785557878f4aa49e1")
Call <ArticleResponse> getBBC();

@GET("v2/top-headlines?sources=cnn&apiKey=a5cc70bd52c9436785557878f4aa49e1")
Call <ArticleResponse> getCNN();