天天看点

Android LayoutParam,MarginLayoutParams

前言

开发中经常会遇到一个场景,给View动态设置 margin 边距,针对容器类布局比较直观。对非容器类进行 margin 边距设置需按不同的LayoutParams设置,否则很容造成异常。

问题:

为什么给父布局(RelativeLayout)下的子 View(ImamgeView) 设置 LinearLayout.LayoutParams ,提示类型转换异常?

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

LayoutParams 的子类:

ViewGroup.MarginLayoutParams
FrameLayout.LayoutParams
LinearLayout.LayoutParams
RelativeLayout.LayoutParams
RecyclerView.LayoutParams
GridLayoutManager.LayoutParams
StaggeredGridLayoutManager.LayoutParams
ViewPager.LayoutParams
WindowManager.LayoutParams      

设置ImageView的 LayoutParams 需要从 LayoutParams 的子类选择一个。查看api 未发现针对View的 LayoutParams. 如下这种格式:

ImageView.LayoutParams

TextView.LayoutParams

看到的是 容器类.LayoutParams 最终继承 ViewGroup.LayoutParams

继承关系

xxxLayout.LayoutParams -> ViewGroup.MarginLayoutParams-> ViewGroup.LayoutParams

view类中方法setLayoutParams()入参要求必须是 ViewGroup.LayoutParams及子类。      
/**
     * Set the layout parameters associated with this view. These supply
     * parameters to the <i>parent</i> of this view specifying how it should be
     * arranged. There are many subclasses of ViewGroup.LayoutParams, and these
     * correspond to the different subclasses of ViewGroup that are responsible
     * for arranging their children.
     *
     * @param params The layout parameters for this view, cannot be null
     */
 
        public void setLayoutParams(ViewGroup.LayoutParams params) {
        if (params == null) {
            throw new NullPointerException("Layout parameters cannot be null");
        }
        mLayoutParams = params;
        resolveLayoutParams();
        if (mParent instanceof ViewGroup) {
            ((ViewGroup) mParent).onSetLayoutParams(this, params);
        }
        requestLayout();
    }      

大概意思是说:设置与此视图关联的布局参数。这些为该视图的 parent 布局提供参数, 告诉父布局应如何排列子布局。 ViewGroup.LayoutParams 有很多子类,它们对应着不同的 ViewGroup 子类,它们负责安排他们的子类。重要的一点是,子View必须告诉parentView如何对子View进行布局,如果添加子View的时候未指定LayoutParams , 默认会给子View创建 LayoutParams 对象。

marginHorizontal,marginVertical

2. ViewGroup中MarginLayoutParams 静态类中有包含两个属性 marginHorizontal,marginVertical。