Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.ClassCastException: GridLayout.LayoutParams cannot cast to Frame.LayoutParams

OS X Yosemite 10.10.5 with Android Studio 2.0

For didactic purpose I want to move as many View attributes as I can from XML to Java.

I've got an android.support.v7.widget.RecyclerView inside a GridLayout and I want to move RecyclerView's android:layout_gravity.

From GridLayout.setGravity and R.attr documentation I know that layout_gravity is used by the child to set gravity attribute in the parent.

The following code is root cause of the exception:

GridLayout.LayoutParams parentParams = new GridLayout.LayoutParams();
parentParams.setGravity(Gravity.CENTER_VERTICAL);
container.setLayoutParams(parentParams);

The XML I want to shrink:

<GridLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recycler_view_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/alphabet_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    <!--android:layout_gravity="center_vertical">-->
    </android.support.v7.widget.RecyclerView>

</GridLayout>

This is the exception chain:

java.lang.ClassCastException: android.widget.GridLayout$LayoutParams cannot be cast to android.widget.FrameLayout$LayoutParams
at android.widget.FrameLayout.onMeasure(FrameLayout.java:431)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2560)
at android.view.View.measure(View.java:17430)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2001)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1166)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1372)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5779)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:550)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

I looked up android.view.View.measure(View.java:17430) to find this:

if (cacheIndex < 0 || sIgnoreMeasureCache) {
    // measure ourselves, this should set the measured dimension flag back
    onMeasure(widthMeasureSpec, heightMeasureSpec);
    mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
} else {

I don't really get how it ended up calling android.support.v7.widget.ContentFrameLayout.onMeasure instead of android.view.View.onMeasure

What am I missing?

like image 562
Paul Avatar asked Jan 27 '26 15:01

Paul


1 Answers

In the code snippet you provide:

GridLayout.LayoutParams parentParams = new GridLayout.LayoutParams();
parentParams.setGravity(Gravity.CENTER_VERTICAL);
container.setLayoutParams(parentParams);

it appears from the variable name container that you are attempting to apply the LayoutParams you construct to your GridLayout instance, rather than to your RecyclerView instance. I'd expect the final line to look something more like

recyclerView.setLayoutParams(parentParams);

If my assumption is correct, the parent of your GridLayout will end up attempting to parse the LayoutParams you built. This parent is unlikely(!) to itself be a GridLayout (I'd guess from the stack trace that it's a FrameLayout), and is choking when it tries to deal with GridLayout-specific LayoutParams.

like image 166
stkent Avatar answered Jan 30 '26 05:01

stkent



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!