RecyclerView не отображается в действии

У меня есть файл NewsDetailsActivity, в котором отображаются некоторые новости. Поверх сведений о новостях я хочу отобразить некоторые cardview в recyclerview. RecyclerView не отображается, но хуже всего то, что другой recyclerview (который у меня есть в MainActivity отображается в моем NewsDetailsActivity, например, если я вызываю какой-то id из моего NewsDetailsActivity.

Единственное, что я хочу, это отображать некоторую информацию в верхней части сведений о новостях, используя идентификатор recyclerview my_recycler_view_coin_details

Информация о новостях

package com.noticripto.activities;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.noticripto.APIClientCoin;
import com.noticripto.adapters.CryptoListAdapter;


import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;


import com.bumptech.glide.Glide;
import com.noticripto.MainActivity;
import com.noticripto.R;
import com.noticripto.adapters.NewsAdapter;
import com.noticripto.model.HomePageModel;
  import com.noticripto.rest.ApiClient;
import com.noticripto.rest.ApiInterface;
import com.noticripto.retrofit.CryptoList;
import com.noticripto.retrofit.Datum;

 import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

public class NewsDetailActivity extends AppCompatActivity {



Toolbar toolbar;

TextView sourceName, newsTitle, newsDesc, newsDate, newsView,labelSimilar;
Button viewMore;
ImageView imagy,small_icn;


ProgressBar progressBar;


RecyclerView recyclerView3;
CryptoListAdapter adapterCoin2;
ApiInterface apiInterfaceCoin2;
List<Datum> cryptoList2 = null;

HomePageModel.News detailNews = null;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_news_detail);
    apiInterfaceCoin2 = APIClientCoin.getClient().create(ApiInterface.class);
    recyclerView3 = findViewById(R.id.my_recycler_view_coin_details);

    initViews();

    LoadNewsDetails();

    getCoinList();


}

private void LoadNewsDetails() {
    // Calling our api
    ApiInterface apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
    Map<String, String> params = new HashMap<>();

    params.put("id" , getIntent().getIntExtra("pid", 0) + "");


    Call<HomePageModel> call = apiInterface.getNewsDetailsById(params);
    call.enqueue(new Callback<HomePageModel>() {
        @Override
        public void onResponse(Call<HomePageModel> call, Response<HomePageModel> response) {

            // Update the news layout
            detailNews = response.body().getNews().get(0);
            newsTitle.setText(detailNews.getTitle());
            newsDesc.setText(NewsAdapter.removeHtml(detailNews.getPostContent()));

            if (detailNews.getImage().length() >=1){
                Glide.with(NewsDetailActivity.this)
                        .load(detailNews.getImage())
                        .placeholder(R.drawable.image1)
                        .into(imagy);
            }else{
                imagy.setVisibility(View.GONE);
            }


        }

        @Override
        public void onFailure(Call<HomePageModel> call, Throwable t) {
            progressBar.setVisibility(View.GONE);
        }
    });

}

private void initViews() {
    toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setTitle("");

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        toolbar.setNavigationIcon(R.drawable.icon_arrow_back_white);

        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();

            }
        });


    }

    cryptoList2 = new ArrayList<>();

    adapterCoin2 = new CryptoListAdapter(cryptoList2);

   // sourceName = findViewById(R.id.source_name );
    newsTitle  = findViewById(R.id.news_title);
    newsDesc  = findViewById(R.id.news_desc);
    newsDate = findViewById(R.id.news_date);
    //newsView = findViewById(R.id.news_view);
    labelSimilar = findViewById(R.id.label_similar_news);

    //viewMore = findViewById(R.id.view_more);
    progressBar = findViewById(R.id.progressBar);

    imagy =findViewById(R.id.news_image);
    //small_icn = findViewById(R.id.small_icn);




    recyclerView3 = findViewById(R.id.my_recycler_view_coin_details);
    LinearLayoutManager linearLayoutManager3 =new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.HORIZONTAL, false);
    recyclerView3.setLayoutManager(linearLayoutManager3);
    recyclerView3.setNestedScrollingEnabled(false);
    recyclerView3.setAdapter(adapterCoin2);

    adapterCoin2.notifyItemInserted(0);
    recyclerView3.scrollToPosition(0);


}


