简体   繁体   中英

NullPointerException on a CardView implementation into a RecycleView

I was developing an App which I would like to show as a MainView, which consist in a RecycleView made of personalized CardView's.

I try to do this from code, but when I recover the CardView widget, and the ImageView, which contain the cardView, always get a null reference object.

The code is this

public class MainView extends AppCompatActivity {

    public final int[] SERVICIOS = {R.string.servicioEntrenamiento_titulo, R.string.servicioProfesores_titulo, R.string.servicioReparaciones_titulo, R.string.servicioTransporte_titulo};

    //TODO: IMPLEMENTAR LA VISTA PRINCIPAL, DE LA APP.
    private RecyclerView recyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager layoutManager;
    //TODO: Implementar las cardView del MainView.
    private CardView cardView;
    private ImageView imgCard;
    private TextView txtTituloCard;
    private TextView txtDescCard;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_view);

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

        // use this setting to improve performance if you know that changes
        // in content do not change the layout size of the RecyclerView
        recyclerView.setHasFixedSize(true);

        // use a linear layout manager
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        // specify an adapter (see also next example)
        mAdapter = new MyAdapter(MyAdapter.getmDataset());
        recyclerView.setAdapter(mAdapter);

        //Setup the CardView components.
        //TODO: Solucionar NullPointerException. EL CardView y el ImageView, están a Null haga lo que haga.
        cardView = findViewById(R.id.cv_mainView);
        imgCard = findViewById(R.id.photo_card);


        for (int i = 0; i < SERVICIOS.length; i++) {

            if (SERVICIOS[i] == R.string.servicioReparaciones_titulo) {

                imgCard.setImageResource(R.drawable.reparaciones);
                txtTituloCard = findViewById(R.id.txtTitulo_Card);
                txtTituloCard.setText(R.string.servicioReparaciones_titulo);
                txtDescCard = findViewById(R.id.txtDescripcion_Card);
                txtDescCard.setText(R.string.servicioReparaciones_descripcion);


            } else if (SERVICIOS[i] == R.string.servicioTransporte_titulo) {

                imgCard.setImageResource(R.drawable.transporte);
                txtTituloCard = findViewById(R.id.txtTitulo_Card);
                txtTituloCard.setText(R.string.servicioTransporte_titulo);
                txtDescCard = findViewById(R.id.txtDescripcion_Card);
                txtDescCard.setText(R.string.servicioTransporte_descripcion);
            } else if (SERVICIOS[i] == R.string.servicioProfesores_titulo) {

                imgCard.setImageResource(R.drawable.profesores);
                txtTituloCard = findViewById(R.id.txtTitulo_Card);
                txtTituloCard.setText(R.string.servicioProfesores_titulo);
                txtDescCard = findViewById(R.id.txtDescripcion_Card);
                txtDescCard.setText(R.string.servicioProfesores_descripcion);

            }else if (SERVICIOS[i] == R.string.servicioEntrenamiento_titulo){

                imgCard.setImageResource(R.drawable.entrenadores);
                txtTituloCard = findViewById(R.id.txtTitulo_Card);
                txtTituloCard.setText(R.string.servicioEntrenamiento_titulo);
                txtDescCard = findViewById(R.id.txtDescripcion_Card);
                txtDescCard.setText(R.string.servicioEntrenamiento_descripcion);
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main_menu, menu);
        return true;

    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {


        switch (item.getItemId()) {
            case R.id.item_info:
                Toast miToast = Toast.makeText(getApplicationContext(), "¡Bienvenido a App-Añados!\nGracias a esta App prodrás contratar servicios de manera rápida y segura!", Toast.LENGTH_LONG);
                miToast.setGravity(Gravity.CENTER, 0, 0);
                miToast.show();
                return true;
            case R.id.message_icon:
                Intent miIntent = new Intent(getApplicationContext(), MessageView.class);
                startActivity(miIntent);
                return true;
            case R.id.perfil:
                Intent miIntent2 = new Intent(getApplicationContext(), MainView.class);
                startActivity(miIntent2);
                return true;
            case R.id.item__salir:
                Toast miToast2 = Toast.makeText(getApplicationContext(), "Saliendo de la aplicación", Toast.LENGTH_LONG);
                miToast2.setGravity(Gravity.CENTER, 0, 0);
                miToast2.show();
                System.exit(0);
                return true;
            default:
        return super.onOptionsItemSelected(item);
        }
    }
}

And the xml file is this:

<?xml version="1.0" encoding="utf-8"?>

<androidx.recyclerview.widget.RecyclerView android:id="@+id/recycleViewServicios"
    android:scrollbars="vertical"
    tools:layout_editor_absoluteX="174dp"
    tools:layout_editor_absoluteY="152dp"
    android:background="@drawable/fondo"
    tools:listitem="@layout/card_view_main_view"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    xmlns:tools="http://schemas.android.com/tools">

    </androidx.recyclerview.widget.RecyclerView>

And the CardView xml file is this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:padding="16dp"
    >

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/cv_mainView"
        card_view:cardCornerRadius="12dp"
        card_view:cardElevation="3dp"
        card_view:contentPadding="4dp"
        >

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="16dp"
            >

            <ImageView
                android:id="@+id/photo_card"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:layout_marginRight="16dp"
                />

            <TextView
                android:id="@+id/txtTitulo_Card"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@+id/txtDescripcion_Card"
                android:layout_alignParentTop="true"
                android:textSize="30sp"
                />

            <TextView
                android:id="@+id/txtDescripcion_Card"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@+id/photo_card"
                android:layout_below="@+id/txtTitulo_Card"
                />

        </RelativeLayout>

    </androidx.cardview.widget.CardView>

