Recyclerview does not display data

Asked

Viewed 57 times

-2

I have a problem where Recyclerview does not render on Activity. Textviews load normally.

In the Emulator I use level 24 or 30 Apis and physical applications.

This appearing this way, the Recycler is just below the Textview 'Customer Portal':

inserir a descrição da imagem aqui

I have tried to revise with Debugger but no error. I checked Adapter on Activity and it is receiving and processing normal data. Data is rarely rendered but still is, even with minimal frequency of success.

Follow the codes:

Thanks in advance !

Adapter:

public class AdapterBrand extends RecyclerView.Adapter<HolderBrand> {

    private static final String TAG = "Adapter Brand";
    //private static final RecyclerView.RecycledViewPool sharedPool = new RecyclerView.RecycledViewPool();

    private final ArrayList<Brand> mArr;
    private final Context context;

    public AdapterBrand(Context context, ArrayList<Brand> mArr) {
        this.context = context;
        this.mArr = mArr;
    }

    @NonNull
    @Override
    public HolderBrand onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new HolderBrand(LayoutInflater.from(context).inflate(R.layout.item_brand_grid, parent, false));

    }

    @Override
    public void onBindViewHolder(@NonNull HolderBrand holder, int position) {
        
        final String brandImage;
        try {

            

                brandImage = mArr.get(position).getImagem();
                holder.onBind(brandImage, holder);

            

        } catch (Exception ex){
            Log.e(TAG, "onBindViewHolder: ", ex);
        }
    }

    @Override
    public int getItemCount() {
        return mArr == null ? 1 : mArr.size();
    }

}

Holder:

public class HolderBrand  extends RecyclerView.ViewHolder {

    private static final String TAG = "Holder Brand";
    private final ImageButton imageButton;

    public HolderBrand(@NonNull View itemView) {
        super(itemView);
        imageButton = itemView.findViewById(R.id.image_title_button_grid);

    }

    public void onBind(String brandImage, HolderBrand holder){

        Picasso.get()
                .load(brandImage)
                .fit()
                .into((ImageButton) holder.imageButton);
    }


}

Activity:

public class ListUsersActivity extends AppCompatActivity  {
    private static final String TAG =  "List Users Activity";

    private ListUsersActivity listUsersActivity;

    public ArrayList<Brand> arrayList;
    public ArrayAdapter<Brand> arrayAdapter;
    private RecyclerView brandList;


    @SuppressLint("SetTextI18n")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list_users);

        Intent intent = getIntent();
        String text = intent.getStringExtra(MainActivity.Texto_extra);

        //Recebe o texto do campo email para as boas vindas no txtVwEmailFromActv1.
        TextView emailTxt1 = findViewById(R.id.txtVwEmailFromActv1);
        emailTxt1.setText("Bem vindo " + "\r\n" + text);

        brandList = (RecyclerView) findViewById(R.id.recyclerView);

        try {
            listUsersActivity = this;

            setComponents();
            new apiAcess(this).getBrands();

        } catch (Exception ex){
            Log.e(TAG, "onCreate: ", ex);
        }



    }


    private void setComponents(){

        arrayList  = new ArrayList<>();
        arrayAdapter  = new ArrayAdapter<>(this, R.layout.item_brand_grid, arrayList);
        brandList.setAdapter(new AdapterBrand(this, arrayList));
        GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3);
        gridLayoutManager.setInitialPrefetchItemCount(3);
        Log.d(TAG, "InitialPrefetchItemCount iniciado");
        brandList.setLayoutManager(gridLayoutManager);
        //AdapterBrand.brandLayoutMg(brandList, gridLayoutManager);
    }
}

Layout Recycler:

<?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"
    android:orientation="vertical">


    <TextView
        android:id="@+id/txtVwEmailFromActv1"
        android:layout_width="0dp"
        android:layout_height="74dp"
        android:layout_marginBottom="15dp"
        android:text="@string/activity_2"
        android:textAlignment="center"
        android:textColor="#171616"
        android:textSize="24sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toTopOf="@+id/presenter1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="MissingConstraints" />


    <TextView
        android:id="@+id/presenter1"
        android:layout_width="0dp"
        android:layout_height="40dp"
        android:layout_marginTop="15dp"
        android:text="@string/presenterBrands"
        android:textAlignment="center"
        android:textColor="#171616"
        android:textSize="24sp"
        android:textStyle="bold|italic"
        app:layout_constraintBottom_toTopOf="@+id/recyclerView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/txtVwEmailFromActv1"
        tools:ignore="MissingConstraints" />

    <androidx.recyclerview.widget.RecyclerView

        android:id="@+id/recyclerView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:visibility="invisible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/presenter1"
        tools:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
        tools:listitem="@layout/item_brand_grid"
        tools:spanCount="3" />


