Это странная проблема, с которой я столкнулся прямо сейчас. Из моего приложения я извлекаю данные из файла JSON по ссылке, а затем анализирую их с помощью Volley. Теперь я хочу отобразить данные в RecyclerView, который, похоже, не работает, я уверен, что мой код хорош, но что-то не работает, и я не могу его найти.
activity_home.xml
Кажется, это отображается, как я тестировал с фоновым цветом:
<?xml version = "1.0" encoding = "utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width = "match_parent"
android:layout_height = "match_parent"
tools:context = ".activities.HomeActivity">
<androidx.recyclerview.widget.RecyclerView
android:id = "@+id/rv_main_list"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
app:layout_constraintBottom_toBottomOf = "parent"
app:layout_constraintEnd_toEndOf = "parent"
app:layout_constraintStart_toStartOf = "parent"
app:layout_constraintTop_toTopOf = "parent">
</androidx.recyclerview.widget.RecyclerView>
</androidx.constraintlayout.widget.ConstraintLayout>
Вот код активности
HomeActivity.java:
public class HomeActivity extends AppCompatActivity {
private String url = "url/to/json.file";
private RecyclerView mList;
private LinearLayoutManager linearLayoutManager;
private List<News> newsList;
private RecyclerView.Adapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
newsList = new ArrayList<>();
mList = findViewById(R.id.rv_main_list);
adapter = new NewsAdapter(newsList);
mList.setHasFixedSize(true);
mList.setLayoutManager(new LinearLayoutManager(this));
mList.setAdapter(adapter);
getData();
}
Это макет, который я накачиваю из адаптера и устанавливаю данные из файла JSON.
layout_single_item
<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
xmlns:app = "http://schemas.android.com/apk/res-auto"
android:id = "@+id/linearlayout"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:background = "#673AB7"
android:orientation = "vertical">
<ImageView
android:id = "@+id/iv_image"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
app:srcCompat = "@mipmap/ic_launcher" />
<TextView
android:id = "@+id/tv_title"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:text = "TextView" />
</LinearLayout>
И соответствующий код класса адаптера, я думаю:
@Override public NewsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); View view = layoutInflater.inflate(R.layout.layout_single_item, parent, false); ViewHolder viewHolder = новый ViewHolder (представление); вернуть видхолдер; }
@Override
public void onBindViewHolder(@NonNull NewsAdapter.ViewHolder holder, int position) {
final News currentNews = newsList.get(position);
holder.tvTitle.setText(String.valueOf(currentNews.getTitle()));
Glide.with(mContext.getApplicationContext()).load(currentNews.getImage()).into(holder.ivArticleImage); }
holder.linearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri newsUri = Uri.parse(currentNews.getNewsLink());
Intent toWebSiteIntent = new Intent(Intent.ACTION_VIEW, newsUri);
mContext.startActivity(toWebSiteIntent);
}
});
Класс ViewHolder:
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView tvTitle;
public ImageView ivArticleImage;
public LinearLayout linearLayout;
public ViewHolder(@NonNull View itemView) {
super(itemView);
this.tvTitle = itemView.findViewById(R.id.tv_title);
this.ivArticleImage = itemView.findViewById(R.id.iv_image);
linearLayout = itemView.findViewById(R.id.linearlayout);
}
}
Не уверен, что я делаю неправильно. Спасибо за ваше время.
Редактировать:
функция получения данных:
private void getData() {
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading...");
progressDialog.show();
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(url, new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
ArrayList<News> newsList = new ArrayList<>();
for(int i = 0; i < response.length(); i++){
try{
JSONObject jsonObject = response.getJSONObject(i);
News article = new News();
article.setTitle(jsonObject.getString("title"));
article.setImage(jsonObject.getString("image"));
}catch (JSONException e){
e.printStackTrace();
progressDialog.dismiss();
}
}
adapter.notifyDataSetChanged();
progressDialog.dismiss();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("Volley", error.toString());
progressDialog.dismiss();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(jsonArrayRequest);
}
Обновление 2:
Process: com.agencegg.apps.actualitecd, PID: 15002 java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference at com.agencegg.apps.actualitecd.adapters.NewsAdapter.onBindViewHolder(NewsAdapter.java:73) at com.agencegg.apps.actualitecd.adapters.NewsAdapter.onBindViewHolder(NewsAdapter.java:31) //...
позвонив adapter.notifyDataSetChanged(); ?
обновить адаптер с помощью списка новостей. Создайте метод в своем классе адаптера. После вызова API вызовите этот метод, а затем adapter.notifyDataSetChanged().
Я не использую API, это прямая ссылка на файл JSON.
Пожалуйста, поделитесь кодом метода getData() для лучшего понимания. После анализа данных из json-файла вызовите метод обновления из вашего адаптера.
Кажется, что элемент не отображается. Потому что даже с жестко закодированными значениями представления не отображаются. tvTitle с текстом по умолчанию не отображается
Добавьте метод в свой адаптер следующим образом:
public void update(ArrayList<News> newsList){
this.newsList = newsList;
}
Обновите свой список в методе onResponse() следующим образом:
@Override
public void onResponse(JSONArray response) {
ArrayList<News> newsList = new ArrayList<>();
for(int i = 0; i < response.length(); i++){
try{
JSONObject jsonObject = response.getJSONObject(i);
News article = new News();
article.setTitle(jsonObject.getString("title"));
article.setImage(jsonObject.getString("image"));
newsList.add(news).
}catch (JSONException e){
e.printStackTrace();
progressDialog.dismiss();
}
}
adapter.update(newsList)
adapter.notifyDataSetChanged();
progressDialog.dismiss();
}
}
Комментарии не для расширенного обсуждения; этот разговор был перешел в чат.
у меня другая просьба
Вы обновили адаптер после получения данных из API? Изначально список пуст.