MLQ
MLQ

Reputation: 13511

Why do I keep getting a null reference to my LinearLayout?

I have a layout called view.xml which contains a View called view_related. Basically, in my dictionary app, if there are related words to an entry, I will replace view_related with a LinearLayout that contains a header "Related entries" and a bunch of TextViews representing every related word.

I keep getting a NullPointerException everytime I'm adding a TextView to the LinearLayout in my Activity's onCreate() method, and I don't understand why though my code looks pretty straightforward.

view.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView android:id="@+id/view_header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="12pt"
        android:textColor="#fff"
        android:textStyle="bold"
        android:background="#990011"
        android:padding="10dp"
        android:text="lalala word"
        />

    <ScrollView android:id="@+id/view_description"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/view_header">
        <LinearLayout android:id="@+id/view_description_content"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <TextView android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="@string/demo_definition"
                />
                <!-- THIS WILL BE REPLACED -->
            <View android:id="@+id/view_related"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"></View>
        </LinearLayout>
    </ScrollView>

</RelativeLayout>

view_related.xml, the LinearLayout that will replace the View element in view.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/view_related_entries"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <TextView android:id="@+id/view_related_header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:textColor="#fff"
        android:textStyle="bold"
        android:textSize="7pt"
        android:background="#000"
        android:text="Related entries"
        />
    <LinearLayout android:id="@+id/view_related_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
    </LinearLayout>
</LinearLayout>

And finally, the onCreate method, which for now assumes the related entries are "Hello" and "Goodbye:"

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.view);

    LinearLayout ll = (LinearLayout) findViewById(R.id.view_related_list);
    TextView tv = new TextView(this);
    tv.setText("Hello");
    ll.addView(tv); // NULL POINTER EXCEPTION

    tv = new TextView(this);
    tv.setText("Goodbye");
    ll.addView(tv);

    LayoutInflater li = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    View view = findViewById(R.id.view_related);
    ViewGroup parent = (ViewGroup) view.getParent();
    int index = parent.indexOfChild(view);
    parent.removeView(view);
    View llview = li.inflate(R.id.view_related_entries, parent, false);
    parent.addView(llview, index);
}

Upvotes: 1

Views: 2861

Answers (5)

user
user

Reputation: 87064

You're doing a lot of wrong things in your code. First you search for a LinearLayout that isn't in the current layout and also isn't in any inflated layout at that moment. Second, you try to inflate an id reference instead of a layout reference. Last, you should use another approach for what you're trying to do. Your code should be(from what I understood):

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.view);   

    LayoutInflater li = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    View view = findViewById(R.id.view_related);
    ViewGroup parent = (ViewGroup) view.getParent();
    int index = parent.indexOfChild(view);
    parent.removeView(view);
    View llview = li.inflate(R.layout.view_related, parent, false); // is view_related the name of the extra layout file?
    parent.addView(llview, index);
    LinearLayout ll = (LinearLayout) findViewById(R.id.view_related_list); // or search for it in llview, llview.findViewById(R.id.view_related_list);
    TextView tv = new TextView(this);
    tv.setText("Hello");
    ll.addView(tv); // NULL POINTER EXCEPTION

    tv = new TextView(this);
    tv.setText("Goodbye");
    ll.addView(tv);
}

This is a situation when you should use a ViewStub to add the new layout file. Although, I don't understand why don't you add the new layout file directly in the view.xml if you're going to add the layout's content in the onCreate method.

Upvotes: 1

Abdul Wahab
Abdul Wahab

Reputation: 819

You may forgetting to declare your Activity in manifest.xml

Upvotes: -1

Nanne
Nanne

Reputation: 64399

setContentView(R.layout.view);
LinearLayout ll = (LinearLayout) findViewById(R.id.view_related_list);

The function findViewById only finds views that are actually set. Your current setContentView does not set an xml that has the id you are looking for in it, so the first line I quoted will not result in anything.

You should either load the correct XML, or inflate the view you are looking for with an inflater

Upvotes: 2

Nermeen
Nermeen

Reputation: 15973

the line (LinearLayout ll = (LinearLayout) findViewById(R.id.view_related_list);) will search for view_related_list in view.xml, as in the line before that is the view you are using..

You need to inflate view_related.xml first and then get the view from it..

Upvotes: 1

G_S
G_S

Reputation: 7110

i think you need to use setContentView(R.layout.view_related); instead of setContentView(R.layout.view);

or another simple thing you can do is take the linear layout in the same layout "view" and make it invisible when not required and visible when required

Upvotes: 0

Related Questions