我的应用程序中的新闻页面没有检索到任何新闻,只显示一个空白的白色页面,而不是新闻源。

问题描述 投票:-1回答:1

我目前正在使用Android Studio 4.0,Build #AI-193.6911.18.40.6514223。

在进入新闻页面时,我被显示为一个空白页面。似乎API没有检索到它应该检索到的新闻。我已经仔细检查了我的整个应用程序是否有任何错别字(以防与API参数不匹配)。一切看起来都是正确的,但API没有检索数据。

我在下面附上了关于这个问题的代码。

newsage.java.com

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.widget.Toast;

import com.example.nvirone.API.ApiClient;
import com.example.nvirone.API.ApiInterface;
import com.example.nvirone.Models.Article;
import com.example.nvirone.Models.News;

import java.util.ArrayList;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class Newspage extends AppCompatActivity {
    public static final String API_KEY = "(unique API key)";
    private RecyclerView recyclerView;
    private Adapter adapter;
    private RecyclerView.LayoutManager layoutManager;
    private List<Article> articles = new ArrayList<>();
    private String TAG = Newspage.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_newspage);
        recyclerView = findViewById(R.id.recyclerView);
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        adapter = new Adapter(articles, Newspage.this);
        recyclerView.setAdapter(adapter);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setNestedScrollingEnabled(false);
        LoadJson();
    }
public void LoadJson(){
    ApiInterface apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
    String country = Utils.getCountry();

    Call<News> call;
    call = apiInterface.getNews(country, API_KEY);
    call.enqueue(new Callback<News>() {
        @Override
        public void onResponse(Call<News> call, Response<News> response) {
            if (response.isSuccessful() && response.body().getArticle()!=null){
                articles.clear();
                articles = response.body().getArticle();
                adapter.notifyDataSetChanged();
            }
        }

        @Override
        public void onFailure(Call<News> call, Throwable t) {
            Toast.makeText(Newspage.this,"NO result",Toast.LENGTH_LONG).show();
        }
    });
    }
}

Newsindetail.java:

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class NewInDetail extends AppCompatActivity {
    WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_in_detail);
        Intent intent = getIntent();
        String url = intent.getStringExtra("url");
        webView = findViewById(R.id.webView);
        webView.getSettings().setDomStorageEnabled(true);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setLoadsImagesAutomatically(true);
        webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
        webView.setWebViewClient(new WebViewClient());
        webView.loadUrl(url);
    }
}

Adapter:

package com.example.nvirone;

import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import com.example.nvirone.Models.Article;
import com.squareup.picasso.Picasso;

import java.util.List;

public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> {
    private List<Article> articles;
    private Context context;
    private AdapterView.OnItemClickListener OnItemClickListener;
    private OnItemClickListener onItemCLickListener;


    public Adapter(List<Article> articles, Context context) {
        this.articles = articles;
        this.context = context;
    }


    public Adapter() {

    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holders, int position) {
        final MyViewHolder holder = holders;
        final Article model = articles.get(position);
        RequestOptions requestOptions = new RequestOptions();
        requestOptions.placeholder(Utils.getRandomDrawbleColor());
        requestOptions.error(Utils.getRandomDrawbleColor());
        requestOptions.diskCacheStrategy(DiskCacheStrategy.ALL);
        requestOptions.centerCrop();

        Glide.with(context).load(model.getUrlToImage()).apply(requestOptions)
                .listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        holder.progressBar.setVisibility(View.GONE);
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        holder.progressBar.setVisibility(View.GONE);
                        return false;
                    }
                })
                .transition(DrawableTransitionOptions.withCrossFade())
                .into(holder.imageView);
        holder.title.setText(model.getTitle());
        holder.desc.setText(model.getDescription());
        holder.source.setText(model.getSource().getName());
        holder.time.setText('\u2022' + Utils.DateToTimeFormat(model.getPublishedAt()));
        holder.published.setText(Utils.DateToTimeFormat(model.getPublishedAt()));
        holder.author.setText(model.getAuthor());
        String imageURL = model.getUrlToImage();
        Picasso.get().load(imageURL).into(holder.imageView);
        holder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(context,NewInDetail.class);
                intent.putExtra("url",model.getUrl());
                context.startActivity(intent);
            }
        });
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.item,parent,false);
        return new MyViewHolder(view, onItemCLickListener);
    }

    @Override
    public int getItemCount() {
        return articles.size();
    }
    public void setOnItemClickListener(OnItemClickListener onItemClickListener){
        this.onItemCLickListener = onItemClickListener;
    }

    public interface OnItemClickListener{
        void onItemClick(View view, int position);
    }

    public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

        TextView title, desc, author, published, source, time;
        ImageView imageView;
        ProgressBar progressBar;
        OnItemClickListener onItemClickListener;
        CardView cardView;
        public MyViewHolder(@NonNull View itemView, OnItemClickListener onItemClickListener) {
            super(itemView);
            itemView.setOnClickListener(this);
            title  = itemView.findViewById(R.id.title);
            desc = itemView.findViewById(R.id.desc);
            author = itemView.findViewById(R.id.author);
            published = itemView.findViewById(R.id.publishedAt);
            source = itemView.findViewById(R.id.source);
            time = itemView.findViewById(R.id.time);
            imageView = itemView.findViewById(R.id.img);
            progressBar = itemView.findViewById(R.id.progress_load_photo);
            cardView = itemView.findViewById(R.id.cardView);

            this.onItemClickListener = onItemCLickListener;
        }
        @Override
        public void onClick(View view) {
            onItemClickListener.onItemClick(view, getAdapterPosition());
        }
    }
}

