Krøllebølle
Krøllebølle

Reputation: 3028

findViewById returns null for custom ImageView using a handler class

I've read through lots of the threads on findViewById returning null for custom class and I couldn't exactly locate my error. I have a main activity which inflates a Fragment (LinearLayout). I want to populate this LinearLayout with several of my custom ImageViews using a handler. The handler basically creates each of the custom ImageView and puts them into an ArrayList which can be read in the main activity.

In my custom ImageView I have the following constructors:

public CustomView(Context context) {
    super(context);
}
public CustomView(Context context, AttributeSet attrs) {
    super(context, attrs);
}
public CustomView(Context context, int ID, String c, String s, int relID, int relAngle,
        Float absX, Float absY, int [] inNumbers ) {
    super(context);

    this.setId(ID);
    color = c;
    size = s;
    x_pos = absX;
    y_pos = absY;
    dependence = inNumbers;
    rel_id = relID;
    rel_angle = relAngle;
}

Then, in my handler class I do the following:

customViews = new ArrayList<CustomView>();

for ( int k = 0; k < numberOfCustomViews; k++ ){

          CustomView w = new CustomView(ctx,
                  scanner.nextInt(),                    //ID
                  scanner.next(),                       //Color
                  scanner.next(),                       //Size
                  scanner.nextInt(),                    //Relative ID
                  scanner.nextInt(),                    //Relative angle
                  scanner.nextFloat(),                  //Absolute x (percent)
                  scanner.nextFloat(),                  //Absolute y (percent)
                  new int[] {scanner.nextInt(),         //Dependence numbers
                    scanner.nextInt()});

            customViews.add(w);
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                    w.getSizeAsResource(), w.getSizeAsResource());

            w.setLayoutParams(lp);
            Log.d(TAG, "CustomView added!");    
      }

In my main activity I do the following to test if the first CustomView is available:

 customViewTest = (CustomView) (findViewById(customViewHandler.customViews.get(1).getId()));

        if ( customViewTest == null )
            Toast.makeText(this, "customViewTest == null", Toast.LENGTH_LONG).show();

This always shows the toast. What am I missing here? Do I need some inflating or something? It should be possible to add custom views to a layout programatically.

Upvotes: 2

Views: 948

Answers (1)

antonyt
antonyt

Reputation: 21883

It is indeed possible to add views to a layout programmatically, but it seems that you are not actually adding the views to any layout at all. You are simply creating a list of views.

Activity.findViewById will return you a view if there is some view with that particular id contained within its layout. This means that views which are not part of the main view hierarchy, even if they have the correct id, will not be found.

After your 'handler class' executes you end up with a list of orphaned views, that is, they do not have a parent view, and in particular, they are not part of the layout of the activity.

Given that you want to use them in fragments, it does not make sense to add them to the main layout of the activity directly. One of the benefits of fragments is that you can manage smaller groups of related views. You should be adding your custom views to the view of the fragment where it is to be used. You can pass the parameters required into the fragment and let it construct these views.

Upvotes: 2

Related Questions