如何以编程方式调整自定义视图的大小?


164

我正在编码自RelativeLayout扩展的自定义视图,并且想以编程方式调整它的大小,该怎么办?

自定义视图类类似于:

public ActiveSlideView(Context context, AttributeSet attr){
        super(context, attr);
        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if(inflater != null){       
            inflater.inflate(R.layout.active_slide, this);
        }

Answers:


253

如果您无法传递视图的高度或宽度,则Android会引发异常。而不是创建一个新的LayoutParams对象,而是使用原始对象,以便保留所有其他设置参数。请注意,getLayoutParams返回的LayoutParams类型是布局的类型,而不是您要调整大小的视图。

RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) someLayout.getLayoutParams();
params.height = 130;
someLayout.setLayoutParams(params);

2
正如@HerbertD提到的那样,除非我使用LinearLayout.LayoutParams,否则这样做也会出错,即使它是我正在调整大小的RelativeLayout。
Martin Belcher-AtWrk

6
@Eigo根据Android文档,LayoutParams传递给父视图,因为这是负责布局的视图。
2011年

1
In值应转换为dp值还是可行。
多丽

这也是可取的,因为它避免了不必要地实例化新的LayoutParams对象
Stephen Kidson 2014年

129
this.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, theSizeIWant));

问题解决了!

注意:确保使用父布局的LayoutParams。我的是LinearLayout.LayoutParams


3
武汉理工大学。您为什么不使用RelativeLayout.LayoutParams?
nmr

1
这对我没用,我得到了一个类强制转换的例外。
Tapan Thaker 2012年

4
@Tapan Thanker使用父级布局的LayoutParams。我的父母布局是LinearLayout。
herbertD

10
我写了一个更通用的版本: private void resizeView(View view, int newWidth, int newHeight) { try { Constructor<? extends LayoutParams> ctor = view.getLayoutParams().getClass().getDeclaredConstructor(int.class, int.class); view.setLayoutParams(ctor.newInstance(newWidth, newHeight)); } catch (Exception e) { e.printStackTrace(); } }
atroutt 2013年

2
这会将所有其他参数重置为默认值。@smisiewicz的答案更好。
弗朗·马佐亚

66

这对我有用:

ViewGroup.LayoutParams params = layout.getLayoutParams();
params.height = customHeight;
layout.requestLayout();

7
这比其他答案要好得多,因为此代码不需要知道父ViewGroup的确切类型。
Bart Burg

1
您知道调用requestLayout()和调用setLayoutParams(params)有什么区别吗?
voghDev '16

2
setLayoutParams(params)包括requestLayout()。
illusionJJ

44

对于它的价值,假设您想以设备独立像素dp)调整视图的大小:-

您需要使用称为的方法applyDimension,该方法是该类的成员,TypedValue可以将像素转换为dps。因此,如果我想将高度设置为150dp(例如),那么我可以这样做:

float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 150, getResources().getDisplayMetrics());
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) someLayout.getLayoutParams();
params.height = (int) pixels;
someLayout.setLayoutParams(params);

其中的表达式:getResources().getDisplayMetrics()获取屏幕密度/分辨率


6
除了可以对尺寸进行硬编码之外,您还可以将其用于像素高度:float pixels = context.getResources().getDimensionPixelSize(R.dimen.card_height);
Francois Dermu

此答案更适合作为正确答案!。谢谢
Yunus Kulyyev


6

试试这个:

...
View view = inflater.inflate(R.layout.active_slide, this);
view.setMinimumWidth(200);

抱歉,自您回答以来,我还没有发布所有问题。现在,这就是整个问题。谢谢!
herbertD 2010年

6

这是@herbertD的上述解决方案的更通用版本:

private void resizeView(View view, int newWidth, int newHeight) { 
    try { 
        Constructor<? extends LayoutParams> ctor = view.getLayoutParams().getClass().getDeclaredConstructor(int.class, int.class); 
        view.setLayoutParams(ctor.newInstance(newWidth, newHeight));   
    } catch (Exception e) { 
        e.printStackTrace(); 
    }
}

@atroutt,您从字面上救了我的一天:)
Qasim

5

我用这种方法来增加自定义视图的宽度

customDrawingView.post(new Runnable() {
                            @Override
                            public void run() {
                                View view_instance = customDrawingView;
                                android.view.ViewGroup.LayoutParams params = view_instance
                                        .getLayoutParams();
                                int newLayoutWidth = customDrawingView
                                        .getWidth()
                                        + customDrawingView.getWidth();
                                params.width = newLayoutWidth;
                                view_instance.setLayoutParams(params);
                                screenWidthBackup = params.width;
                            }
                        });

4

我用这种方式解决了..我基本上在xml文件中有一个简单的视图。

 View viewname = findViewById(R.id.prod_extra);
             prodExtra.getLayoutParams().height=64;

2
哈哈,非常幼稚但可以正常工作,但是我建议最终调用setLayoutParams()来将更改正确传播到可能的嵌套子级,因此在更新.width和.height之后,调用view.setLayoutParams(view.getLayoutParams())这也是总是输入类型证明
comeGetSome

@Bhargav Rao您可以在这个主题上为我提供帮助吗? https://stackoverflow.com/q/44259342/6596724
tux-world

2

如果只有,two or three condition(sizes)则可以使用@Overide之 onMeasure类的

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
{
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

并轻松地在CustomView类中更改这些条件的大小。


1

如果您要覆盖onMeasure,请不要忘记更新新的尺寸

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(newWidth, newHeight);
}

1

这就是我实现这一目标的方式。在Sileria中,他/她做了以下事情:

ViewGroup.LayoutParams params = layout.getLayoutParams();
params.height = customHeight;
layout.requestLayout();

这是正确的,但是它希望我们将的高度设置为pixels,但是我想dp将高度设置为,所以我添加了:

public int convertDpToPixelInt(float dp, Context context) {
    return (int) (dp * (((float) context.getResources().getDisplayMetrics().densityDpi) / 160.0f));
}

因此它将如下所示:

ViewGroup.LayoutParams params = layout.getLayoutParams();
params.height = convertDpToPixelInt(50, getContext());
layout.requestLayout();

0

这是我所做的:

View myView;  
myView.getLayoutParams().height = 32;  
myView.getLayoutParams().width = 32;

如果该视图所属的视图组,则可能还需要调用yourViewGroup.requestLayout()使其生效。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.