public void getCoinList() {

    Call<CryptoList> call2 = apiInterfaceCoin2.doGetUserList("20");
    call2.enqueue(new Callback<CryptoList>() {
        @Override
        public void onResponse(Call<CryptoList> call, Response<CryptoList> response) 
{
            CryptoList list = response.body();

            cryptoList2.clear();
            cryptoList2.addAll(list.getData());

            adapterCoin2.notifyDataSetChanged();

            System.out.println("List getData = " + list.getData());
        }

        @Override
        public void onFailure(Call<CryptoList> call, Throwable t) {
            Toast.makeText(NewsDetailActivity.this, "onFailure", 
   Toast.LENGTH_SHORT).show();
            Log.d("XXXX", t.getLocalizedMessage());
            call.cancel();
        }
    });
}




@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.news_details_menu, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    if (item.getItemId() == R.id.share){

        if (detailNews != null){
            // Opening sharing options
            Intent i = new Intent(Intent.ACTION_SEND);
            i.setType("text/plain");
            i.putExtra(Intent.EXTRA_SUBJECT, detailNews.getTitle());
            i.putExtra(Intent.EXTRA_TEXT, detailNews.getPostContent());
            startActivity(i);

        }else{
            Toast.makeText(this, "Lo Sentimos!", Toast.LENGTH_SHORT).show();

        }
    }

    return super.onOptionsItemSelected(item);
   }
  }

crypto_list_item_in_detail_activity.xml

     <?xml version="1.0" encoding="utf-8"?>
    <androidx.cardview.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/cardViewCoinDetails"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginRight="3dp"
    android:layout_marginBottom="10dp"
    android:layout_marginTop="10dp"
    android:layout_marginLeft="10dp"
    app:cardCornerRadius="8dp"
    app:cardBackgroundColor="@android:color/white">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <TextView
                android:id="@+id/symbolNameDetails"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:fontFamily="roboto_bold"
                android:gravity="center"
                android:paddingBottom="3dp"
                android:singleLine="true"
                android:text="Symbol"
                android:textAppearance="@android:style/TextAppearance.Large"
                android:textColor="#000"
                android:textSize="15dp" />

            <TextView
                android:id="@+id/priceDetails"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:singleLine="true"
                android:textStyle="bold"
                android:text="Price"
                android:textSize="13dp"
                android:layout_marginBottom="5dp"
                android:layout_toRightOf="@+id/symbolNameDetails"
                android:textAppearance="@android:style/TextAppearance.Medium"
                android:textColor="#000" />


        </RelativeLayout>

    </LinearLayout>

</androidx.cardview.widget.CardView>

activity_news_details.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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.NewsDetailActivity">

<androidx.appcompat.widget.Toolbar
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/toolbar"
    android:background="@color/black"/>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_below="@+id/toolbar"
    android:layout_height="wrap_content">


    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="5dp"
        android:indeterminateTint="@color/yellow"/>


    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="none"
        android:overScrollMode="never"
        android:layout_below="@+id/progressBar">




        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">


            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/my_recycler_view_coin_details"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scrollbars="horizontal" />

            <androidx.cardview.widget.CardView
                android:id="@+id/wrapper_cardview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="5dp">

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <LinearLayout
                        android:id="@+id/wrapper"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal">

                    </LinearLayout>

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:id="@+id/news_title"
                        android:text="Titulo"
                        android:textStyle="bold"
                        android:layout_below="@+id/wrapper"
                        android:textSize="22sp"
                        android:paddingLeft="16dp"
                        android:textAlignment="center"
                        android:paddingStart="16dp"
                        android:textColor="@color/black"
                        android:gravity="center_horizontal" />


                    <RelativeLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:id="@+id/wrapper_news"
                        android:layout_below="@id/news_title"
                        android:paddingLeft="10dp"
                        android:layout_marginTop="4dp">


                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:id="@+id/news_date"
                            android:paddingEnd="10dp"
                            android:paddingStart="10dp"
                            android:text="Date"
                            android:paddingRight="5dp"/>


                    </RelativeLayout>

                    <ImageView
                        android:layout_width="match_parent"
                        android:adjustViewBounds="true"
                        android:id="@+id/news_image"
                        android:src="@drawable/icon_youtube"
                        android:layout_below="@id/wrapper_news"
                        android:layout_height="wrap_content"/>


                    <TextView
                        android:id="@+id/news_desc"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_below="@id/news_image"
                        android:fontFamily="@font/roboto"
                        android:padding="10dp"
                        android:text="News Description"
                        android:firstBaselineToTopHeight="0dp"
                        android:includeFontPadding="false"
                        android:lineSpacingExtra="2dp"
                        android:textColor="@color/black"
                        android:textSize="17sp" />

                </RelativeLayout>

            </androidx.cardview.widget.CardView>


            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/wrapper_cardview"
                android:padding="10dp"
                android:textSize="18sp"
                android:text="Similar News"
                android:visibility="gone"
                android:id="@+id/label_similar_news"/>

            <androidx.recyclerview.widget.RecyclerView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/news_recy"
                android:layout_below="@id/label_similar_news"/>




        </RelativeLayout>

    </androidx.core.widget.NestedScrollView>




    </RelativeLayout>
  </RelativeLayout>

