I have a custom class (touchbutton) extending the TextView class. I am having trouble resizing the button manually. I can get the button to work for only one type of layout or container, but not both. For the most part, Touchbutton is in gridviews so my method to change the size is as so:
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 is resized in a LinearLayout (for example) I get a crash with the 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 the instantiation of params.
I noticed that both GridView
and LinearLayout
share the parent ViewGroup
, so i tried using ViewGroup.LayoutParams
. This, however, this will lead to the same behavior for gridviews (logcat citing the same line).
Does anyone know how I might make this work for any type of layout or widget?
UPDATE: As recommended i tried with 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 recycle the current layoutparams:
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 ViewGroup.LayoutParams specified above works for the LinearLayout. However, as seen above, the gridview doesn't like it...
Why are you casting LayoutParams at all?
Button.getLayoutParams()
should returnViewGroup.LayoutParams
, which you can access the height and width on - no cast needed. Are you sure when you triedViewGroup.LayoutParams
you didn't do something like:(That'll still fail).
In any case, use this:
Then if you still get an exception, post that one - not the one with the casting.
To understand what happens here you need to look in the Android source. There is a method in ViewGroup
generateLayoutParams
which JavaDoc states:If you look at LinearLayout and AbsListView (the parent of GridView) source you'll see they convert their children layout params to
LinearsLayout.LayoutParams
andAbsListView.LayoutParams
respectively. But this conversion only happens when the child is added to the layout.Thus if you add your TouchButton to the LinearLayout (programmaticaly or via XML) it will receive
LinearsLayout.LayoutParams
and, if you add it to the GridView (via an adapter) it receivesAbsListView.LayoutParams
.But if you set layout params manually afterwards, you will get
ClassCastException
somewhere in the parent container code (since it expects its children layout params to be of some specific type).For the solution of your issue I suggest you the following: