Android-related knowledge and screen (b)

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/gaolh89/article/details/81161584

In the Android and screen-related knowledge points (a), some of the general concepts related to our screen, the basic usage, conversion between units, screen shots, and other knowledge points learning. This article will further knowledge about screen to learn.

Before learning this article, it is recommended to read the Android-related knowledge points screen (a)


Note:
(1) Local herein relates to a test machine, unless otherwise noted: A refers to a tester Resolution: 1080 2160 mobile phone, the test unit B refers to the resolution: 720 1280

(2) Since the author of the phone companies require a different resolution, the TextView font size, the same width and height control are not different resolutions using different phone dp, sp. Therefore, in the code set, the default custom property value process, They are fixed values. If we project requirements adapted Note that modifying the section.

.Xml relationship with a data code,

We are the first to write a native in xml TextView set the font size 40sp code is as follows:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
    >

    <!--直接xml设置-->
    <TextView
        android:id="@+id/tv_xml"
        android:layout_width="300dp"
        android:layout_height="100dp"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="20dp"
        android:background="@color/colorPrimary"
        android:text="测试内容"
        android:textSize="40sp"
        />
</LinearLayout>

Then obtains the font size in the code, the code is as follows:

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dptext);
        mTvXml = (TextView) findViewById(R.id.tv_xml);
        float textSize = mTvXml.getTextSize();
    }

Breakpoint test, the test machine A, mTvXmlTextSize value 110.0; the test machine B, mTvXmlTextSize value of 80.0.

In addition, the need to add things explained:

(1) xml used 40sp, modify the phone system, set the font, the results on the test machine is no longer 110.0,80.0. But with the system to set the font is changed.

(2) If the xml 40sp into 40dp, the test results on the same machine as 110.0,80.0. (Phone system and set the font size modifications are 110.0,80.0)

# 2. With regard to xml, code, custom properties using a screen-related knowledge #

On the basis of our earlier, then add 2 textView control. ID tv_code in native to the TextView TextView (line 23). We set the font size in the code, the margins .id is tv_custom TextView (line 33) is Inheritance native TextView custom control.

xml code is as follows:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
    >

    <!--直接xml设置-->
    <TextView
        android:id="@+id/tv_xml"
        android:layout_width="350dp"
        android:layout_height="100dp"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="20dp"
        android:background="@color/colorPrimary"
        android:text="测试内容"
        android:textSize="40sp"
        />

    <!--通过代码 set的形式-->
    <TextView
        android:id="@+id/tv_code"
        android:layout_width="350dp"
        android:layout_height="100dp"
        android:layout_gravity="center_horizontal"
        android:background="@color/colorAccent"
        android:text="测试内容"
        />

    <!--通过自定义控件属性的形式-->
    <com.mfc.countdowntimerutils.TestTextView
        android:id="@+id/tv_custom"
        android:layout_width="350dp"
        android:layout_height="100dp"
        android:layout_gravity="center_horizontal"
        android:background="@color/colorPrimary"
        android:text="测试内容"
        app:testTextMarginTop="20dp"
        app:testTextSize="40sp"
        />

</LinearLayout>

To test the accuracy, textView we only change the font size, textview distance layout_marginTop.
Which, com.mfc.countdowntimerutils.TestTextView belong to legacy systems TextView controls. Custom control does not belong to the scope of this article to talk about, for unfamiliar or custom control interested students, free to Google.

com.mfc.countdowntimerutils.TestTextView the property code as follows (valuse / arrts below):

  <!--自定义字体大小 margintop的TextView-->
    <declare-styleable name="TestTextView">
        <attr name="testTextSize" format="dimension"/>
        <attr name="testTextMarginTop" format="dimension"/>
    </declare-styleable>

TestTextView custom code is as follows:

@SuppressLint("AppCompatCustomView")
public class TestTextView extends TextView implements ViewTreeObserver.OnGlobalLayoutListener {

    private Context    mContext;
    int marginTop;

    public TestTextView(Context context) {
        super(context);
    }

    public TestTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
        init(context, attrs);
    }

    public TestTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private void init(Context context, AttributeSet attrs) {

        mContext = context;

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable
                .TestTextView);

        if (typedArray != null) {

           //①如果xml中使用了TestTextView_testTextSize属性,typedArray.getDimensionPixelOffset
            //会根据xml中使用的单位进行内部转化(比如xml中都是使用40sp,不同分辨率手机得到的initTextSize值不同).
            
            //②如果xml中没有使用TestTextView_testTextSize属性,typedArray.getDimensionPixelOffset会直接
            //使用默认的值(它不知道单位的,默认值也没有单位)
            int initTextSize = typedArray.getDimensionPixelOffset(R.styleable
                    .TestTextView_testTextSize, DisplayUtils.sp2px(mContext, 40));
            setTextSize(TypedValue.COMPLEX_UNIT_PX,initTextSize);

            //TestTextView_testTextMarginTop的道理同上述的TestTextView_testTextSize
            marginTop = typedArray.getDimensionPixelOffset(R.styleable
                    .TestTextView_testTextMarginTop, DisplayUtils.dip2px(mContext,20));
            typedArray.recycle();


          post(() -> {

                LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) getLayoutParams();
                Log.e("测试元素", "init: " + this);
                lp.leftMargin = 0;
                lp.rightMargin = 0;
                //数据是px
                lp.topMargin = marginTop;
                lp.bottomMargin = 0;
                setLayoutParams(lp);

            });

        }
    }




    @Override
    public void onGlobalLayout() {

        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) getLayoutParams();
        Log.e("测试元素", "init: " + this);
        lp.leftMargin = 0;
        lp.rightMargin = 0;
        //数据是px
        lp.topMargin = marginTop;
        lp.bottomMargin = 0;
        setLayoutParams(lp);
    }