</androidx.constraintlayout.widget.ConstraintLayout>

Item layout:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/cardView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent">


        <ImageButton
            android:id="@+id/image_title_button_grid"
            android:layout_width="123dp"
            android:layout_height="96dp"
            android:layout_margin="8dp"
            android:clickable="true"
            android:contentDescription="@string/brandlogo"
            android:contextClickable="true"
            android:focusable="true"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.078"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.454"
            tools:srcCompat="@tools:sample/avatars[3]" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

apiAcess:

public class apiAcess {

    private static final String TAG = "apiAcess";

    private final ListUsersActivity lActivity;

    public apiAcess(ListUsersActivity lActivity) {
        this.lActivity = lActivity;
    }

    public void getBrands(){
        try {
            TaskManager.getINSTANCE().createTask(() -> {
                try {
                    final api getBrand = brandJson.createService(api.class);

                    String jsonFile = "http://" + BuildConfig.URL_BRANDS_JSON;

                    Call<ResponseBody> callApi = getBrand.getAllBrands(jsonFile);

                    callApi.enqueue(new Callback<ResponseBody>() {
                        @Override
                        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                            if (response.isSuccessful()) {
                                try {
                                    TaskManager.getINSTANCE().createTask(() -> {
                                        try {
                                            String responseBd = response.body().string();
                                            Portais n = new Gson().fromJson(responseBd, Portais.class);

                                            Log.d(TAG, "onResponse: Portais: " + n.getPortais());;
                                            //aqui é onde todos os valores do arquivo .json são recebidos em formato de array de objetos
                                            lActivity.runOnUiThread(() -> {
                                                lActivity.arrayList.addAll(n.getPortais());
                                                lActivity.arrayAdapter.notifyDataSetChanged();
                                            });


                                        } catch (Exception ex) {
                                            Log.e(TAG, "onResponse: ", ex);
                                        }
                                    });
                                } catch (Exception ex) {
                                    Log.e(TAG, "createTask: ", ex);
                                }

                            }

                        }

                        @Override
                        public void onFailure(Call<ResponseBody> call, Throwable t) {
                            Log.e(TAG, "onFailure: ", t);
                        }
                    });

                } catch (Exception ex) {
                    Log.e(TAG, "TaskManager: ", ex);
                }


            });

        }catch (Exception ex){
            Log.e(TAG, "getBrands: ", ex);
        }

    }

}

2 answers

0

Oops, Philip speaks! All good?

Dude, looking at your code... I couldn’t find the moment you populated the Adapter array.
I see you send him an empty list:

arrayList  = new ArrayList<>();
arrayAdapter  = new ArrayAdapter<>(this, R.layout.item_brand_grid, arrayList);
brandList.setAdapter(new AdapterBrand(this, arrayList));

But I haven’t found anywhere the moment you submit the new object list Brand pro Adapter.

Does it have to do with this line here that assigns no value to any variable?

   new apiAcess(this).getBrands();

Try to create a function to submit the new list pro Adapter and then run a notifyDatasetChanged() to render your recyclerView items again.

For example (inside your Adapter):

public void submitList(List<Brand> brandList) {
  mArr = brandList;
  notifyDatasetChanged();
}

But I strongly advise you to research on Recyclerview and Diffutils to understand a little better.

Hope I helped, hugs!

EDIT:

Now with the file apiAccess got better to understand. Dude, I wouldn’t advise you to reference Activity to your API layer. Take a look at this link, it teaches the popular a view Recycler using good practices.

Maaas, by solving your problem directly, you are populating the variable referring to Activity and not Adapter. What should be modified is the mArr that’s inside the Adapter.

lActivity.arrayList.addAll(n.getPortais());
lActivity.arrayAdapter.notifyDataSetChanged();

Then, following your implementation logic, you would have to do 2 functions in Activity:

  • A function to initialize Adapter and recyclerview (basically setcomponents);
  • And another function to send the list you received from the api. Basically a lActivity.submitList(n.getPortais()). This is the function that will be in Activity and that will bridge to Adapter.
    Since it is an asynchronous process, there must be such a function (as if it were a callback function) to perform the change in Activity. Otherwise, you will not be able to predict when the list arrives from the request to popular power your Adapter ;)

0


The error itself was the Activity setComponents method

was replaced:

arrayAdapter  = new ArrayAdapter<>(this, R.layout.item_brand_grid, arrayList);
brandList.setAdapter(new AdapterBrand(this, arrayList));

for:

    arrayAdapter  = new AdapterBrand(this, arrayList);
    brandList.setAdapter(arrayAdapter);

The model-type Adapter was not being used, as another empty was being declared before. After changing and instantiating only in arrayAdapter, it worked on devices and emulator.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.