ApiClient.ApiInterface: ApiClient:

package com.example.nvirone.API;

import java.security.cert.CertificateException;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class ApiClient {
    public static final String BaseURL = "https://newsapi.org/v2/";
    public static Retrofit retrofit ;

    public static Retrofit getApiClient(){
        if(retrofit==null){
            retrofit = new Retrofit.Builder().baseUrl(BaseURL).client(getUnsafeOkHttpClient().build()).addConverterFactory(GsonConverterFactory.create()).build();
        }
        return retrofit;
    }
    public static OkHttpClient.Builder getUnsafeOkHttpClient(){
        try {
            // Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[]{};
                        }
                    }
            };

            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
            return builder;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

ApiInterface:

package com.example.nvirone.API;

import com.example.nvirone.Models.News;

import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;

public interface ApiInterface {
    @GET("top-headlines")
    Call<News> getNews(

            @Query("country") String country,
            @Query("apiKey") String apiKey
    );
}

Utils:

package com.example.nvirone;

import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;

import org.ocpsoft.prettytime.PrettyTime;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Random;

public class Utils {

    public static ColorDrawable[] vibrantLightColorList =
            {
                    new ColorDrawable(Color.parseColor("#ffeead")),
                    new ColorDrawable(Color.parseColor("#93cfb3")),
                    new ColorDrawable(Color.parseColor("#fd7a7a")),
                    new ColorDrawable(Color.parseColor("#faca5f")),
                    new ColorDrawable(Color.parseColor("#1ba798")),
                    new ColorDrawable(Color.parseColor("#6aa9ae")),
                    new ColorDrawable(Color.parseColor("#ffbf27")),
                    new ColorDrawable(Color.parseColor("#d93947"))
            };

    public static ColorDrawable getRandomDrawbleColor() {
        int idx = new Random().nextInt(vibrantLightColorList.length);
        return vibrantLightColorList[idx];
    }

    public static String DateToTimeFormat(String oldstringDate){
        PrettyTime p = new PrettyTime(new Locale(getCountry()));
        String isTime = null;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'",
                    Locale.ENGLISH);
            Date date = sdf.parse(oldstringDate);
            isTime = p.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return isTime;
    }

    public static String DateFormat(String oldstringDate){
        String newDate;
        SimpleDateFormat dateFormat = new SimpleDateFormat("E, d MMM yyyy", new Locale(getCountry()));
        try {
            Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'",Locale.CHINA).parse(oldstringDate);
            assert date != null;
            newDate = dateFormat.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
            newDate = oldstringDate;
        }

        return newDate;
    }

    public static String getCountry(){
        Locale locale = Locale.getDefault();
        String country = locale.getCountry();
        return country.toLowerCase();
    }
}

根据API的参数。

新闻。

package com.example.nvirone.Models;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

import java.util.List;

public class News {
    @SerializedName("status")
    @Expose
    private String status;

    @SerializedName("totalResults")
    @Expose
    private int totalResult;

    @SerializedName("articles")
    @Expose
    private List<Article> article;

    public String getStatus() {
        return status;
    }

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

    public int getTotalResult() {
        return totalResult;
    }

    public void setTotalResult(int totalResult) {
        this.totalResult = totalResult;
    }

    public List<Article> getArticle() {
        return article;
    }

    public void setArticle(List<Article> article) {
        this.article = article;
    }
}

文章:新闻。

package com.example.nvirone.Models;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class 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;

    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;
    }
}

源。

