找到你要的答案

Q:findViewById returns null in custom View after inflate

Q:findViewById返回自定义视图无效后的膨胀

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.

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.

这里是代码:

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);
        }
    };
} ...
}

在活动中添加自定义视图

mRootLayoutLocations.addView(new LocationItem(this));

视图是膨胀的正确,因为我可以看到它,但是当我尝试进入自定义视图与视图的应用程序崩溃时。

answer1: 回答1:

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());

好的,我把视图放大到视图(持有者)

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

然后访问视图通过v.findviewbyid。现在它的工作。

代码:

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());
answer2: 回答2:

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);
            }
        };
    }

    ...
}

您需要使用适当的构造函数,而不是重载它们。

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);
            }
        };
    }

    ...
}
answer3: 回答3:

I fear you must inflate the view instead of finding it from nowhere. The method

findindViewById(int Id)

must be called within the Actvity's onCreate or with a view within which the child view/widget you are trying to find is resides in.

If all of the child views resides in a single xml file(within single parent root)

View rootView=(View) LayoutInflater.from(context).inflate(R.layout.list_item_location);
pickupContainer = (RelativeLayout) rootview.findViewById(R.id.rl_location_pickup_container);

我担心你必须夸大观点,而不是找不到它。的方法

findindViewById(int Id)

必须在活动的OnCreate或视图的子视图/部件你需要找到的是居住在被称为。

如果所有子视图驻留在单个XML文件中(父根内)

View rootView=(View) LayoutInflater.from(context).inflate(R.layout.list_item_location);
pickupContainer = (RelativeLayout) rootview.findViewById(R.id.rl_location_pickup_container);
answer4: 回答4:

this should work

public LocationItem(Context context, AttributeSet attrs, int defStyle) {
   super(context, attrs, defStyle);
   this = inflate(getContext(), R.layout.list_item_location,null);
   ...

这应该工作

public LocationItem(Context context, AttributeSet attrs, int defStyle) {
   super(context, attrs, defStyle);
   this = inflate(getContext(), R.layout.list_item_location,null);
   ...
android  android-layout  nullpointerexception  android-custom-view  layout-inflater