Reputation: 69
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.
P.S. 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. P.S.S. I can reference any other view in that hierarchy just fine.
Upvotes: 1
Views: 3115
Reputation: 11
i think id should use +id like this.hope this can help you.
<include
layout="@layout/tipview_card_container"
android:id="@+id/tipViewCardLayoutContainer" />
Upvotes: 0
Reputation: 1621
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);
Upvotes: 5