title: android custom layout parameters ClassCastException and what about the View?
body: <p>Okay, here is what I am doing... I have two custom layouts:</p>
  
  <pre><code>HandedLayout extends ViewGroup
  </code></pre>
  
  <p>and</p>
  
  <pre><code>HandedPathLayout extends HandedLayout
  </code></pre>
  
  <p>So in the root layout, I have a custom LayoutParameters to accept a layout property, called handed.  Here is the Layout Parameters class in </p>
  
  <pre><code>    public static class LayoutParams extends ViewGroup.LayoutParams {
      public int handed;
      public LayoutParams(Context c, AttributeSet attrs) {
          super(c, attrs);
          TypedArray a =
                  c.obtainStyledAttributes(attrs, R.styleable.HandedLayout_LayoutParams);
          handed = a.getInt(R.styleable.HandedLayout_LayoutParams_layout_handed,
                  HandedLayout.RIGHT_HANDED);
          a.recycle();
      }
      public LayoutParams(int width, int height) {
          super(width, height);
      }
  }
  </code></pre>
  
  <p>And as I understand it (shakily, it seems), I also need to override 3 classes in HandedLayout.  Here they are:</p>
  
  <pre><code>@Override
      public HandedLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {
          return new HandedLayout.LayoutParams(getContext(), attrs);
  
      }
  
      @Override
      protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
          return p instanceof LayoutParams;
      }
  
      @Override
      protected HandedLayout.LayoutParams generateDefaultLayoutParams() {
          return new HandedLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
      }
  </code></pre>
  
  <p>So in the inner custom layout (HandedPathLayout), I need lots of layout parameters, so I do the exact same thing!  Here is the LayoutParameters class inside of HandedPathLayout:</p>
  
  <pre><code>public static class LayoutParams extends HandedLayout.LayoutParams {
  
      public int[] endSides;
      public int[] endPositions;
      public int[] anchorSides;
      public int[] anchorPositions;
      public int controlPointDistance;
  
      public LayoutParams(int width, int height) {
          super(width, height);
      }
  
      public LayoutParams(Context context, AttributeSet attrs) {
          super(context, attrs);
  
          endSides = new int[2];
          endPositions = new int[2];
          anchorSides = new int[2];
          anchorPositions = new int[2];
  
          TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HandedPathLayout_LayoutParams);;
          try {
              //this is the second place that the default handedness is set, watch out!
              //handed = a.getInteger(R.styleable.HandedLayout_LayoutParams_layout_handed, HandedLayout.RIGHT_HANDED);
              endSides[0] = a.getInteger(R.styleable.HandedPathLayout_LayoutParams_layout_from_side, HandedLayout.BOTTOM_SIDE);
              endSides[1] = a.getInteger(R.styleable.HandedPathLayout_LayoutParams_layout_to_side, HandedLayout.PINKIE_SIDE);
              endPositions[0] = a.getDimensionPixelSize(R.styleable.HandedPathLayout_LayoutParams_layout_from_position, 0);
              endPositions[1] = a.getDimensionPixelSize(R.styleable.HandedPathLayout_LayoutParams_layout_to_position, 0);
              anchorSides[0] = a.getInteger(R.styleable.HandedPathLayout_LayoutParams_layout_anchor_up_side, HandedLayout.TOP_SIDE);
              anchorSides[1] = a.getInteger(R.styleable.HandedPathLayout_LayoutParams_layout_anchor_down_side, HandedLayout.BOTTOM_SIDE);
              //todo: should these positions be set relative to handedness?  which direction is zero?
              anchorPositions[0] = a.getDimensionPixelSize(R.styleable.HandedPathLayout_LayoutParams_layout_anchor_up_position, 0);
              anchorPositions[1] = a.getDimensionPixelSize(R.styleable.HandedPathLayout_LayoutParams_layout_anchor_down_position, 0);
              controlPointDistance = a.getInteger(R.styleable.HandedPathLayout_LayoutParams_layout_control_point_position, HandedLayout.BOTTOM_SIDE);
  
          } finally {
              a.recycle();
          }
  
      }
  
  }
  </code></pre>
  
  <p>And then again, in the HandedPathLayout class, the three functions to make sure we get the right kind of LayoutParams:</p>
  
  <pre><code>    @Override
  protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
      return p instanceof HandedPathLayout.LayoutParams;
  }
  
  @Override
  public HandedPathLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {
      return new HandedPathLayout.LayoutParams(getContext(), attrs);
  }
  
  @Override
  protected HandedPathLayout.LayoutParams generateDefaultLayoutParams() {
      return new HandedPathLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
  }
  </code></pre>
  
  <p>I've tried this with and without the fully qualified LayoutParams class names.</p>
  
  <p>So, now that's all there and compiles okay, and then in onMeasure of the root ViewGroup, the HandedLayout, I loop through the children and attempt to get at their getLayoutParams() so I can figure out where to put them and how to measure them, and I get this ClassCastException!</p>
  
  <blockquote>
    <p>05-29 18:16:35.061 9391-9391/com.codesolutions.onehandkeyboard E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                     Process: com.codesolutions.onehandkeyboard, PID: 9391
                                                                                     java.lang.ClassCastException: com.codesolutions.pathlayout.HandedLayout$LayoutParams cannot be cast to com.codesolutions.pathlayout.HandedPathLayout$LayoutParams
                                                                                         at com.codesolutions.pathlayout.HandedLayout.onMeasure(HandedLayout.java:90)</p>
  </blockquote>
  
  <p>That exception is being thrown from this cast, which seems like it should get the right kind, in the debugger I've confirmed that the child is indeed a HandedPathLayout, and all indications are that the LayoutParams are of the correct type!</p>
  
  <pre><code>                HandedPathLayout.LayoutParams lp =
                      (HandedPathLayout.LayoutParams)child.getLayoutParams();
  </code></pre>
  
  <p>I just don't get why the LayoutParams are not of the correct type!</p>
  
  <p>And another thing about this I don't get is about the custom View (extends TextView) that I want to put into my HandedPathLayout.  It needs a custom layout_rows XML attribute, so do I need to make it it's own LayoutParams?  Those are only for ViewGroups, right?  But then it's the view that needs that attribute applied, and not the ViewGroup.</p>
  
  <p>UPDATE:</p>
  
  <p>So when I run the debugger and stop just before my cast that fails, in the onMeasure of HandedLayout... I find that, indeed, the LayoutParams objects are NEITHER of the types I expect!  The getLayoutParams of the parent (the HandedLayout) returns a FrameLayout.LayoutParams (which makes no sense to me at all) and the child (which is a HandedPathLayout) has a HandedLayout.LayoutParams!  WHY?!  What am I not understanding here?</p>
  
  <p>Thank you!</p>