E/RecyclerView:未连接适配器;正在跳过带有API 29的布局错误Android Studio



所以我在安卓工作室中跟踪一个视频从头开始做新闻应用程序,遇到了标题错误。我试着遵循关于同一错误的许多问题的答案,但很难理解,因为每个人都有不同的代码。这是我的适配器代码:

package com.example.newsapp4;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import com.example.newsapp4.Model.Articles;
import com.squareup.picasso.Picasso;
import java.util.List;
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
Context context;
List<Articles> articles;
public Adapter(Context context, List<Articles> articles) {
this.context = context;
this.articles = articles;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.items, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
final Articles a = articles.get(position);
String imageUrl = a.getUrlToImage();
holder.tvTitle.setText(a.getTitle());
holder.tvSource.setText(a.getSource().getName());
holder.tvDate.setText(a.getPublishedAt());

Picasso.with(context).load(imageUrl).into(holder.imageView);
}
@Override
public int getItemCount() {
return articles.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tvTitle,tvSource,tvDate;
ImageView imageView;
CardView cardView;
public ViewHolder(@NonNull View itemView) {
super(itemView);
tvTitle = itemView.findViewById(R.id.tvTitle);
tvSource = itemView.findViewById(R.id.tvSource);
tvDate = itemView.findViewById(R.id.tvDate);
imageView = itemView.findViewById(R.id.image);
cardView = itemView.findViewById(R.id.cardView);
}
}
}

这是我的java类,我用recyclerview调用适配器:

package com.example.newsapp4;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.example.newsapp4.Model.Articles;
import com.example.newsapp4.Model.Headlines;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class sportsnews extends AppCompatActivity {
Adapter adapter;
Intent intencion;
RecyclerView recyclerView;
final String API_KEY = "my api key";
List<Articles> articles = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sportsnews);
recyclerView = findViewById(R.id.recyclerView1);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
String country = getCountry();
retrieveJson(country, API_KEY);
}
public void retrieveJson(String country, String apiKey){
Call<Headlines> call = ApiClient.getInstance().getApi().getHeadlines(country, apiKey);
call.enqueue(new Callback<Headlines>() {
@Override
public void onResponse(Call<Headlines> call, Response<Headlines> response) {
if(response.isSuccessful() && response.body().getArticles() != null){
articles.clear();
articles = response.body().getArticles();
adapter = new Adapter(sportsnews.this,articles);
recyclerView.setAdapter(adapter);
}
}

@Override
public void onFailure(Call<Headlines> call, Throwable t) {
Toast.makeText(sportsnews.this, t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
});
}
public String getCountry(){
Locale locale = Locale.getDefault();
String country = locale.getCountry();
return country.toLowerCase();
}
public void aPerfil(View vista){
intencion = new Intent(this, profile_activity.class);
startActivity(intencion);
}
}

请注意,有一个方法与一个未应用的按钮一起使用。方法为aPerfil

这是我的manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.newsapp4">

<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".sportsnews" android:screenOrientation="locked"/>
<activity android:name=".profile_activity" android:screenOrientation="locked"/>
<activity android:name=".menuContent" android:screenOrientation="locked"/>
<activity android:name=".MainActivity" android:screenOrientation="locked">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="preloaded_fonts"
android:resource="@array/preloaded_fonts" />
</application>
</manifest>

在到达具有适配器的活动之前还有更多的活动。

我猜我需要把网页给我的密钥放在我的api密钥中,比如很多数字和字母,而不是链接。

如果你需要,可以随意要求更多的代码。

谢谢你抽出时间!

retrieveJson(country, API_KEY);之前将下面的代码从onResponse移动到onCreate

adapter = new Adapter(sportsnews.this,articles);
recyclerView.setAdapter(adapter);

在你的Adapter中创建一个类似的设置器

public void setArticles(List<Articles> newArticle) {
if (newArticle != null && newArticle.size() > 0) {
this.articles = newArticle;
notifyDataSetChanged();
}
}

然后在您的onResponse中写一些类似于下面的内容,之前您在recylerview中设置适配器。

adapter.setArticles(articles)

注意:recylerView在膨胀时应始终连接到适配器,您不能等待API响应,因为它在diff线程上运行,需要一段时间才能获取数据。到那时,操作系统将已经尝试膨胀recylerView,如果没有连接适配器,则会失败。

因此,即使有空数据,我们也应该始终附加适配器,因为这不是问题。您可以在从API收到数据时传递数据,然后调用notifyDataSetChanged((,然后适配器将负责对每个项进行充气。

最新更新