【问题标题】:How to resize a custom view programmatically?如何以编程方式调整自定义视图的大小?
【发布时间】:2011-02-27 03:14:43
【问题描述】:

我正在编写一个从 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);
        }

【问题讨论】:

标签: android resize


【解决方案1】:

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

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

【讨论】:

  • 正如@HerbertD 提到的,除非我使用LinearLayout.LayoutParams,否则我也会遇到错误,即使它是我正在调整大小的RelativeLayout。
  • @Eigo 根据 Android 文档,LayoutParams 被传递给父视图,因为这是负责布局的视图。
  • in 值是否应该转换为 dp 值或者它会起作用。
  • 这也是可取的,因为它避免了不必要地实例化新的 LayoutParams 对象
【解决方案2】:
this.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, theSizeIWant));

问题解决了!

注意:请务必使用父布局的LayoutParams。我的是LinearLayout.LayoutParams

【讨论】:

  • 哇。你为什么不使用RelativeLayout.LayoutParams?
  • 这对我不起作用,我得到了一个类转换异常。
  • @TapanThanker 使用父布局的 LayoutParams。我的父布局是 LinearLayout。
  • 我写了一个更通用的版本: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(); } }
  • 这会将所有其他参数重置为默认值。 @smisiewicz 答案更好。
【解决方案3】:

这对我有用:

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

【讨论】:

  • 这比其他答案要好得多,因为此代码不需要知道父 ViewGroup 的确切类型。
  • 你知道调用 requestLayout() 和调用 setLayoutParams(params) 有什么区别吗?
  • setLayoutParams(params) 包括 requestLayout()。
【解决方案4】:

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

您需要使用一个名为applyDimension 的方法,它是TypedValue 类的成员,将dp 转换为像素。因此,如果我想将高度设置为 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() 获取屏幕密度/分辨率

【讨论】:

  • 除了硬编码您的尺寸之外,您还可以将其用于像素高度:float pixels = context.getResources().getDimensionPixelSize(R.dimen.card_height);
【解决方案5】:

在 Kotlin 中,您可以使用 ktx extensions:

yourView.updateLayoutParams {
   height = <YOUR_HEIGHT>
}

【讨论】:

    【解决方案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(); 
        }
    }
    

    【讨论】:

      【解决方案7】:

      试试这个:

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

      【讨论】:

        【解决方案8】:

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

        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;
                                    }
                                });
        

        【讨论】:

          【解决方案9】:

          我是这样解决的。我在 xml 文件中基本上有一个简单的视图。

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

          【讨论】:

          • 哈哈,非常幼稚但工作良好的方式,但是我建议最终调用 setLayoutParams() 以正确地将更改传播到可能的嵌套子级,因此在更新 .width 和 .height 后,调用 view.setLayoutParams(view .getLayoutParams()) 这也总是类型证明
          • @Bhargav Rao 你能帮我解决这个问题吗:https://stackoverflow.com/q/44259342/6596724
          【解决方案10】:

          使用 Kotlin 并使用 dp 单位:

          myView.updateLayoutParams {
              val pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 200f, context.resources.displayMetrics)
              height = pixels.toInt()
          }
          

          【讨论】:

            【解决方案11】:

            如果你只有two or three condition(sizes),那么你可以使用@Overide onMeasure like

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

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

            【讨论】:

              【解决方案12】:

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

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

              【讨论】:

                【解决方案13】:

                这就是我实现这一目标的方式。在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();
                

                【讨论】:

                  【解决方案14】:

                  这就是我所做的:

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

                  如果该视图属于某个视图组,您可能还需要调用 yourViewGroup.requestLayout() 使其生效。

                  【讨论】:

                    【解决方案15】:

                    科特林


                    更新布局参数:

                    val view = layoutInflater.inflate(R.layout.cell, binding.ssss, false).apply {
                                id = View.generateViewId()
                    
                                updateLayoutParams { 
                                    height = 200
                                    width = 400 
                                }
                    
                            }
                    binding.ssss.addView(view)
                    


                    布局参数:

                    val view = layoutInflater.inflate(R.layout.cell, binding.ssss, false).apply {
                                id = View.generateViewId()
                                
                                layoutParams.width = 200
                                layoutParams.height = 200
                                
                            }
                    binding.ssss.addView(view)
                    

                    PS。 Vel_daN:爱​​你所做的事情?。

                    【讨论】:

                      猜你喜欢
                      • 2012-11-09
                      • 2015-05-26
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2018-04-22
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多