package com.example.nvirone.Models;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Source {
    @SerializedName("id")
    @Expose
    private String id;

    @SerializedName("name")
    @Expose
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

用于显示新闻源的卡片视图。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">
    <androidx.cardview.widget.CardView
        android:id="@+id/cardView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="11dp"
        android:layout_marginRight="11dp"
        android:layout_marginTop="7dp"
        android:layout_marginBottom="7dp"
        app:cardElevation="@dimen/cardview_default_elevation"
        app:cardCornerRadius="15dp">
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:id="@+id/img"
                android:scaleType="centerCrop"
                android:transitionName="img"
                tools:ignore= "UnusedAttribute"/>
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="80dp"
                android:id="@+id/shadow_bottom"
                android:src="@drawable/bottom_shadow"
                android:layout_alignBottom="@+id/img" />
            <ProgressBar
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                style="@android:style/Widget.ProgressBar.Small"
                android:id="@+id/progress_load_photo"
                android:layout_marginTop="70dp" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:id="@+id/author"
                android:drawablePadding="10dp"
                android:ellipsize="end"
                android:maxLines="1"
                android:textColor="@android:color/white"
                android:singleLine="true"
                android:text="Author"
                android:gravity="bottom"
                android:layout_marginRight="160dp"
                android:layout_alignLeft="@+id/title"
                android:layout_alignStart="@+id/title"
                android:layout_alignRight="@+id/layoutDate"
                android:layout_alignTop="@+id/layoutDate"
                android:layout_alignEnd="@+id/layoutDate"/>
            <FrameLayout
                android:id="@+id/layoutDate"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/img"
                android:background="@drawable/round_white"
                android:padding="5dp"
                android:layout_alignParentRight="true"
                android:layout_marginRight="20dp"
                android:layout_marginTop="50dp">
                <ImageView
                    android:src="@drawable/ic_date"
                    android:layout_width="18dp"
                    android:layout_height="18dp"
                    android:layout_marginLeft="5dp"
                    android:layout_marginRight="5dp"/>
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="#606060"
                    android:id="@+id/publishedAt"
                    android:layout_marginLeft="27dp"
                    android:layout_marginRight="10dp"
                    android:text="01 January 2000"/>
            </FrameLayout>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:fontFamily="sans-serif-light"
                android:textStyle="bold"
                android:textColor="@color/colorTextTitle"
                android:layout_marginLeft="16dp"
                android:layout_marginRight="16dp"
                android:text="Title"
                android:textSize="17sp"
                android:layout_marginTop="10dp"
                android:layout_below="@id/img"
                android:id="@+id/title"/>
            <TextView
                android:id="@+id/desc"
                android:layout_width="wrap_content"
                android:layout_height="20dp"
                android:layout_marginRight="16dp"
                android:layout_below="@+id/title"
                android:layout_marginLeft="16dp"
                android:layout_marginTop="5dp"
                android:text="Desc"/>
            <TextView
                android:id="@+id/source"
                android:layout_width="wrap_content"
                android:layout_height="20dp"
                android:layout_below="@+id/desc"
                android:layout_marginLeft="16dp"
                android:layout_marginTop="10dp"
                android:layout_marginBottom="10dp"
                android:fontFamily="sans-serif-light"
                android:textStyle="bold"
                android:textColor="@color/colorTextTitle"
                android:ellipsize="end"
                android:singleLine="true"
                android:drawablePadding="10dp"
                android:maxLines="1"
                android:text="Source"/>
            <TextView
                android:id="@+id/time"
                android:layout_width="wrap_content"
                android:layout_height="20dp"
                android:layout_below="@+id/desc"
                android:layout_marginTop="10dp"
                android:layout_marginBottom="10dp"
                android:layout_toRightOf="@+id/source"
                android:ellipsize="end"
                android:singleLine="true"
                android:drawablePadding="10dp"
                android:maxLines="1"
                android:text="Time"/>


        </RelativeLayout>


    </androidx.cardview.widget.CardView>

</FrameLayout>

EDIT .I have added some code in the API: NEWS: Article : Source: The cardview that is supposed to display the newsfeed : EDIT :我已经添加了一些代码在 API interface 如下所示,在尝试使用这个查询后,又出现了同样的问题。

@GET("everything")
Call<News> getNewsSearch(

    @Query("q") String Keyword,
    @Query("language") String language,
    @Query("SortBy") String sortBy,
    @Query("apiKey") String apiKey

    );
java android api android-studio
1个回答
0
投票

你需要添加这个方法在你的 Adapter.java:

public void addArticles(List<Article> articles) {
    this.articles.addAll(articles);
    int count = getItemCount();
    notifyItemRangeInserted(count, count + articles.size());
}

并在你身上这样使用 NewsPage.java:

public void LoadJson() {
   ApiInterface apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
   String       country      = Utils.getCountry();

   Call<News> call;
   call = apiInterface.getNews(country, API_KEY);
   call.enqueue(new Callback<News>() {

      @Override
      public void onResponse(Call<News> call, Response<News> response) {
         List<Article> newArticles = response.body().getArticle();
         if (response.isSuccessful() && newArticles != null) {
            adapter.addArticles(newArticles);
         }
      }

      @Override
      public void onFailure(Call<News> call, Throwable t) {
         Toast.makeText(NewsPage.this, "NO result", Toast.LENGTH_LONG).show();
      }
   });
}
© www.soinside.com 2019 - 2024. All rights reserved.