//    @Override
//    protected void onFinishInflate() {
//        super.onFinishInflate();
//        getViewTreeObserver().addOnGlobalLayoutListener(this);
//    }

}

In the code above, the use of view drawn on the rewritable onFinishInflate () method, or a post () method if it is directly used, it will report a null pointer, which are not part of the scope of this paper discuss, is omitted.

Further two points should be noted:
1. Check setTextSize () methods source we found that this method has received one parameter, i.e. setTextSize(float size)
the relevant part of the source code as follows:

/**
     * Set the default text size to the given value, interpreted as "scaled
     * pixel" units.  This size is adjusted based on the current density and
     * user font size preference.
     *
     * <p>Note: if this TextView has the auto-size feature enabled than this function is no-op.
     *
     * @param size The scaled pixel size.
     *
     * @attr ref android.R.styleable#TextView_textSize
     */
    @android.view.RemotableViewMethod
    public void setTextSize(float size) {
        setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
    }

It is seen from the source line 14, if only one parameter is passed, the system will automatically add TypedValue.COMPLEX_UNIT_SP into two parameters.

The first parameter is doing with it, we continue to see the point of this method continues source source code as follows:

/**
     * Set the default text size to a given unit and value. See {@link
     * TypedValue} for the possible dimension units.
     *
     * <p>Note: if this TextView has the auto-size feature enabled than this function is no-op.
     *
     * @param unit The desired dimension unit.
     * @param size The desired size in the given units.
     *
     * @attr ref android.R.styleable#TextView_textSize
     */
    public void setTextSize(int unit, float size) {
        if (!isAutoSizeEnabled()) {
            setTextSizeInternal(unit, size, true /* shouldRequestLayout */);
        }
    }

From line 7 shows the description of the unit parameters: unit is the size of the unit needed to look up the description of the TextView TypedValue.COMPLEX_UNIT_SP constant, this constant refers sp means we setTextSize (14) is 14sp.... easily mistaken px.

Similarly, we can set the first parameter sp or dp Of course, the latter value corresponding to the replacement or the need to achieve the effect of Example 40sp If px, the following code...:

mTvCode.setTextSize(TypedValue.COMPLEX_UNIT_PX,DisplayUtils.sp2px(this,40));

2. With regard to the set margin or padding method, or a wide view Higher calculating unit is px. If you use TestTextView_testTextMarginTop attribute xml system call typedArray.getDimensionPixelOffset (R.styleable.TestTextView_testTextMarginTop, value) value, the resolution on the screen, custom XML attribute values ​​automatically converted /

3. When using the most primitive textView, we in xml, are set

android:textSize="40sp"
android:layout_marginTop="20dp"

In order to achieve the same effect, and we use setTextSize setMargin way is how to achieve it:
(1) look at the way textView native but using code settings:

public class TestActivity extends AppCompatActivity {

    private TextView mTvXml, mTvCode, mTvCutom;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        mTvXml = (TextView) findViewById(R.id.tv_xml);
        mTvCode = (TextView) findViewById(R.id.tv_code);
        mTvCutom = (TextView) findViewById(R.id.tv_custom);

        //这里的40等同于40sp
        mTvCode.setTextSize(40);


        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mTvCode.getLayoutParams();
        lp.leftMargin = 0;
        lp.rightMargin = 0;
        //数据是px
        int temptopMargin = DisplayUtils.dip2px(this, 20);
        lp.topMargin = temptopMargin;
        lp.bottomMargin = 0;
        mTvCode.setLayoutParams(lp);
        
    }
}

Just have said, setTextSize () If you are in an argument, the value of the unit is sp so write directly setTextSize (40) can be.
If you want to use two parameters, written as:

mTvCode.setTextSize(TypedValue.COMPLEX_UNIT_PX,DisplayUtils.sp2px(this,40));

And setMargin way, because the unit is assigned px, and so we need to start the 20dp px dp turn after the assignment, namely:

 int temptopMargin = DisplayUtils.dip2px(this, 20);
 lp.topMargin = temptopMargin;

This is a mobile phone A breakpoint test data. (Resolution: 1080 * 2160)
Write pictures described here

This is the mobile phone B break test data. (Resolution: 720 * 1280)
Write pictures described here

(2) Information (TestTextView.class above code snippet) Custom control:

① set the font size

      int initTextSize = typedArray.getDimensionPixelOffset(R.styleable.TestTextView_testTextSize, DisplayUtils.sp2px(mContext, 40));
      
      setTextSize(TypedValue.COMPLEX_UNIT_PX,initTextSize);

② Set spacing


marginTop = typedArray.getDimensionPixelOffset(R.styleable.TestTextView_testTextMarginTop, DisplayUtils.dip2px(mContext,20));
          
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) getLayoutParams();
Log.e("测试元素", "init: " + this);
lp.leftMargin = 0;
lp.rightMargin = 0;
//数据是px
lp.topMargin = marginTop;
lp.bottomMargin = 0;
setLayoutParams(lp);

The same, typedArray.getDimensionPixelOffset acquired values ​​are in PX. SetMargin the unit value PX is required. Therefore, direct use can No (can not be converted)

This is a mobile phone A breakpoint test data
Write pictures described here

This is the mobile phone B break test data
Write pictures described here

720 in particular handset B becomes clear data 1280 (720 1280 Mobile Resolution: 1dp = 2px)

After running function,

Effect on the phone A is as follows

Write pictures described here

Effect on the phone B are as follows
Write pictures described here

Can be found, whether it is that a three outcomes, font size, spacing, and controls on top of the same. In order to verify the feasibility of the method.

Guess you like

Origin blog.csdn.net/gaolh89/article/details/81161584