更改布局和容器的自定义按钮大小
我有一个扩展 TextView 类的自定义类(触摸按钮)。我在手动调整按钮大小时遇到问题。我可以让按钮仅适用于一种类型的布局或容器,但不能同时适用于两者。大多数情况下,Touchbutton 位于 gridviews 中,因此我更改大小的方法如下:
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);
}
但是,当在 LinearLayout 中调整 TouchButton 大小时(例如),我会遇到 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)
第 204 行指的是 params 的实例化。
我注意到 GridView 和 LinearLayout 共享父 ViewGroup,因此我尝试使用 ViewGroup.LayoutParams。然而,这将导致 gridview 的相同行为(logcat 引用同一行)。
有谁知道我如何使其适用于任何类型的布局或小部件?
更新: 按照建议,我再次尝试使用 View 组:
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);
或者不尝试回收当前的布局参数:
setLayoutParams(new ViewGroup.LayoutParams(dim, dim));
并且我得到相同类型的错误:
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)
更新 2: 似乎使用上面指定的 ViewGroup.LayoutParams 适用于 LinearLayout。然而,如上所示,gridview 不喜欢它......
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...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
要了解这里发生的情况,您需要查看 Android 源代码。 ViewGroup
generateLayoutParams
中有一个方法,JavaDoc 指出:如果您查看 LinearLayout 和 AbsListView(GridView 的父级)源代码,您会发现它们将其子布局参数分别转换为 LinearLayout.LayoutParams 和 AbsListView.LayoutParams 。但这种转换仅在将子级添加到布局时才会发生。
因此,如果您将 TouchButton 添加到 LinearLayout(以编程方式或通过 XML),它将接收
LinearsLayout.LayoutParams
,如果您将其添加到 GridView(通过适配器),它将接收AbsListView.LayoutParams
。但是,如果您随后手动设置布局参数,您将在父容器代码中的某个位置得到 ClassCastException(因为它期望其子布局参数具有某种特定类型)。
为了解决您的问题,我建议您采取以下措施:
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:
为什么要强制转换 LayoutParams?
Button.getLayoutParams()
应返回ViewGroup.LayoutParams
,您可以访问其高度和宽度 - 无需强制转换。您确定在尝试ViewGroup.LayoutParams
时没有执行以下操作:(那仍然会失败)。
无论如何,请使用此方法:
然后,如果您仍然遇到异常,请发布该异常 - 而不是带有强制转换的异常。
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.