简体   繁体   中英

Why does findViewById returns null for CardView?

Would somebody explain why I'm getting an NPE for my cardView? It makes no sense to me. Here's all relevant code and stack trace:

ACTIVITY hosting the CardView

public class MainScreen extends AppCompatActivity implements TipView.OnValueChangedListener 
{ 

 private TipView tipView;

 private CardView cardView;

 private TextView tipTextView;
 private TextView taxTextView;
 private TextView splitTextView;
 private TextView productTextView;
 private TextView totalTextView;

 private TextView youPayEachPay;


 private ImageButton productEditButton;
 private ImageButton dataToggle;

 private ProductTotalWindow productTotalWindow;



 private double productTotal = 0.0d;

 private double currentTip = 0.0d;
 private double currentTax = 0.0d;
 private int currentSplit = 1;


 private NumberFormat currencyFormat;


 private String pricesDefaults = "$0.00";

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


    cardView = (CardView) findViewById(R.id.tipViewCardLayoutContainer).findViewById(R.id.cardViewId);

  //NPE is thrown since, obviously the reference points to a null object
  cardView.setCardBackgroundColor(Color.RED);


    this.tipView = (TipView) findViewById(R.id.tipView);
         tipView.setOnValueChangedListener(this);



    dataToggle = (ImageButton) findViewById(R.id.dataToggle);
    dataToggle.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            expandLayout();
        }
    });



    initDataPricesViews();

    initProductEditView();

    currencyFormat = NumberFormat.getCurrencyInstance();

  }

}

XML code for the main layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main_screen"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.bryan.tipease.MainScreen">


   <!--
     tipview_card_container is the layout hosting my cardview
    -->
<include
    layout="@layout/tipview_card_container"
    android:id="@id/tipViewCardLayoutContainer" />




<FrameLayout
    android:layout_alignParentBottom="true"
    android:layout_below="@id/tipViewCardLayoutContainer"
    android:id="@id/pricesTotalContainer"

    android:layout_width="match_parent"
    android:layout_height="match_parent">


<include layout="@layout/prices_layout" />

</FrameLayout>



</RelativeLayout>



//The cards xml file itself

 <?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"

    android:layout_width="match_parent"
    android:layout_height="wrap_content"

    android:id="@id/cardViewId"

    app:contentPadding="16dp"
    app:cardElevation="16dp"
    app:cardBackgroundColor="@color/tipViewCardBackground">


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

        <com.example.bryan.tipease.TipView
            style="@style/WidgetTipViewStyle"

            android:id="@id/tipView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />



    <ImageButton
        style="@style/BreakerBarContent"
        android:src="@drawable/forkknifefab"
        android:id="@id/productDialogLauncher"
        android:contentDescription="@string/contentDescForkKnifeImage"

        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />


    <ImageButton
        style="@style/BreakerBarContent"
        android:src="@drawable/toggle_circle"
        android:id="@id/dataToggle"
        android:contentDescription="@string/contentDescDataToggleImage"

        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"

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

  </android.support.v7.widget.CardView>

Stacktrace

02-23 21:06:55.548 26169-26169/? E/AndroidRuntime: FATAL EXCEPTION: main
                                               Process:  com.example.bryan.tipease, PID: 26169
                                                java.lang.RuntimeException:  Unable to start activity   ComponentInfo{com.example.bryan.tipease/com.example.bryan.tipease.MainScreen}:  java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.CardView.setCardBackgroundColor(int)' on a null object reference
                                                   at  android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2378)
                                                   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2440)
                                                   at android.app.ActivityThread.access$800(ActivityThread.java:162)
                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1348)
                                                   at android.os.Handler.dispatchMessage(Handler.java:102)
                                                   at android.os.Looper.loop(Looper.java:135)
                                                   at android.app.ActivityThread.main(ActivityThread.java:5422)
                                                   at java.lang.reflect.Method.invoke(Native Method)
                                                   at java.lang.reflect.Method.invoke(Method.java:372)
                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:914)
                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)
                                                Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.CardView.setCardBackgroundColor(int)' on a null object reference
                                                   at com.example.bryan.tipease.MainScreen.onCreate(MainScreen.java:62)
                                                   at android.app.Activity.performCreate(Activity.java:6056)
                                                   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
                                                   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2331)
                                                   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2440) 
                                                   at android.app.ActivityThread.access$800(ActivityThread.java:162) 
                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1348) 
                                                   at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                   at android.os.Looper.loop(Looper.java:135) 
                                                   at android.app.ActivityThread.main(ActivityThread.java:5422) 
                                                   at java.lang.reflect.Method.invoke(Native Method) 
                                                   at java.lang.reflect.Method.invoke(Method.java:372) 
                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:914) 
                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707) 

This is a weird issue that I've been able to recreate only once. I assumed the problem was with how I was referencing the cardview, with regards to the use of an include tag, however creating a test app to see if I can recreate this problem, there was no issue with my references.

PS I've omitted some methods from the activity for sake of brevity, but believe me they're irrelevant to the cause of my issue here. PSS I can reference any other view in that hierarchy just fine.

As @Mike M. mentioned above in the comments.

First

You do not need to chain your findViewById() 's like you did here:

cardView = (CardView) findViewById(R.id.tipViewCardLayoutContainer).findViewById(R.id.cardViewId); .

The View hierarchy will be searched from the top-down. This means you should search for the android:id="@+id that you want, rather than chaining them.

Second

The id android:id="@id/tipViewCardLayoutContainer" in your <include> overrides the id of your root View , this means your CardView now has the id of tipViewCardLayoutContainer instead of android:id="@id/cardViewId" .

All you need to do is remove the id from your <include> and call

CardView cardview = (CardView) findViewById(R.id.cardViewId);

i think id should use +id like this.hope this can help you.

<include
layout="@layout/tipview_card_container"
android:id="@+id/tipViewCardLayoutContainer" />

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