И, наконец, я пытаюсь получить список отсюда:

КриптолистАдаптер

package com.noticripto.adapters;

import android.content.Context;
 import android.graphics.Color;
 import androidx.recyclerview.widget.RecyclerView;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.RelativeLayout;
 import android.widget.TextView;

 import com.noticripto.retrofit.Datum;
 import com.noticripto.R;

 import java.util.List;

 public class CryptoListAdapter extends 
 RecyclerView.Adapter<CryptoListAdapter.ViewHolder> {

private List<Datum> mData;
private ItemClickListener mClickListener;
ImageView arrowImage;
RelativeLayout layout;
RelativeLayout symbolBG;

// data is passed into the constructor
public CryptoListAdapter(List<Datum> data) {
    this.mData = data;
}

// Usually involves inflating a layout from XML and returning the holder
// inflates the row layout from xml when needed
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    Context context = parent.getContext();
    LayoutInflater inflater = LayoutInflater.from(context);
    View view = inflater.inflate(R.layout.crypto_list_item, parent, false);
    ViewHolder viewHolder = new ViewHolder(view);

    layout = view.findViewById(R.id.relativeBG);
    symbolBG = view.findViewById(R.id.symbolBG);
    arrowImage = view.findViewById(R.id.arrow_img);


    return viewHolder;
}

// Involves populating data into the item through holder
// binds the data to the TextView in each row
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    // Get the data model based on position
    Datum datum = mData.get(position);

    TextView symbolName = holder.symbolName;
    symbolName.setText(" (" + datum.getSymbol() + ")");

    // Set item views based on your views and data model
    TextView name = holder.name;
    name.setText(datum.getName());
    TextView symbolNameDetails = holder.symbolNameDetails;
    symbolNameDetails.setText(datum.getSymbol());


    TextView price = holder.price;
    TextView priceDetails = holder.priceDetails;
    if(datum.getQuote().getUSD().getPrice() >= 1) {
        price.setText("$" + String.format("%.2f", datum.getQuote().getUSD().getPrice()));
       priceDetails.setText("$" + String.format("%.2f", datum.getQuote().getUSD().getPrice()));
    }else{
        price.setText("$" + String.format("%f", datum.getQuote().getUSD().getPrice()));
       priceDetails.setText("$" + String.format("%.2f", datum.getQuote().getUSD().getPrice()));
    }

    //TextView marketCap = holder.marketCap;
    //marketCap.setText("Market Cap: $" + String.format("%,d", 
Math.round(datum.getQuote().getUSD().getMarketCap())));

    //TextView volume24h = holder.volume24h;
    //volume24h.setText("Volume/24h: $" + String.format("%,d", 
Math.round(datum.getQuote().getUSD().getVolume24h())));

    //TextView textView1h = holder.textView1h;
    //textView1h.setText(String.format("1h: %.2f", 
datum.getQuote().getUSD().getPercentChange1h()) + "%");

    TextView textView24h = holder.textView24h;
    textView24h.setText(String.format("%.2f", datum.getQuote().getUSD().getPercentChange24h()) + "%");





    if(datum.getQuote().getUSD().getPercentChange24h() < 0.0){
        //red
        textView24h.setText(String.format("%.2f", Math.abs(datum.getQuote().getUSD().getPercentChange24h())) + "%");
        textView24h.setTextColor(Color.parseColor("#ffffff"));
        arrowImage.setImageResource(R.drawable.arrow_down_white);
        layout.setBackgroundColor(Color.parseColor("#EA3943"));
        symbolBG.setBackgroundColor(Color.parseColor("#EA3943"));

           priceDetails.setTextColor(Color.parseColor("#EA3943"));





    }else{
        //green
        textView24h.setText(String.format("%.2f", 
      Math.abs(datum.getQuote().getUSD().getPercentChange24h())) + "%");
        textView24h.setTextColor(Color.parseColor("#ffffff"));
        arrowImage.setImageResource(R.drawable.arrow_up_white);
        layout.setBackgroundColor(Color.parseColor("#18C784"));
        symbolBG.setBackgroundColor(Color.parseColor("#18C784"));

        priceDetails.setTextColor(Color.parseColor("#18C784"));

    }


    //TextView textView7d = holder.textView7d;
    //textView7d.setText(String.format("7d: %.2f", 
    datum.getQuote().getUSD().getPercentChange7d()) + "%");

  }

// Returns the total count of items in the list
// total number of rows
@Override
public int getItemCount() {
    return mData.size();
}

// Provide a direct reference to each of the views within a data item
// Used to cache the views within the item layout for fast access
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements 
    View.OnClickListener {
    // Your holder should contain a member variable
    // for any view that will be set as you render a row
    TextView name;
    TextView price;
    TextView marketCap;
    TextView volume24h;
    TextView textView1h;
    TextView textView24h;
    TextView textView7d;
    TextView symbolName;


    TextView priceDetails;
    TextView symbolNameDetails;

    // We also create a constructor that accepts the entire item row
    // and does the view lookups to find each subview
    ViewHolder(View itemView) {
        // Stores the itemView in a public final member variable that can be used
        // to access the context from any ViewHolder instance.
        super(itemView);

        name = itemView.findViewById(R.id.name);
        price = itemView.findViewById(R.id.price);
        //marketCap = itemView.findViewById(R.id.marketCap);
       // volume24h = itemView.findViewById(R.id.volume24h);
        //textView1h = itemView.findViewById(R.id.textView1h);
        textView24h = itemView.findViewById(R.id.textView24h);
        //textView7d = itemView.findViewById(R.id.textView7d);
        symbolName = itemView.findViewById(R.id.symbolName);


        priceDetails = itemView.findViewById(R.id.priceDetails);
        symbolNameDetails = itemView.findViewById(R.id.symbolNameDetails);




        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        if (mClickListener != null) mClickListener.onItemClick(view, 
 getAdapterPosition());
    }
}

// convenience method for getting data at click position
public Datum getItem(int id) {
    return mData.get(id);
}

// allows clicks events to be caught
public void setClickListener(ItemClickListener itemClickListener) {
    this.mClickListener = itemClickListener;
}

// parent activity will implement this method to respond to click events
public interface ItemClickListener {
    void onItemClick(View view, int position);
}
  }

Журнал не говорит ничего полезного, просто список может быть пустым, но тот же список работает на MainActivity, поэтому я считаю, что проблема внутри моего NewsDetailActivity.

Я также попробовал некоторые ответы, и ни один из них мне не помог:

RecyclerView не отображается RecyclerView не отображает элементы CardView неправильно отображается в RecyclerView

Опять же, я просто хочу отобразить свой список из CryptoListAdapter под панелью инструментов NewsDetailActivity... в красивом cardview

Это то, что я хочу сделать... введите здесь описание изображения