</LinearLayout>

Finally this is the error which I get on the Logcat:

2020-12-26 15:47:58.667 32725-32725/com.example.apaados E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.apaados, PID: 32725
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.apaados/com.example.apaados.RecycleImplementation.MainView}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageResource(int)' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageResource(int)' on a null object reference
        at com.example.apaados.RecycleImplementation.MainView.onCreate(MainView.java:88)
        at android.app.Activity.performCreate(Activity.java:7802)
        at android.app.Activity.performCreate(Activity.java:7791)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7356) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 

If you have some experience on Android develoment, and you know or guess where can be the error, take thank's for advance!

********************** UPDATE ******************************

Okey, after apply the changes that suggest David Velasquez, I gettiong the following error:



     Caused by: java.lang.IllegalArgumentException: Target must not be null.
        at com.squareup.picasso.RequestCreator.into(RequestCreator.java:682)
        at com.squareup.picasso.RequestCreator.into(RequestCreator.java:665)
        at com.example.apaados.RecycleImplementation.MainView.onCreate(MainView.java:92)
        at android.app.Activity.performCreate(Activity.java:7802)
````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````

This error refere to this piece of code:

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_view);

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

        // use this setting to improve performance if you know that changes
        // in content do not change the layout size of the RecyclerView
        recyclerView.setHasFixedSize(true);

        // use a linear layout manager
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        // specify an adapter (see also next example)
        mAdapter = new MyAdapter(MyAdapter.getmDataset());
        recyclerView.setAdapter(mAdapter);

        //Setup the CardView components.
        //TODO: Solucionar NullPointerException. EL CardView y el ImageView, están a Null haga lo que haga.
        //TODO: Solucionar NullPointerException. EL CardView y el ImageView, están a Null haga lo que haga.
        cardView = findViewById(R.id.cv_mainView);
        imgCard = findViewById(R.id.photo_card);


        for (int i = 0; i < SERVICIOS.length; i++) {

            if (SERVICIOS[i] == R.string.servicioReparaciones_titulo) {
                *******This line is which throw the error******
                Picasso.get().load(R.drawable.reparaciones).fit().into(imgCard);
                //imgCard.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.reparaciones));
                txtTituloCard = findViewById(R.id.txtTitulo_Card);
                txtTituloCard.setText(R.string.servicioReparaciones_titulo);
                txtDescCard = findViewById(R.id.txtDescripcion_Card);
                txtDescCard.setText(R.string.servicioReparaciones_descripcion);

                break;
            } else if (SERVICIOS[i] == R.string.servicioTransporte_titulo) {
                *****This line is which throw the error****
                Picasso.get().load(R.drawable.transporte).fit().into(imgCard);
                //imgCard.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.transporte));
                txtTituloCard = findViewById(R.id.txtTitulo_Card);
                txtTituloCard.setText(R.string.servicioTransporte_titulo);
                txtDescCard = findViewById(R.id.txtDescripcion_Card);
                txtDescCard.setText(R.string.servicioTransporte_descripcion);
                break;
            } else if (SERVICIOS[i] == R.string.servicioProfesores_titulo) {
                *****This line is which throw the error****
                Picasso.get().load(R.drawable.profesores).fit().into(imgCard);
               imgCard.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.profesores));
                txtTituloCard = findViewById(R.id.txtTitulo_Card);
                txtTituloCard.setText(R.string.servicioProfesores_titulo);
                txtDescCard = findViewById(R.id.txtDescripcion_Card);
                txtDescCard.setText(R.string.servicioProfesores_descripcion);
                break;
            }else if (SERVICIOS[i] == R.string.servicioEntrenamiento_titulo){
                *******This line is which throw the error****** 
                Picasso.get().load(R.drawable.entrenadores).fit().into(imgCard);
                //imgCard.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.entrenadores));
                txtTituloCard = findViewById(R.id.txtTitulo_Card);
                txtTituloCard.setText(R.string.servicioEntrenamiento_titulo);
                txtDescCard = findViewById(R.id.txtDescripcion_Card);
                txtDescCard.setText(R.string.servicioEntrenamiento_descripcion);
                break;
            }
        }
    }
````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````

As you can check the error is throw when I try to use the Picasso Library in order to load the images.

Try this:

imgCard.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.some_image));

If that fails try using the Picasso library. It helps with image loading in Android, especially when used in a RecyclerView. You can then do something like:

Picasso.get().load(R.drawable.some_image).fit().into(imgCard);

Also here are a few things you should try resolving:

  1. The way you are creating the recyclerView adapter is incorrect. You need to do this:

     MyAdapter myAdapter = new MyAdapter(MyAdapter.getmDataset());

    myAdapter should be of the custom child class you created, not of RecyclerView.Adapter .

  2. You should be using LinearLayoutManager instead of RecyclerView.LayoutManager

  3. Once your for loop succeeds in entering one of the if/else if blocks, you should break out of it so as not to continue doing meaningless work.

  4. You should not be calling findViewById() in each if/else if block in the loop. Do all your view initialization at the beginning of onCreate() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM