Mi página de noticias en mi aplicación no recupera ninguna noticia y solo se muestra una página en blanco en lugar de una fuente de noticias

Ganesh Chandra:

Actualmente estoy trabajando en Android Studio 4.0, Build # AI-193.6911.18.40.6514223.

Al ingresar a la página de noticias, se me muestra una página en blanco. Parece que la API no está recuperando las noticias que se supone que debe. He verificado dos veces mi aplicación completa para ver si hay algún error tipográfico (en caso de que no coincida con los parámetros de la API). Todo parece correcto pero la API no está recuperando los datos.

He adjuntado debajo del código con respecto al problema.

newspage.java:

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

Adaptador:

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:

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

Utilidades:

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

Parámetros según la API:

NOTICIAS:

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

Artículo:

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

Fuente:

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

La vista de tarjeta que se supone que muestra el suministro de noticias:

<?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>
hiddeneyes02:

Necesita agregar este método en su Adapter.java:

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

Y úsalo de esta manera en tu 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();
      }
   });
}

Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.

En caso de infracción, por favor [email protected] Eliminar

Editado en
0

Déjame decir algunas palabras

0Comentarios
Iniciar sesiónRevisión de participación posterior

Artículos relacionados

TOP Lista

  1. 1

    ¿Cómo ocultar la aplicación web de los robots de búsqueda? (ASP.NET)

  2. 2

    Pandas의 CSV 파일을 Pandas 데이터 프레임으로 가져 오기

  3. 3

    uitableview delete button image in iOS

  4. 4

    Manera correcta de agregar referencias al proyecto C # de modo que sean compatibles con el control de versiones

  5. 5

    Swift / Firebase : Facebook 사용자가 계정을 만들 때 Firebase 데이터베이스에 제대로 저장하려면 어떻게해야합니까?

  6. 6

    caída condicional de filas desde un marco de datos de pandas

  7. 7

    Link library in Visual Studio, why two different ways?

  8. 8

    Pagination class not getting applied in html

  9. 9

    Que signifie Decimal (-1)?

  10. 10

    UIButton textLabel with different fonts

  11. 11

    WPF pleine largeur DataGridColumn sur la largeur de DataGrid

  12. 12

    Opción de máquina virtual no reconocida 'MaxPermSize = 512m' cuando se ejecuta Zeppelin

  13. 13

    matplotlib로 그래프를 그리는 동안 커서 위치에서 날짜 / 시간을 볼 수 없습니다. "DateFormatter에서 x = 0 값을 찾았습니다"라는 오류가 발생합니다.

  14. 14

    ¿Es posible en Windows evitar que otras aplicaciones se enganchen en las DLL del sistema?

  15. 15

    Error de la base de datos de Android Firebase: Permiso denegado al depurar en un teléfono

  16. 16

    Pandas: suma filas de DataFrame para columnas dadas

  17. 17

    ggplot2: gráfico con líneas y puntos para problemas de leyenda de dos conjuntos de datos

  18. 18

    ¿Cómo especificar el puerto en el que se aloja una aplicación ASP.NET Core?

  19. 19

    Recherche de la position d'index d'une valeur dans r dataframe

  20. 20

    GPU를 사용하여 ffmpeg 필터의 처리 속도를 가속화하는 방법은 무엇입니까?

  21. 21

    nested observables executed one after the other after termination

CalienteEtiquetas

Archivo