0

I have been spending hours unsuccessfully trying to adjust the width, height, and offset of a simple view in Android as the result of a button press. I have discovered that setTranslationX and setTranslationY always work; the legacy method of setLayoutParams never works once the view is laid out initially. Calls to requestLayout() and invalidate() similarly produce no results.

I have tried to setLayoutParams within the context of posting a runnable, but this does nothing.

Because setTranslationX always works, I would just use that, but unfortunately there is no equivalent method like setWidth or setHeight.

As you can see in the AOSP, setTranslationX makes a call to invalidateViewProperty, which is a private method of View.

Is there an equivalent method to setTranslationX to adjust a view width or view margin, that presumably triggers invalidateViewProperty, and, by extension, works reliably?

EDIT

While in some situations, setLayoutParams may be expected to work after the initial layout, I am in a situation where setLayoutParams has no effect after the initial layout, but setTranslationX does. My setup is as follows:

  • Running Android KitKat 4.4
  • The view in question is MATCH_PARENT for both width, height
  • The view in question is a child of a RelativeLayout
  • The view in question is a View class with a simple solid-color background drawable

Here is the view:

<View 
    android:id="@+id/border"
    android:background="@drawable/match_background_border_transparent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

And here is the (non-working) code meant to dynamically alter its margins, but has no effect. Again, if I call setTranslationX, that always works.

    holder.toggleButton.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            imageBorder.post(new Runnable() {
                @Override
                public void run() {
                    RelativeLayout.LayoutParams p = (LayoutParams) imageBorder.getLayoutParams();
                    p.leftMargin = 20;
                    p.rightMargin = 20;
                    p.topMargin = 20;
                    p.bottomMargin = 20;
                    imageBorder.setLayoutParams(p);
                    // imageBorder.setTranslationX does have an effect if I included it here
                }
            });
        }
    });
Community
  • 1
  • 1
esilver
  • 27,713
  • 23
  • 122
  • 168
  • Did you try `view.layout`? I am not sure about `invalidateViewProperty` though – Blackbelt Mar 15 '15 at 17:03
  • "the legacy method of setLayoutParams never works once the view is laid out initially" -- yes, it does. – CommonsWare Mar 15 '15 at 17:04
  • Just added more info...just tried view.layout, it similarly had no effect... – esilver Mar 15 '15 at 17:20
  • Since we don't have all your code (e.g., the entire layout, the background image), it will be difficult for anyone to reproduce your findings. Try setting the margins to 20 initially, such as in your layout resource. If there is no effect, then the problem is not in *changing* the margins, but something else with regards to your layout, examining the margins, etc. – CommonsWare Mar 15 '15 at 17:31
  • When I add margins in the XML, I do see an effect. Further, when I attempt to programmatically adjust LayoutParams for other views in the activity, it works. I must be hitting some kind of edge case in the framework. – esilver Mar 15 '15 at 18:14

1 Answers1

1

I have determined why setTranslationX was working, but setLayoutParams was not. My views were ultimately descendents of an AdapterView. I was able to programmatically manipulate LayoutParams of the AdapterView and his siblings, but none of the AdapterView's descendents.

Additional research showed that this was a common Android question:

What was confusing was that this view was several levels deep; i.e., it went:

AdapterView -> FrameLayout -> RelativeLayout -> View

Anyhow, I was able to accomplish my programmatic layout goals by wrapping view in another view, and using setPadding.

Community
  • 1
  • 1
esilver
  • 27,713
  • 23
  • 122
  • 168