簡體   English   中英

將 CardView 實現上的 NullPointerException 轉換為 RecycleView

[英]NullPointerException on a CardView implementation into a RecycleView

我正在開發一個我想顯示為 MainView 的應用程序,它包含一個由個性化 CardView 組成的 RecycleView。

我嘗試從代碼中執行此操作,但是當我恢復 CardView 小部件和包含 cardView 的 ImageView 時,總是得到 null 參考 object。

代碼是這樣的

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);
        }
    }
}

xml 文件是這樣的:

<?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>

CardView xml 文件是這樣的:

<?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>

最后,這是我在 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) 

如果您對 Android 的開發有一些經驗,並且您知道或猜到錯誤可能在哪里,請提前感謝!

************************更新*************************** ***

好的,在應用建議 David Velasquez 的更改后,我收到以下錯誤:



     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)
````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````

這個錯誤是指這段代碼:

  @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;
            }
        }
    }
````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````

如您所見,當我嘗試使用畢加索庫加載圖像時會拋出錯誤。

嘗試這個:

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

如果失敗,請嘗試使用 Picasso 庫。 它有助於在 Android 中加載圖像,尤其是在 RecyclerView 中使用時。 然后,您可以執行以下操作:

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

這里還有一些你應該嘗試解決的問題:

  1. 您創建 recyclerView 適配器的方式不正確。 你需要這樣做:

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

    myAdapter應該是您創建的自定義子 class ,而不是RecyclerView.Adapter

  2. 您應該使用LinearLayoutManager而不是RecyclerView.LayoutManager

  3. 一旦您的 for 循環成功break if/else if 塊之一,您應該跳出它,以免繼續做無意義的工作。

  4. 您不應該在循環中的每個 if/else if 塊中調用findViewById() onCreate()開始時進行所有視圖初始化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM