Resize custom buttons for layouts and containers

I have a custom class (touchbutton) extending the TextView class. I have a problem resizing the button manually. I can make the button work only for one type of layout or container, but not for both. For the most part, Touchbutton is in gridviews, so my way to resize it like this:

private void setLayout(buttonsize_t size) { log("Setting Layout: "+buttonsize_t.getPxl(size)); final float scale = getContext().getResources().getDisplayMetrics().density; int dim = (int) (buttonsize_t.getPxl(size) * scale + 0.5f); AbsListView.LayoutParams params = (AbsListView.LayoutParams) getLayoutParams(); if (params != null) { params.height = dim; params.width = dim; } else { params = new AbsListView.LayoutParams(dim,dim); } setLayoutParams(params); } 

However, when the TouchButton changes to LinearLayout (for example), I get a crash using Logcat:

 09-01 19:18:35.630: ERROR/AndroidRuntime(20793): java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams 09-01 19:18:35.630: ERROR/AndroidRuntime(20793): at com.ians.aac3.TouchButton.setLayout(TouchButton.java:204) 

Line 204 refers to an instance of parameters.

I noticed that both GridView and LinearLayout share the parent ViewGroup , so I tried using ViewGroup.LayoutParams . This, however, will lead to the same behavior for gridviews (logcat, referring to the same line).

Does anyone know how I can make this work for any type of layout or widget?

UPDATE: As recommended, I tried the View group again:

 import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.util.Log; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.TextView; ..... ViewGroup.LayoutParams params = getLayoutParams(); if (params != null) { params.height = dim; params.width = dim; } else { params = new LayoutParams(dim,dim); } setLayoutParams(params); 

or without trying to rework the current layout options:

 setLayoutParams(new ViewGroup.LayoutParams(dim, dim)); 

And I get the same type of error:

 09-02 09:10:49.680: ERROR/AndroidRuntime(7069): java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams 09-02 09:10:49.680: ERROR/AndroidRuntime(7069): at android.widget.GridView.onMeasure(GridView.java:1028) 09-02 09:10:49.680: ERROR/AndroidRuntime(7069): at android.view.View.measure(View.java:10828) 09-02 09:10:49.680: ERROR/AndroidRuntime(7069): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4351) 09-02 09:10:49.680: ERROR/AndroidRuntime(7069): at android.widget.FrameLayout.onMeasure(FrameLayout.java:267) 09-02 09:10:49.680: ERROR/AndroidRuntime(7069): at android.view.View.measure(View.java:10828) 09-02 09:10:49.680: ERROR/AndroidRuntime(7069): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4351) 09-02 09:10:49.680: ERROR/AndroidRuntime(7069): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1284) 

Update 2: It seems that using the above ViewGroup.LayoutParams works for LinearLayout. However, as seen above, gridview does not like ...

+4
source share
2 answers

To understand what is going on here, you need to look in the Android source. There is a method in ViewGroup generateLayoutParams that points to a JavaDoc:

Returns a secure set of layout options based on the supplied Titles layout. When a ViewGroup is passed a view whose layout parameters do not pass the checkLayoutParams(android.view.ViewGroup.LayoutParams) test checkLayoutParams(android.view.ViewGroup.LayoutParams) , this method is called. This method should return a new set of layout parameters for this ViewGroup, possibly by copying the corresponding attributes from the specified set of layout parameters.

If you look at the source of LinearLayout and AbsListView (the parent element of the GridView), you will see that they will convert their layout settings for children to LinearsLayout.LayoutParams and AbsListView.LayoutParams respectively. But this transformation occurs only when the child is added to the layout.
Thus, if you add TouchButton to LinearLayout (programmatically or via XML), it will receive LinearsLayout.LayoutParams , and if you add it to GridView (via adapter), it will receive AbsListView.LayoutParams .
But if after that you set the layout parameters manually, you will get a ClassCastException somewhere in the parent container (since it expects its layout parameters for children to have a certain type).

To solve your problem, I suggest you the following:

 private void setLayout(buttonsize_t size) { log("Setting Layout: "+buttonsize_t.getPxl(size)); final float scale = getContext().getResources().getDisplayMetrics().density; int dim = (int) (buttonsize_t.getPxl(size) * scale + 0.5f); ViewGroup.LayoutParams params = (ViewGroup.LayoutParams) getLayoutParams(); if (params != null) { params.height = dim; params.width = dim; setLayoutParams(params); } else { // the LayoutParams was not set yet, it must be the GridView // which delays setting till child rendering params = new AbsListView.LayoutParams(dim, dim); setLayoutParams(params); } } 
+19
source

Why are you even imposing LayoutParams?

Button.getLayoutParams() should return a ViewGroup.LayoutParams , which you can access the height and width - without the need for a throw. Are you sure that when you tried ViewGroup.LayoutParams , you did not do something like:

 ViewGroup.LayoutParams params = (AbsListView.LayoutParams) getLayoutParams(); 

(It still fails).

Anyway, use this:

 ViewGroup.LayoutParams params = getLayoutParams(); 

Then, if you still get the exception, write that one is not the one who has casting.

0
source

All Articles