Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

findViewById returns null in custom View after inflate

I have a custom RelativeLayout and I inflate an xml res file in it. This works fine if I use the custom layout in an xml file and set it as contentview, but if I try to add it in the code with new LocationItem(this) and addChild() the findViewById method always returns null in the constructor of the custom RelativeLayout.

Here is the code:

public class LocationItem extends RelativeLayout {

private String parcelType;
private int countIntoBox, countFromBox;

private RelativeLayout deliveryContainer, pickupContainer;

private TextView countPickup, countDelivery;

public LocationItem(Context context) {
    this(context, null);
}

public LocationItem(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public LocationItem(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    inflate(getContext(), R.layout.list_item_location, this);
    deliveryContainer = (RelativeLayout) findViewById(R.id.rl_location_delivery_container);
    pickupContainer = (RelativeLayout) findViewById(R.id.rl_location_pickup_container);
    countPickup = (TextView) findViewById(R.id.tv_location_pickup_count);
    countDelivery = (TextView) findViewById(R.id.tv_location_delivery_count);

    countPickup.setOnClickListener(getShowNumberPickerListener());
    countDelivery.setOnClickListener(getShowNumberPickerListener());
}

private OnClickListener getShowNumberPickerListener() {
    return new OnClickListener() {
        @Override
        public void onClick(View view) {
            showNumberPickerDialog(view);
        }
    };
} ...
}

Add custom view in activity

mRootLayoutLocations.addView(new LocationItem(this));

The view is inflated correctly, because I can see it, but when I try to access a view inside the custom view the app crashes with a NullPointerException.

like image 634
Fabian Avatar asked Oct 20 '22 12:10

Fabian


2 Answers

Ok i inflated the view into a View(holder)

View v = inflate(getContext(), R.layout.list_item_location, this); 

and then access the views via v.findViewById. Now it's working.

Code:

View v = inflate(getContext(), R.layout.list_item_location, this);
deliveryContainer = (RelativeLayout) v.findViewById(R.id.rl_location_delivery_container);
pickupContainer = (RelativeLayout) v.findViewById(R.id.rl_location_pickup_container);
countPickup = (TextView) v.findViewById(R.id.tv_location_pickup_count);
countDelivery = (TextView) v.findViewById(R.id.tv_location_delivery_count);

countPickup.setOnClickListener(getShowNumberPickerListener());
countDelivery.setOnClickListener(getShowNumberPickerListener());
like image 123
Fabian Avatar answered Oct 22 '22 04:10

Fabian


You need to be using appropriate constructors, not overloading them.

public class LocationItem extends RelativeLayout {

    private String parcelType;
    private int countIntoBox, countFromBox;

    private RelativeLayout deliveryContainer, pickupContainer;

    private TextView countPickup, countDelivery;

    public LocationItem(Context context) {
        super(context);
        init(context, null, 0);
    }

    public LocationItem(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public LocationItem(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        inflate(getContext(), R.layout.list_item_location, this);
        deliveryContainer = (RelativeLayout) findViewById(R.id.rl_location_delivery_container);
        pickupContainer = (RelativeLayout) findViewById(R.id.rl_location_pickup_container);
        countPickup = (TextView) findViewById(R.id.tv_location_pickup_count);
        countDelivery = (TextView) findViewById(R.id.tv_location_delivery_count);

        countPickup.setOnClickListener(getShowNumberPickerListener());
        countDelivery.setOnClickListener(getShowNumberPickerListener());
    }

    private OnClickListener getShowNumberPickerListener() {
        return new OnClickListener() {
            @Override
            public void onClick(View view) {
                showNumberPickerDialog(view);
            }
        };
    }

    ...
}
like image 24
Bojan Kseneman Avatar answered Oct 22 '22 03:10

Bojan Kseneman