精华内容
下载资源
问答
  • java代码控制layout_Margin参数

    万次阅读 2015-02-09 15:49:27
    声明本文属于个人所有,转载注明出处:http://blog.csdn.net/hnulwt/article/details/43671687问题描述今天在做android的界面,不过需要用...在layout xml文件中,通过书写android:layout_marginLeft android:layout_ma

    声明

    本文属于个人所有,转载注明出处:http://blog.csdn.net/hnulwt/article/details/43671687

    问题描述

    今天在做android的界面,不过需要用java代码来动态生成一个界面,写起来不算难,但是在控制每行与上行的间隔的时候遇到了问题。在layout xml文件中,通过书写android:layout_marginLeft android:layout_marginTop 等等几个方法来控制当前view与旁边view的间隔距离。但是如何在java中书写呢?

    解决方案

    在java代码中输写,我只发现了有setPadding(left, top, right, bottom),但是并没有setMargin或者setLayoutMargin方法来控制view间隔。
    查询了谷歌官网,在官网查到了ViewGroup.MarginLayoutParams类,资料如下:


    XML Attributes
    Attribute Name Related Method Description
    android:layout_marginBottom setMargins(int,int,int,int) Specifies extra space on the bottom side of this view.
    android:layout_marginEnd setMarginEnd(int) Specifies extra space on the end side of this view.
    android:layout_marginLeft setMargins(int,int,int,int) Specifies extra space on the left side of this view.
    android:layout_marginRight setMargins(int,int,int,int) Specifies extra space on the right side of this view.
    android:layout_marginStart setMarginStart(int) Specifies extra space on the start side of this view.
    android:layout_marginTop setMargins(int,int,int,int) Specifies extra space on the top side of this view.


    可以看到他们属性还是有对应的方法的:setMargins 和 setMarginEnd等等方法。
    但是这个方法怎么用呢。为此我又进行了一系列探索,发现应该用下面方式使用:

            LinearLayout line = (LinearLayout) findViewById(R.id.layoutbtnlinear_aboutme);
            LinearLayout.LayoutParams params = (LayoutParams) line.getLayoutParams();
            params.setMargins(0, 1, 0, 0);
            line.setLayoutParams(params);
    

    但是这种方式其实还是有点问题的,我的LinearLayout是在java代码中生成的,好吧,继续寻找方法:

    LinearLayout ll = new LinearLayout(this);
    ll.setOrientation(LinearLayout.VERTICAL);
    
    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
         LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    
    layoutParams.setMargins(30, 20, 30, 0);
    
    Button okButton=new Button(this);
    okButton.setText("text");
    ll.addView(okButton, layoutParams);
    展开全文
  • 看到大神的一篇奇文,解决了我多年的困扰。 原博地址:http://www.cnblogs.com/angeldevil/p/3479431.html 零、序 ... 1. 在layout中定义属性 ... 2.... 3.... 1. View的第三构造函数的第三

    看到大神的一篇奇文,解决了我多年的困扰。

    原博地址:http://www.cnblogs.com/angeldevil/p/3479431.html


    零、序

    一、自定义Style

    二、在XML中为属性声明属性值

      1. 在layout中定义属性

      2. 设置Style

      3. 通过Theme指定

    三、在运行时获取属性值

      1. View的第三个构造函数的第三个参数defStyle

      2. obtailStyledAttributes

      3. Example

    四、结论与代码下载

    零、序

      系统自带的View可以在xml中配置属性,对于写的好的Custom View同样可以在xml中配置属性,为了使自定义的View的属性可以在xml中配置,需要以下4个步骤:

      1. 通过<declare-styleable>为自定义View添加属性

      2. 在xml中为相应的属性声明属性值

      3. 在运行时(一般为构造函数)获取属性值

      4. 将获取到的属性值应用到View

      怎么将获取到的属性值应用到View就不用说了,自己定义的属性什么用处自己肯定是清楚的,所以接下来看一下前三点。

    一、自定义Style

      通过<declare-styleable>元素声明Custom View需要的属性即可,下面是一个例子,文件是res/values/attrs.xml

    复制代码
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="Customize">
            <attr name="attr_one" format="string" />
            <attr name="attr_two" format="string" />
            <attr name="attr_three" format="string" />
            <attr name="attr_four" format="string" />
        </declare-styleable>
     
        <attr name="CustomizeStyle" format="reference" />
    </resources>
    复制代码

      在上述xml中,我们声明了Customize与CustomizeSyle,Customize包含了attr_one、attr_two、attr_three与attr_four四个attribute,CustomizeStyle也是一个attribute,但是却没有声明在declare-styleable中。

      定义在declare-styleable中与直接用attr定义没有实质的不同,上述xml中,无论attr_one - attr_four是否声明在declare-styleable中,系统都会为我们在R.attr中生成5个attribute

    复制代码
    public static final class attr {
        public static final int CustomizeStyle=0x7f010004;
        public static final int attr_one=0x7f010000;
        public static final int attr_two=0x7f010001;
        public static final int attr_three=0x7f010002;
        public static final int attr_four=0x7f010003;
    }
    复制代码

      不同的是,如果声明在declare-styleable中,系统还会为我们在R.styleable中生成相关的属性。

    复制代码
    public static final class styleable {
        public static final int[] Customize = {
            0x7f010000, 0x7f010001, 0x7f010002, 0x7f010003
        };
        public static final int Customize_attr_one = 0;
        public static final int Customize_attr_two = 1;    
        public static final int Customize_attr_three = 2;
        public static final int Customize_attr_four = 3;
    }
    复制代码

       如上所示,R.styleable.Customize是一个int[],而里面的元素的值正好和R.attr.attr_one - R.attr.attr_four一一对应,而R.styleable.Customize_attr_one等4个值就是R.attr.attr_one-R.attr.attr_four在R.styleable.Customize数组中的索引。这个数组和索引在第三步运行时获得属性值时会用到,将attr分组声明在declare-styleabe中的作用就是系统会自动为我们生成这些东西,如果不声明在declare-styleable中,我们完全可以在需要的时候自己构建这个数组,由于数组是自己构建的,每个属性的下标索引也就很清楚了,只是比较麻烦。以上一家之言,不过从使用及实验难上看确实是这样的。

    二、在xml中为相应的属性声明属性值

            我们知道,在xml中为属性赋值有几种不同的方式

    1. 直接在layout中使用属性

    2. 设置style并在style中设置属性

    3. Application和Activity可以指定theme,可以在theme中指定在当前Application或Activity中属性的默认值

            下面就分别看一下这三种方式

    1. 直接在layout中使用属性

            在xml layout中使用自定义属性和使用系统属性差不多,不过属性所属的namespace不同,比如像下面这样。

    复制代码
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:ad="http://schemas.android.com/apk/res/com.angeldevil.customstyle"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity" >
    
        <com.angeldevil.customstyle.CustomTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            ad:attr_one="attr one in xml"
            style="@style/ThroughStyle"
            android:text="@string/hello_world" />
    
    </RelativeLayout>
    复制代码

      像layout_width等属性属于android的namespace,自定义的属性属于当前程序的namespace,只需像声明android的namespace一样声明当前程序的namespace就好,只需要把上面红色部分的android换成当前程序的包名。应用属性的时候也需要注意属性的namespace。

    2. 设置style并在style中设置属性

      看上面xml中绿色的那一行,我们为CustomTextView声明了一个style:ThroughStyle,这个Style很简单,只是指定了两个属性的值

    <style name="ThroughStyle">
        <item name="attr_one">attr one from style</item>
        <item name="attr_two">attr two from style</item>
    </style>

      注意,在style中我们声明了attr_one的值,同时在xml中也直接向attr_one赋了值,最终用哪一个有个优先级的问题,后面在第三节:在运行时获取属性值中再说,接下来看下第三种方式。

    3. theme中指定在当前Application或Activity中属性的默认值

    复制代码
    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
        <item name="attr_one">attr one from theme</item>
        <item name="attr_two">attr two from theme</item>
        <item name="attr_three">attr three from theme</item>
        <item name="CustomizeStyle">@style/CustomizeStyleInTheme</item>
    </style>
    
    <style name="CustomizeStyleInTheme">
        <item name="attr_one">attr one from theme reference</item>
        <item name="attr_two">attr two from theme reference</item>
        <item name="attr_three">attr three from theme reference</item>
    </style>
    复制代码

       在上述xml中,我们在AppTheme中为attr_one、attr_two与attr_three指定了值,但是同时也为CustomizeStyle指定了一个reference,而在这个reference中为attr_one、attr_two与attr_three指定了值,CustomizeStyle就是我们在attrs.xml中定义的一个属性。在theme中为属性设置值的方式有两这种,直接在theme中定义或通过另一个attribute引用一个style,这两种方式还是有区别的,在下面的获取属性值一节中可以看到。

    三、在运行时获取属性值

            在styles.xml中,我们同时定义一个DefaultCustomizeStyle的style,它的作用等下可以看到。

    <style name="DefaultCustomizeStyle">
        <item name="attr_one">attr one from defalut style res</item>
        <item name="attr_two">attr two from defalut style res</item>
        <item name="attr_three">attr three from defalut style res</item>
    </style>

      先看下CustomTextView的代码

    复制代码
    public class CustomTextView extends TextView {
        private static final String TAG = CustomTextView.class.getSimpleName();
    
        public CustomTextView(Context context) {
            super(context);
        }
    
        public CustomTextView(Context context, AttributeSet attrs) {
            this(context, attrs, R.attr.CustomizeStyle);
        }
    
        public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Customize, defStyle, R.style.DefaultCustomizeStyle);
            String one = a.getString(R.styleable.Customize_attr_one);
            String two = a.getString(R.styleable.Customize_attr_two);
            String three = a.getString(R.styleable.Customize_attr_three);
            String four = a.getString(R.styleable.Customize_attr_four);
            Log.i(TAG, "one:" + one);
            Log.i(TAG, "two:" + two);
            Log.i(TAG, "three:" + three);
            Log.i(TAG, "four:" + four);
            a.recycle();
        }
    }
    复制代码

       主要代码都在第三个函数中,这里也没做什么,只是通过Context的obtainStyledAttributes获得了前面定义的4个属性的值并打印了出来。

    View的第三个构造函数的第三个参数defStyle

      如果在Code中实例化一个View会调用第一个构造函数,如果在xml中定义会调用第二个构造函数,而第三个函数系统是不调用的,要由View(我们自定义的或系统预定义的View,如此处的CustomTextView和Button)显式调用,比如在这里我们在第二个构造函数中调用了第三个构造函数,并将R.attr.CustomizeStyle传给了第三个参数。

      第三个参数的意义就如同它的名字所说的,是默认的Style,只是这里没有说清楚,这里的默认的Style是指它在当前Application或Activity所用的Theme中的默认Style,以系统中的Button为例说明。

    复制代码
    public Button(Context context) {
        this(context, null);
    }
    
    public Button(Context context, AttributeSet attrs) {
        this(context, attrs, com.android.internal.R.attr.buttonStyle);
    }
    
    public Button(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    复制代码

       在Code中实例化View会调用第一个构造函数,在XML中定义会调用第二个构造函数,在Button的实现中都调用了第三个构造函数,并且defStyle的值是com.android.internal.R.attr.buttonStyle。buttonStyle是系统中定义的一个attribute,系统默认有一个Theme,比如4.0中是Theme.Holo

    <style name="Theme.DeviceDefault" parent="Theme.Holo" >
        ...
        <item name="buttonStyle">@android:style/Widget.DeviceDefault.Button</item>
        ....
    </style>

      上面是系统默认的Theme,为buttonStyle指定了一个Style

    复制代码
    <style name="Widget.DeviceDefault.Button" parent="Widget.Holo.Button" >
    </style>
    
    <style name="Widget.Holo.Button" parent="Widget.Button">
    <item name="android:background">@android:drawable/btn_default_holo_dark</item>
        <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
        <item name="android:textColor">@android:color/primary_text_holo_dark</item>
        <item name="android:minHeight">48dip</item>
        <item name="android:minWidth">64dip</item>
    </style>
    复制代码

       这个Style定义了系统中Button的默认属性,如background等。

      从文档中第三个构造函数的说明中也可以看到,这个构造函数的作用是View的子类提供这个类的基础样式

    View(Context context, AttributeSet attrs, int defStyleAttr)

    Perform inflation from XML and apply a class-specific base style.

      上面说的都比较抽象,还是直接看实例代码来的清楚明白,实验用的代码上面全都贴完了,这里直接看结果,但在这之前要先看一个函数:obtainStyledAtributes。

    obtainStyledAtributes

      我们要获取的属性值都是通过这个函数返回的TypedArray获得的,这是官方说明:obtainStyledAttributes,以下是函数原型:

    public TypedArray obtainStyledAttributes (AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)

      4个参数的意思分别是:

        set:属性值的集合

        attrs:我们要获取的属性的资源ID的一个数组,如同ContextProvider中请求数据库时的Projection数组,就是从一堆属性中我们希望查询什么属性的值

        defStyleAttr:这个是当前Theme中的一个attribute,是指向style的一个引用,当在layout xml中和style中都没有为View指定属性时,会从Theme中这个attribute指向的Style中查找相应的属性值,这就是defStyle的意思,如果没有指定属性值,就用这个值,所以是默认值,但这个attribute要在Theme中指定,且是指向一个Style的引用,如果这个参数传入0表示不向Theme中搜索默认值

        defStyleRes:这个也是指向一个Style的资源ID,但是仅在defStyleAttr为0或defStyleAttr不为0但Theme中没有为defStyleAttr属性赋值时起作用

      链接中对这个函数说明勉强过得去,这里简要概括一下。对于一个属性可以在多个地方指定它的值,如XML直接定义,style,Theme,而这些位置定义的值有一个优先级,按优先级从高到低依次是:

    直接在XML中定义>style定义>由defStyleAttr和defStyleRes指定的默认值>直接在Theme中指定的值

      看这个关系式就比较明白了,defStyleAttr和defStyleRes在前面的参数说明中已经说了,“直接在Theme中指定的值”的意思在下面的示代码中可以看到。

    实验验证

      相关的代码都前面都已经贴上了,不过为了方便查看,这里再把相关的XML一起贴一遍

    复制代码
    main_activity.xml
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:ad="http://schemas.android.com/apk/res/com.angeldevil.customstyle"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity" >
    
        <com.angeldevil.customstyle.CustomTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            ad:attr_one="attr one in xml"
            style="@style/ThroughStyle"
            android:text="@string/hello_world" />
    
    </RelativeLayout>
    
    attrs.xml
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <declare-styleable name="Customize">
            <attr name="attr_one" format="string" />
            <attr name="attr_two" format="string" />
            <attr name="attr_three" format="string" />
            <attr name="attr_four" format="string" />
        </declare-styleable>
    
        <attr name="CustomizeStyle" format="reference" />
    
    </resources>
    
    styles.xml
    <resources>
    
        <style name="AppBaseTheme" parent="android:Theme.Light">
        </style>
        <!-- Application theme. -->
        <style name="AppTheme" parent="AppBaseTheme">
            <!-- All customizations that are NOT specific to a particular API-level can go here. -->
            <item name="attr_one">attr one from theme</item>
            <item name="attr_two">attr two from theme</item>
            <item name="attr_three">attr three from theme</item>
            <item name="CustomizeStyle">@style/CustomizeStyleInTheme</item>
        </style>
    
        <style name="CustomizeStyleInTheme">
            <item name="attr_one">attr one from theme reference</item>
            <item name="attr_two">attr two from theme reference</item>
            <item name="attr_three">attr three from theme reference</item>
        </style>
    
        <style name="ThroughStyle">
            <item name="attr_one">attr one from style</item>
            <item name="attr_two">attr two from style</item>
        </style>
        
        <style name="DefaultCustomizeStyle">
            <item name="attr_one">attr one from defalut style res</item>
            <item name="attr_two">attr two from defalut style res</item>
            <item name="attr_three">attr three from defalut style res</item>
        </style>
    
    </resources>
    复制代码

       在Code中是这样获取属性的

    复制代码
    public CustomTextView(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.CustomizeStyle);
    }
    
    public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
            
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Customize, defStyle,
                    R.style.DefaultCustomizeStyle);
        ...
    }
    复制代码

      CustomizeStyle是定义的一个attribute,DefaultCustomizeStyle是定义的一个style。

      从代码中可以看到,R.attr.CustomizeStyle就是前面提到的defStyleAttr,R.style.DefaultCustomizeStyle就是defStyleRes。

      在Styles.xml中我们为App定义了一个Theme:AppTheme,在这个Theme中直接为attr_one、attr_two、attr_three定义了属性值,这个就是前面关系式中说的直接在Theme中指定的值。

      在AppTheme中同时定义了CustomizeStyle,引用了一个Style,在CustomTextView的构造函数中分别打印了attr_one、attr_two、attr_three、attr_four的值,所以下面我们就可以通过Log输出验证一下前面的关系式,如果一个attribute在多个位置都定义了值,究竟哪一个起作用。

      

      如上图所示:

      • attr_one同时在xml、style、defStyleAttr、defStyleRes与Theme中直接定义了值,但起作用的是在xml中的定义
      • attr_two同时在style、defStyleAttr、defStyleRes与Theme中直接定义了值,但起用的是在style中的定义
      • attr_three同时在defStyleAttr、defStyleRes与Theme中直接定义了值,但起作用的是defStyleAttr
      • attr_four在defStyleRes中定义了,但结果仍是0。

      这可以说明:

    1. 直接在XML中定义>style定义>由defStyleAttr定义的值>defStyleRes指定的默认值、直接在Theme中指定的值

    2. defStyleAttr(即defStyle)不为0且在当前Theme中可以找到这个attribute的定义时,defStyleRes不起作用,所以attr_four虽然在defStyleRes(DefaultCustomizeStyle)中定义了,但取到的值仍为null。

      为了看一下defStyleRes的作用,1. 我们在AppTheme中加上attr_four的定义,2. 向obtainStyledAttributes的第三个参数传入0,或者移除AppTheme中CustomizeStyle的定义,结果是一样的

    复制代码
    <style name="AppTheme" parent="AppBaseTheme">
        <item name="attr_one">attr one from theme</item>
        <item name="attr_two">attr two from theme</item>
        <item name="attr_three">attr three from theme</item>
        <item name="attr_four">attr four from theme</item>
    </style>
    复制代码

       由于defStyleAttr为0,或者defStyleAttr不为0但是我们没有为这个属性赋值,所以defStyleRes起作用,当一个属性没有在XML和Style中赋值时,系统会在defStyleRes(此处为DefaultCustomizeStyle)查找属性的值。

      

      我们看到attr_three的值来自defStyleRes,而attr_four的值来自Theme中的直接定义(DefaultCustomizeStyle定义了attr_one、atrr_two、attr_three) ,这就说明

    1. defStyleAtrtr即defStyle为0或Theme中没有定义defStyle时defStyleRes才起作用

    2. defStyleRes>在Theme中直接定义

     结论

       从前面的说明可以得到以下结论:

      1. 要为自定义View自定义属性,可以通过declare-styleable声明需要的属性
      2. 为了在Theme设置View的默认样式,可以同时定义一个format为reference的属性att_a,在定义Theme时为这个attribute指定一个Style,并且在View的第二个构造函数中将R.attr.attr_a 作为第三个参数调用第三个构造函数
      3. 可以定义一个Style作为Theme中没有定义attr_a时View属性的默认值。
      4. 可以在Theme中直接为属性赋值,但优先级最低
      5. 当defStyleAttr(即View的构造函数的第三个参数)不为0且在Theme中有为这个attr赋值时,defStyleRes(通过obtainStyledAttributes的第四个参数指定)不起作用
      6. 属性值定义的优先级:xml>style>Theme中的默认Sytle>默认Style(通过obtainStyledAttributes的第四个参数指定)>在Theme中直接指定属性值

    1. 代码地址:http://files.cnblogs.com/angeldevil/CustomStyle.zip


    展开全文
  • 先看两个参数的构造函数: public View(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); }public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

    先看两个参数的构造函数:

    public View(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs, 0);
        }
    public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            this(context, attrs, defStyleAttr, 0);
        }

    四个参数的构造,省略了很多

    public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            this(context);
    
            final TypedArray a = context.obtainStyledAttributes(
                    attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);
    
            if (mDebugViewAttributes) {
                saveAttributeData(attrs, a);
            }
    
            Drawable background = null;

    一个参数的构造:

     public View(Context context) {
            mContext = context;
            mResources = context != null ? context.getResources() : null;
            mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED;
            // Set some flags defaults
            mPrivateFlags2 =
                    (LAYOUT_DIRECTION_DEFAULT << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) |
                    (TEXT_DIRECTION_DEFAULT << PFLAG2_TEXT_DIRECTION_MASK_SHIFT) |
                    (PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT) |
                    (TEXT_ALIGNMENT_DEFAULT << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT) |
                    (PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT) |
                    (IMPORTANT_FOR_ACCESSIBILITY_DEFAULT << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT);
            mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
            setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS);
            mUserPaddingStart = UNDEFINED_PADDING;
            mUserPaddingEnd = UNDEFINED_PADDING;
            mRenderNode = RenderNode.create(getClass().getName(), this);
    
            if (!sCompatibilityDone && context != null) {
                final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
    
                // Older apps may need this compatibility hack for measurement.
                sUseBrokenMakeMeasureSpec = targetSdkVersion <= JELLY_BEAN_MR1;
    
                // Older apps expect onMeasure() to always be called on a layout pass, regardless
                // of whether a layout was requested on that View.
                sIgnoreMeasureCache = targetSdkVersion < KITKAT;
    
                Canvas.sCompatibilityRestore = targetSdkVersion < M;
    
                // In M and newer, our widgets can pass a "hint" value in the size
                // for UNSPECIFIED MeasureSpecs. This lets child views of scrolling containers
                // know what the expected parent size is going to be, so e.g. list items can size
                // themselves at 1/3 the size of their container. It breaks older apps though,
                // specifically apps that use some popular open source libraries.
                sUseZeroUnspecifiedMeasureSpec = targetSdkVersion < M;
    
                // Old versions of the platform would give different results from
                // LinearLayout measurement passes using EXACTLY and non-EXACTLY
                // modes, so we always need to run an additional EXACTLY pass.
                sAlwaysRemeasureExactly = targetSdkVersion <= M;
    
                // Prior to N, layout params could change without requiring a
                // subsequent call to setLayoutParams() and they would usually
                // work. Partial layout breaks this assumption.
                sLayoutParamsAlwaysChanged = targetSdkVersion <= M;
    
                // Prior to N, TextureView would silently ignore calls to setBackground/setForeground.
                // On N+, we throw, but that breaks compatibility with apps that use these methods.
                sTextureViewIgnoresDrawableSetters = targetSdkVersion <= M;
    
                // Prior to N, we would drop margins in LayoutParam conversions. The fix triggers bugs
                // in apps so we target check it to avoid breaking existing apps.
                sPreserveMarginParamsInLayoutParamConversion = targetSdkVersion >= N;
    
                sCascadedDragDrop = targetSdkVersion < N;
    
                sCompatibilityDone = true;
            }
        }

    默认情况下,最终会调用四个参数的构造函数,其他两个参数的值都是0,最终第四个构造函数又调用了第一个。

    我们在自定义view时,一般会重写一个参数的构造(在activity中直接new 时使用),两个参数的构造(xml中声明时)。其他两个参数的构造都是手动执行的,比如自定义view的时候,需要传入一个默认的style,或是系统的控件比如Button:

    public Button(Context context) {
            this(context, null);
        }
    
        public Button(Context context, AttributeSet attrs) {
            this(context, attrs, com.android.internal.R.attr.buttonStyle);
        }
    
        public Button(Context context, AttributeSet attrs, int defStyleAttr) {
            this(context, attrs, defStyleAttr, 0);
        }
    
        public Button(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
        }

    可以看出,在Button的四个构造函数中,无论我们从代码中new一个buttong还是从xml中声明了一button,其最终都会执行四个构造的方法,而在第二个构造函数中,调用了三个参数的构造函数,并传入了一个attrStyle,这个是系统为button定义的style,也就是说如果我们没有在xml中为这个button指定属性(也就是第二个参数attrs没有传入值),那么系统默认会去使用默认的风格来装饰这个button,前提是这个buttonStyle属性在app或是activity的Theme中被引用了。
    一句话就是说,如果我们的attrs没有设置(比如直接code中new一个buttong,或是xml中没有设置其他风格),那么会去取默认的风格,而如果默认的风格被构造的时候传入了0,或是APP theme中没有找到对应的值,那么第四个参数传入的值才起了作用。
    也就是说第三个参数,是跟app theme关联的。也就是为什么我们在给app或是activity设置不同的风格的时候,button的样式也会跟着改变的原因了。


    最后附上一篇详细讲解这几个属性的文章,需要多读几遍然后实践一下才能理解了。

    Android中自定义样式与View的构造函数中的第三个参数defStyle的意义


    另外,清理下资源下的attr标签和style标签以及theme标签,都在values文件夹中定义(文件的命名并没有具体的规定,只要是资源文件,头标签是<resources>就行:

    1、attrs.xml

    比如,有如下定义:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="Customize">
            <attr name="attr_one" format="string"/>
            <attr name="attr_two" format="string"/>
            <attr name="attr_three" format="string"/>
            <attr name="attr_four" format="string"/>
        </declare-styleable>
    
        <attr name="CustomizeStyle" format="reference"/>
    </resources>

    上面定义的所有attr都会在R.attr这个类中被赋值:

    public static final class attr {
        public static final int CustomizeStyle=0x7f010004;
        public static final int attr_one=0x7f010000;
        public static final int attr_two=0x7f010001;
        public static final int attr_three=0x7f010002;
        public static final int attr_four=0x7f010003;
    }

    而<declare-styleable>标签下的会在R.styleable类中生成相关的数组。

    我的理解是,declare标签下的是每种控件特有的属性,而直接attr标签则是所有控件都共有的属性吧。


    2、styles.xml

    相当于是为这些定义的属性赋值,也就是集合起来,一个组合就有一种风格

    比如button:

    <style name="Widget.Button">
            <item name="android:background">@android:drawable/btn_default</item>
            <item name="android:focusable">true</item>
            <item name="android:clickable">true</item>
            <item name="android:textAppearance">?android:attr/textAppearanceSmallInverse</item>
            <item name="android:textColor">@android:color/primary_text_light</item>
            <item name="android:gravity">center_vertical|center_horizontal</item>
        </style>

    每个item里面的name是在attrs.xml中定义好的属性,而后面跟着的就是该属性的具体值了,该值可以是个具体的值,也可以是另一个style或其他资源的引用(在其定义的时候其格式就是format=“reference”


    在控件的xml中,我们可以为控件指定一个个的attr属性值,也可以使用一个style来设置一组attr值,比如:

    <TextView
            android:id ="@+id/tv1"
            android:layout_width ="wrap_content"
            android:layout_height ="wrap_content"
            android:textColor ="#FFFFFF" />
    

    可以用如下代替:

    <style name= "Sample1">
           
            < item name= "android:layout_width" >wrap_content </ item>
            < item name= "android:layout_height" >wrap_content </ item>
            < item name= "android:textColor" >#00FF00 </item >
           
        </style >
    
    <TextView
            android:id ="@+id/tv1"
            style= "@style/Sample1"
            android:text ="@string/sample1_tv1" />
    

    组成一个style被引用,其实可以起到复用的作用。

    3、theme标签,该标签只能应用于整个app或是activity,android:theme="@style/mystyle"。其引用的是一个style集合,一旦声明了一个theme,该app或是activity下的所有控件都默认使用这种风格,但是如果控件自己制定了自己的风格(比如说在xml中指定自己的属性)那么将会优先选择控件自己制定的风格。


    参考:Android中Styles、Themes、attrs介绍

    展开全文
  • UGUI提高<二> LayoutGroup布局参数详解

    万次阅读 2016-11-17 16:47:32
    Grid Layout Group 横竖布局 Padding —— 间隔 CellSize —— 子物体大小 Spacing —— 子物体之间的间隔 Start Corner —— 子物体排列的角度 Start Axis —— 子物体排列方向 Child Alignment —— 子物体整体...

    原创


    一. Grid Layout Group 横竖布局

    Padding   ——  间隔

    CellSize   ——  子物体大小

    Spacing   ——  子物体之间的间隔

    Start Corner  ——  子物体排列的角度

    Start Axis       ——  子物体排列方向

    Child Alignment  —— 子物体整体位于什么方位

    Constraint  约束  ——  Flexible灵活的( 按照父物体长宽自动横竖行 )    Fixed Column Count   指定列数      Fixed Row Count 指定行数


    二.Horizontal(Vertical) Layout Group  横(竖)向布局

    child force expand  ——  是否强制拉伸长宽到父物体大小


    单是一个布局组件很难实现想要的效果,还可以再添加一个Content Size Fitter 组件配合使用(只是用来过滤尺寸,没有设置的选项默认为0处理,比如选择Min  Width  ,但是子物体上没有设置过Min  Width  ,那么它就没有宽度)。


    Content Size Fitter  内容大小过滤 组件

    Horizontal Fit    ——   子物体横向适配(Unconstrained 不受约束  Preferred Size   首选尺寸  Min Size 最小尺寸)

    Vertical Fit         ——   子物体竖向适配


    Layout Element    布局元素 组件   ( 子物体上需要添加 )

    Min  Width        ——   最小宽度( 不受父物体宽度影响 )

    Min  Height      ——   最小高度

    Preferred Width  ——  首选宽度( 最大不能超过父物体宽度 )

    Preferred Height ——  首选高度

    Flexible Width    ——  灵活宽度 ( 只有0和大于0两种  大于0的话会自动补全宽度)

    Flexible Height ——   灵活高度


    注:横竖布局下的子物体大小是统一的,不能单独设置大小。没有单个横竖布局灵活,但是设置简单一些。


    三.Content Size Fitter  内容大小过滤 组件

    一般和Layout Group配合使用  用法刚才已经写过了,再写一次加深印象。


    四. Aspect Ratio Fitter  宽高比过滤  组件

    Aspect Mode  ——  宽高比模式 ( Width Controls Height 宽控制高(高度不可修改)   Height Controls Width 高控制宽     Fit In Parent 宽或高和父物体一样,另一个小于父物体   Envelope Parent 宽或高和父物体一样,另一个包围父物体 )

    Aspect Ratio  ——   宽高比例



    展开全文
  • Matplotlib

    万次阅读 多人点赞 2018-08-23 23:28:21
    Pyplot简介 matplotlib.pyplot 是一命令风格的函数集合,这使得 matplotlib 工作起来和...每一 pyplot 函数都会使图形发生一些变化,例如:创建一幅图形、在一幅图中创建一绘图区域、在绘图区域中绘制一些线...
  • ViewGroup.layout(int l, int t, int r, int b)四个输入参数的含义
  • View绘制详解(),谝一谝layout过程

    千次阅读 2016-10-05 12:18:42
    上篇博客我们介绍了View的测量过程,这只是View显示过程的第一步,第二步就是layout了,这我们一般译作布局,其实就是在View测量完成之后根据View的大小,将其一摆放在ViewGroup中的过程。OK,那我们今天...
  • View工作原理()view的layout过程

    万次阅读 2014-01-03 10:40:53
    一、android中view的... Layout过程其实就是父视图按照子视图的大小及布局参数将子视图放在窗口的合适的位置上。 视图的布局过程是从ViewRoot对象调用根视图的layout()方法开始,接着layout()方法调用根视图的onLay
  • openGL之API学习(十七)layout作用详解

    千次阅读 多人点赞 2019-04-17 21:42:22
    原文在https://www.khronos.org/opengl/wiki/Layout_Qualifier_(GLSL) GLSL语言规范中也有对此的详细说明... 这里大致翻译如下: 布局限定符(GLSL除了这限定符,还有很多其它限定符,比如存储限定符、...
  • ViewGroup.layout(int l, int t, int r, int b)这个方法是确定View的大小和位置的,然后将其绘制出来,里面的四个参数分别是View的四个点的坐标,他的坐标不是相对屏幕的原点,而且相对于他的父布局来说的, ...
  • 通过上面的例子总结,我们可以通过父容器的测量规格和子View的布局参数来确定子View的MeasureSpec,这样便确立了子View的宽高,下面是父容器测量规格和子View布局参数确立子ViewMeasureSpec的结果图 Android视图...
  • 这里的this 有问题 换成什么参数都有问题 写成this 的话 整行代码都有红线! 请大神帮忙! ``` package fragment; import android.content.Context; import android.content.Intent; import android.location....
  • 一、关于layout_margin 搞Android时间也不短了,对layout_margin也不陌生了,可最近遇到一问题让我发现,对它的认识还不够深入全面。大量网络资料上都说,layout_margin指view距离父view的距离。这说法不够严谨...
  • android onlayout参数

    千次阅读 2015-03-05 23:59:14
    由于我们希望优先横向布局子控件,那么,首先,我们知道总宽度是多少,这值可以通过getMeasuredWidth()来得到,当然子控件的宽度也可以通过子控件对象的getMeasuredWidth()来得到。 这样,就不复杂了,具体的...
  • Android View 布局流程(Layout)完全解析

    千次阅读 2016-05-28 13:31:34
    前言上一篇文章,笔者详细讲述了View三大工作流程的第一,Measure流程,如果对测量流程还不熟悉的读者...那么我们开始对layout流程进行详细的解析。ViewGroup的布局流程上一篇文章提到,三大流程始于ViewRootImpl#p
  • View属性的解析设计到两类:AttributeSet 和 TypedArray,前者将View设置的所有属性做了汇集和封装,后者提供了解析属性值的方法。
  • 接着在 onLayout 中判断是否有子 View,如果有,则调用了第一个子 View 的 layout 方法,分别传入 0, 0, childAt.getMeasuredWidth(), childAt.getMeasuredHeight() 四个参数,这四个参数分别代表了子 View 在 当前...
  • 自定义View之Layout方法详解

    千次阅读 2017-04-01 12:02:57
    自定义View之onLayout、Layout分析
  • PCB Layout 设计流程

    千次阅读 2020-03-31 14:24:37
    所以即使你不太懂什么叫电路设计,只要确定有一可正常工作的电路图 ,基本上也就可以做出一PCB板。你也可以做出你自己的PCB板,只要你掌握了一些的Design Rule。 至于如何确定这是一可以"工作" 的电路图? ...
  • SAP MM ME1M 报表的Layout之调整

    千次阅读 2018-07-23 08:30:39
    SAP MM ME1M 报表的Layout之调整       之所周知,SAP的很多报表都可以是ALV的格式输出,这格式对于业务而言,界面友好,方便业务人员按照自己的需求去调整报表输出结果,也方便业务人员将输出导出到本地...
  • ExtJs常用布局--layout详解(含实例)

    万次阅读 2016-05-23 18:27:14
    序言: 笔者用的ExtJs版本:ext-3.2.0 ExtJs常见的布局方式有:border、form、absolute...本文所有实例代码已提供下载,下载链接:ExtJs常用布局--layout详解实例代码   简介: 最常用的边框布局——BorderLay...
  • 前言今天在lint项目的代码...今天再次遇到这个问题,便老老实实记录一下LayouInflater中inflate方法两个参数和三个参数的区别。用法LayoutInflater.from(RecylerActivity.this).inflate(R.layout.my_text_view,viewGro
  • 转载请注明出处:...View树的Layout流程 View的Layout时序图 View布局流程之Layout ViewGroup的Layout过程 setFrame方法 View的Layout过程 FrameLayout的Layout过程 View树的Layout流程图:View布局流程之
  • Qt中QLayout.addWidget()参数结构及用法

    万次阅读 2019-04-19 18:18:03
    种布局的参数是一样的。 .addWidget()函数 addWidget(QWidget * widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment = 0) QWidget * widget:需要添加的widget in....
  • 一、背景Android 开发者在日常的开发中,经常需要用到查看视图的功能,Android Studio 开发团队为我们提供了 LayoutInspector 插件。在较新的版本提供了 Li...
  • 其核心是一个大小自适应的中心面板(必选),面板的上下左右四个方向可以放置可折叠、可缩放的面板(可选),各个面板可以添加任意数量的页眉和页脚面板。UI Layout支持内层布局的嵌套,任意块元素都可以当作布局的...
  • Android Layout 布局属性全解

    千次阅读 2016-09-06 10:00:38
      Android Layout 布局属性全解 标签: android FrameLayout 2014-11-12 18:01 2722人阅读 评论(0) 收藏 举报  分类: android开发(55) 
  • 上一篇文章我们讲了View的measure的流程,接下来我们讲下View的layout和draw流程,如果你理解了View的measure的流程,那这篇文章自然就不在话下了。
  • Android自定义View(二)-Layout原理篇

    千次阅读 2018-09-22 11:35:48
    一、Layout的作用:计算视图的位置,即Left、Top、Right、Bottom点的位置 二、layout过程:跟measure类似,layout也会根据View的类型分成两种情况进行处理。 View类型 layout过程 单一View...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 98,320
精华内容 39,328
关键字:

layout的四个参数