0

I have a fragment, that when added via XML, as

  <fragment
            class="my.fragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:tag="config" />

it is successfully added to the view, and i can interact with it. However, when i try to add it programmatically, in a scrollview, as a second child as:

    val layout = FrameLayout(this)
    val params = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)
    layout.layoutParams = params
    layout.id = View.generateViewId()
    scrollview_container.addView(layout, params)

    val f2 = MyFragment.newInstance(Gson().toJson(asset))
    val trans = supportFragmentManager.beginTransaction()

    trans.add(layout.id, f2, "config")
    trans.addToBackStack(null)
    trans.commit()

i get the following error (sorry, it's long)

E/AndroidRuntime: FATAL EXCEPTION: main
Process: my.process, PID: 4950
java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.view.ViewGroup$MarginLayoutParams
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6819)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
    at android.view.View.measure(View.java:24530)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
    at android.view.View.measure(View.java:24530)
    at android.widget.ScrollView.measureChildWithMargins(ScrollView.java:1414)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
    at android.widget.ScrollView.onMeasure(ScrollView.java:452)
    at android.view.View.measure(View.java:24530)
    at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:735)
    at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:481)
    at android.view.View.measure(View.java:24530)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
    at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
    at android.view.View.measure(View.java:24530)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
    at android.view.View.measure(View.java:24530)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
    at android.view.View.measure(View.java:24530)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
    at android.view.View.measure(View.java:24530)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
    at com.android.internal.policy.DecorView.onMeasure(DecorView.java:742)
    at android.view.View.measure(View.java:24530)
    at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:3006)
    at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1833)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2122)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1721)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7598)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:966)
    at android.view.Choreographer.doCallbacks(Choreographer.java:790)
    at android.view.Choreographer.doFrame(Choreographer.java:725)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:951)
    at android.os.Handler.handleCallback(Handler.java:883)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7356)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

There is no application code in this stack trace, only Android SDK calls. I have also tried to add my fragment in a NavHostFragment, but i still get the same error.

Any ideas? Thanks in advance!

Victor Benetatos
  • 396
  • 3
  • 12
  • [`ViewGroup.MarginLayoutParams`](https://developer.android.com/reference/android/view/ViewGroup.MarginLayoutParams) are being expected. I've even waited a little until I've hit the "close" button. – Martin Zeitler Jan 30 '20 at 10:09
  • @MartinZeitler Good that you have waited, but apart from the fact my question has nothing to do with margins, using val params = ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.MATCH_PARENT) does not seem to work. So, please, try to answer in a sensible and complete way. – Victor Benetatos Jan 30 '20 at 10:26
  • This question is in general a little unclear, because it is unknown what `scrollview_container` is... it seems as if you are setting `FrameLayout.LayoutParams` on a `ScrollView` (which expects the `ViewGroup.MarginLayoutParams` as 2nd argument), instead of setting them on the `FrameLayout`. – Martin Zeitler Jan 30 '20 at 10:50
  • Then ask for clarifications in the first place. scrollview_container is the one child of the scrollview. It is a LinearLayout, in which the FrameLayout i create is added. In the FrameLayout I then try to add the fragment. – Victor Benetatos Jan 30 '20 at 10:53
  • Please read [How to create a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) in the first place, before trying to educate me. Once you have such one (notice the [edit](https://stackoverflow.com/posts/59983176/edit) button), you still could eventually have the question reopened. – Martin Zeitler Jan 30 '20 at 12:38
  • So, this is a bug i introduced myself. In the onViewCreated method of the fragment i was trying to add, i was changing the fragment's root view layoutparamters. So when the parent was measuring, was getting the wrong parameters. I still haven't figured out why it works via XML, but life goes on. – Victor Benetatos Jan 30 '20 at 12:39
  • I don't think so, because you don't set the `FrameLayout.LayoutParams` to the `FrameLayout` (as it is supposed to be), but set them instead of `ViewGroup.MarginLayoutParams` with `.addView(layout, params)`, which causes the `ClassCastException`. – Martin Zeitler Jan 30 '20 at 12:46
  • f2 which is the fragment added, in it's onCreateView method was changing it's layoutParams to ViewGroup.Layout Params. I can now add the fragment to the ScrollView. – Victor Benetatos Jan 30 '20 at 13:29

2 Answers2

0

Try to change below line in your code:

val params = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)

To:

val params = ScrollView.LayoutParams(ScrollView.LayoutParams.MATCH_PARENT, ScrollView.LayoutParams.MATCH_PARENT);
0

It seems your Fragment already have Layout Params.Except to change them you should modify existing params like this.

    ViewGroup.LayoutParams params = yourfragment.getView().getLayoutParams();
    params.width = ViewGroup.LayoutParams.MATCH_PARENT;
    params.height = ViewGroup.LayoutParams.MATCH_PARENT;
    contactsFragment.getView().requestLayout();

The answer is in java language but you will get concept from here.

Muhammad Zahab
  • 1,049
  • 10
  • 21