person Maduro    schedule 03.07.2021    source источник
comment
...другой recyclerview (тот, что у меня есть в MainActivity, отображается в моем NewsDetailsActivity... – Вы говорите, что данные неверны, или визуальный дизайн RecyclerView и/или его элементов неверен? Или все это ?   -  person Mike M.    schedule 03.07.2021
comment
Данные верны. Я просто хочу отобразить то, что у меня есть в crypto_list_item_in_detail_activity.xml, внутри моего NewsDetailActivity   -  person Maduro    schedule 03.07.2021
comment
View view = inflater.inflate(R.layout.crypto_list_item, parent, false); – Ты это имеешь в виду? Вы хотели раздуть этот другой макет? В onCreateViewHolder() CryptoListAdapter?   -  person Mike M.    schedule 03.07.2021
comment
crypto_list_item_in_detail_activity.xml внутри NewsDetailActivity   -  person Maduro    schedule 03.07.2021
comment
Дело в том, что я не получаю данные от CryptoListAdapter до NewsDetailActivity, и я также не могу отображать crypto_list_item_in_detail_activity.xml внутри NewsDetailActivity, но данные CryptoListAdapter полностью в порядке и отображаются внутри MainActivity, поэтому я думаю, что проблема между NewsDetailActivity и CryptoListAdapter и crypto_list_item_in_detail_activity.xml макетом   -  person Maduro    schedule 03.07.2021
comment
Вы нигде не используете crypto_list_item_in_detail_activity в опубликованном коде. В CryptoListAdapter жестко запрограммировано crypto_list_item, поэтому он всегда будет показывать этот макет элемента, независимо от того, Activity в каком экземпляре CryptoListAdapter вы используете экземпляр CryptoListAdapter. Если вы хотите использовать CryptoListAdapter в нескольких местах, но с разными макетами элементов, вам нужно измените свой код, чтобы разрешить раздувание разных макетов в onCreateView(), в строке, которую я показал выше.   -  person Mike M.    schedule 03.07.2021
comment
Дааааа... это именно то, что мне нужно... черт... я так сосредоточился на туториале, что не понял этого. Как заставить это работать для любой активности с разными макетами?   -  person Maduro    schedule 03.07.2021
comment
Обычный способ сделать это — добавить параметр конструктора для передачи R.layout и создать для него поле; например, private int layoutResId;, public CryptoListAdapter(List<Datum> data, int layoutResId) { ... this.layoutResId = layoutResId; }. Затем измените вызов inflate, чтобы использовать это поле: ... inflater.inflate(layoutResId, ...);. Подписывайтесь на меня?   -  person Mike M.    schedule 03.07.2021
comment
Jeje так себе... не могли бы вы привести пример. У меня есть идея ... это только то, откуда я буду звонить или передавать layoutId   -  person Maduro    schedule 03.07.2021
comment
Что ж, давайте отступим на секунду, потому что я предположил то, чего не должен был. Мое предложение просто заменить разные макеты будет работать только в том случае, если и crypto_list_item, и crypto_list_item_in_detail_activity имеют View с одинаковыми идентификаторами в каждом. То есть они оба показывают одни и те же данные, просто выглядят по-разному. Это то, что вы хотите сделать? Если так, то это сработает. Если нет, и они должны отображать разные данные в каждом Activity, то похоже, что вам действительно нужны отдельные классы Adapter.   -  person Mike M.    schedule 03.07.2021
comment
Давайте продолжим обсуждение в чате.   -  person Maduro    schedule 03.07.2021


Ответы (1)


это просто и нормально! вы заполняете свой массив в getCoinList(), но устанавливаете адаптер для RecyclerView в initViews(), таким образом, ваш массив еще не заполнен, но вы передаете его своему переработчику! , вы должны сначала получить свой массив, затем передать его адаптеру и установить адаптер в RecyclerView.

person Erfan    schedule 03.07.2021
comment
Когда вы говорите, сначала получите массив... где мне это сделать? потому что я думал, что получение массива в initViews() было получением массива в первую очередь. Не могли бы вы предоставить пример кода, основанный на моих методах. Спасибо, - person Maduro; 03.07.2021
comment
Я удалил recyclerview из onCreate и поставил его на initViews, но все еще говорю: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference - person Maduro; 03.07.2021
comment
Все работает. Спасибо за вашу помощь - person Maduro; 03.07.2021