为什么 CardView 的 findViewById 返回 null?

who*_*pum 1 android nullpointerexception android-cardview

有人能解释一下为什么我的cardView 得到了NPE 吗?对我来说完全是无稽之谈。这是所有相关代码和堆栈跟踪:

\n\n

托管 CardView 的活动

\n\n
public class MainScreen extends AppCompatActivity implements TipView.OnValueChangedListener \n{ \n\n private TipView tipView;\n\n private CardView cardView;\n\n private TextView tipTextView;\n private TextView taxTextView;\n private TextView splitTextView;\n private TextView productTextView;\n private TextView totalTextView;\n\n private TextView youPayEachPay;\n\n\n private ImageButton productEditButton;\n private ImageButton dataToggle;\n\n private ProductTotalWindow productTotalWindow;\n\n\n\n private double productTotal = 0.0d;\n\n private double currentTip = 0.0d;\n private double currentTax = 0.0d;\n private int currentSplit = 1;\n\n\n private NumberFormat currencyFormat;\n\n\n private String pricesDefaults = "$0.00";\n\n @Override\n protected void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    setContentView(R.layout.activity_main_screen);\n\n\n    cardView = (CardView) findViewById(R.id.tipViewCardLayoutContainer).findViewById(R.id.cardViewId);\n\n  //NPE is thrown since, obviously the reference points to a null object\n  cardView.setCardBackgroundColor(Color.RED);\n\n\n    this.tipView = (TipView) findViewById(R.id.tipView);\n         tipView.setOnValueChangedListener(this);\n\n\n\n    dataToggle = (ImageButton) findViewById(R.id.dataToggle);\n    dataToggle.setOnClickListener(new View.OnClickListener() {\n        @Override\n        public void onClick(View v) {\n            expandLayout();\n        }\n    });\n\n\n\n    initDataPricesViews();\n\n    initProductEditView();\n\n    currencyFormat = NumberFormat.getCurrencyInstance();\n\n  }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

主布局的 XML 代码

\n\n
<?xml version="1.0" encoding="utf-8"?>\n<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"\n    xmlns:tools="http://schemas.android.com/tools"\n    android:id="@+id/activity_main_screen"\n    android:layout_width="match_parent"\n    android:layout_height="match_parent"\n    tools:context="com.example.bryan.tipease.MainScreen">\n\n\n   <!--\n     tipview_card_container is the layout hosting my cardview\n    -->\n<include\n    layout="@layout/tipview_card_container"\n    android:id="@id/tipViewCardLayoutContainer" />\n\n\n\n\n<FrameLayout\n    android:layout_alignParentBottom="true"\n    android:layout_below="@id/tipViewCardLayoutContainer"\n    android:id="@id/pricesTotalContainer"\n\n    android:layout_width="match_parent"\n    android:layout_height="match_parent">\n\n\n<include layout="@layout/prices_layout" />\n\n</FrameLayout>\n\n\n\n</RelativeLayout>\n\n\n\n//The cards xml file itself\n\n <?xml version="1.0" encoding="utf-8"?>\n<android.support.v7.widget.CardView\n    xmlns:android="http://schemas.android.com/apk/res/android"\n    xmlns:app="http://schemas.android.com/apk/res-auto"\n\n    android:layout_width="match_parent"\n    android:layout_height="wrap_content"\n\n    android:id="@id/cardViewId"\n\n    app:contentPadding="16dp"\n    app:cardElevation="16dp"\n    app:cardBackgroundColor="@color/tipViewCardBackground">\n\n\n    <RelativeLayout\n        android:layout_width="match_parent"\n        android:layout_height="wrap_content">\n\n        <com.example.bryan.tipease.TipView\n            style="@style/WidgetTipViewStyle"\n\n            android:id="@id/tipView"\n            android:layout_width="wrap_content"\n            android:layout_height="wrap_content" />\n\n\n\n    <ImageButton\n        style="@style/BreakerBarContent"\n        android:src="@drawable/forkknifefab"\n        android:id="@id/productDialogLauncher"\n        android:contentDescription="@string/contentDescForkKnifeImage"\n\n        android:layout_width="wrap_content"\n        android:layout_height="wrap_content" />\n\n\n    <ImageButton\n        style="@style/BreakerBarContent"\n        android:src="@drawable/toggle_circle"\n        android:id="@id/dataToggle"\n        android:contentDescription="@string/contentDescDataToggleImage"\n\n        android:layout_alignParentRight="true"\n        android:layout_alignParentEnd="true"\n\n        android:layout_width="wrap_content"\n        android:layout_height="wrap_content" />\n</RelativeLayout>\n\n  </android.support.v7.widget.CardView>\n
Run Code Online (Sandbox Code Playgroud)\n\n

堆栈跟踪

\n\n
02-23 21:06:55.548 26169-26169/? E/AndroidRuntime: FATAL EXCEPTION: main\n                                               Process:  com.example.bryan.tipease, PID: 26169\n                                                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\n                                                   at  android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2378)\n                                                   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2440)\n                                                   at android.app.ActivityThread.access$800(ActivityThread.java:162)\n                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1348)\n                                                   at android.os.Handler.dispatchMessage(Handler.java:102)\n                                                   at android.os.Looper.loop(Looper.java:135)\n                                                   at android.app.ActivityThread.main(ActivityThread.java:5422)\n                                                   at java.lang.reflect.Method.invoke(Native Method)\n                                                   at java.lang.reflect.Method.invoke(Method.java:372)\n                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:914)\n                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)\n                                                Caused by: java.lang.NullPointerException: Attempt to invoke virtual method \'void android.support.v7.widget.CardView.setCardBackgroundColor(int)\' on a null object reference\n                                                   at com.example.bryan.tipease.MainScreen.onCreate(MainScreen.java:62)\n                                                   at android.app.Activity.performCreate(Activity.java:6056)\n                                                   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)\n                                                   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2331)\n                                                   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2440)\xc2\xa0\n                                                   at android.app.ActivityThread.access$800(ActivityThread.java:162)\xc2\xa0\n                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1348)\xc2\xa0\n                                                   at android.os.Handler.dispatchMessage(Handler.java:102)\xc2\xa0\n                                                   at android.os.Looper.loop(Looper.java:135)\xc2\xa0\n                                                   at android.app.ActivityThread.main(ActivityThread.java:5422)\xc2\xa0\n                                                   at java.lang.reflect.Method.invoke(Native Method)\xc2\xa0\n                                                   at java.lang.reflect.Method.invoke(Method.java:372)\xc2\xa0\n                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:914)\xc2\xa0\n                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)\xc2\xa0\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是一个奇怪的问题,我只能重现一次。我认为问题出在我如何引用cardview,关于包含标签的使用,但是创建一个测试应用程序来看看我是否可以重现这个问题,我的引用没有问题。

\n\n

PS 为了简洁起见,我在活动中省略了一些方法,但相信我,它们与我的问题的原因无关。\nP.SS 我可以很好地引用该层次结构中的任何其他视图。

\n

Dre*_*rko 5

正如@Mike M.上面评论中提到的。

第一的

您不需要findViewById()像这里那样链接您的 :

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

View将从上到下的层次结构进行搜索。这意味着您应该搜索android:id="@+id您想要的内容,而不是链接它们。

第二

id android:id="@id/tipViewCardLayoutContainer"你的 in会<include>覆盖id你的 root 的View,这意味着你CardView现在有idoftipViewCardLayoutContainer而不是android:id="@id/cardViewId"

您所需要做的就是id从您的中删除<include>并致电

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