【问题标题】:Inflating ImageButton programatically changes width & height params to wrap_content. Why?膨胀 ImageButton 以编程方式将宽度和高度参数更改为 wrap_content。为什么?
【发布时间】:2015-06-19 13:21:03
【问题描述】:

在我的应用中,我使用的是android.support.v7.widget.Toolbar

工具栏的左半部分始终充当后退按钮。

对于不同的活动,右半部分是不同的。有时它只是文本,有时是一个按钮。所以我以编程方式用视图膨胀右半部分。

工具栏

<android.support.v7.widget.Toolbar>
...
... <LinearLayout
        android:id="@+id/left_LL"/>
...
<LinearLayout
        android:id="@+id/right_LL"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:orientation="horizontal" />

</android.support.v7.widget.Toolbar>

我在 right_LL 中夸大了这个视图:

child_button.xml

<?xml version="1.0" encoding="utf-8"?>
<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/right_IB"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/save"
android:background="@null"
android:onClick="onRightHeaderButton"
android:scaleType="fitXY" />

我像这样以编程方式添加它:

right_LL.addView(inflater.inflate(R.layout.child_button,
                    null, false));

所以问题是按钮占据了屏幕的一半。它的原始尺寸是 512x512。

我认为也许 LayoutParams 会以某种方式被重置,所以我也尝试了

final float scale = getResources().getDisplayMetrics().density;
int pixels = (int) (30 * scale + 0.5f);

right_IB = (ImageButton) right_LL.findViewById(R.id.right_IB);
right_IB.setLayoutParams(new ViewGroup.LayoutParams(
                    pixels,pixels));

它给出了这个例外:

java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.widget.LinearLayout$LayoutParams

任何帮助将不胜感激。

【问题讨论】:

    标签: android android-layout android-inflate layoutparams


    【解决方案1】:

    当您调用inflater.inflate(R.layout.child_button, null, false) 时,您正在为父视图传递null - 这会导致任何layout_ 属性被忽略(因为这些属性仅由父视图使用) - 请参阅this Google+ post更多细节。

    相反,您应该使用

    inflater.inflate(R.layout.child_button, right_LL, true));
    

    这会导致您的 child_button 布局为其父布局 right_LL 正确膨胀,并自动添加(这就是 true 所做的)。

    【讨论】:

    • 没用。我这样做了。 right_LL.addView(inflater.inflate(R.layout.child_button,right_LL, true));
    • 当您使用 inflate(id, parent, true) 时,true 会自动为您调用 addView() - 您只需要我在答案中包含的那一行即可。
    • 成功了。谢谢。我也发布了一个答案。请您阅读并添加解释。
    【解决方案2】:

    确保您导入正确的LayoutParams

    android.widget.LinearLayout.LayoutParamsLinearLayout

    或者您的LayoutParams 的导入语句可能正在导入ViewGroup.LayoutParams

    尝试显式使用

    LinearLayout.LayoutParams(...):
    
    spinner1.setLayoutParams(new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
    

    【讨论】:

      【解决方案3】:

      碰巧我决定用一个 LinearLayout 包围我的 ImageButton 并且它起作用了!!! 这样问题就解决了。

      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content">
      
      <ImageButton
          android:id="@+id/right_IB"
          android:layout_width="30dp"
          android:layout_height="30dp"
          android:background="@null"
          android:onClick="onRightHeaderButton"
          android:scaleType="fitXY"
          android:src="@drawable/ic_launcher" />
      </LinearLayout>
      

      我真的不知道为什么,但确实如此。如果有人能给我正确的解释,我会很棒。

      【讨论】:

      • 同样的事情:当您在 inflate() 调用中不包含父级时,最外面的 layout_ 属性将被忽略 - 但是,现在您的 ImageButton 实际上具有父级布局,因此, 其layout_ 属性被保留。
      猜你喜欢
      • 1970-01-01
      • 2017-02-28
      • 2011-08-31
      • 1970-01-01
      • 1970-01-01
      • 2019-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多