英寸:显示屏的尺寸用对角线的长度表示,单位为英寸,1英寸:25.4mm;

px:像素点,图像是由像素点组成的

ppi (pixels per inch):分辨率 (在图像中,每英寸所包含的像素数目),如480x800就是在长度方向有480个像素点,在宽度方向有800个像素点,一共是由480X800个像素点组成。屏幕为4寸,那么分辨率计算是:
480的平方+800的平方,将和开方,再除以4;

dp:在一个160分辨率的屏幕下,1dp就是1px。

dp和dx换算公式
dp*ppi/160 = px。比如1dp x 320ppi/160 = 2px。

为什么android控件尺寸用dp,而不是px?
因为用px会因为不同分辨率的屏幕的改变而改变,比如100px的button,在480X800的分辨率下会占屏幕长度大概四分之一的位置,但是在屏幕分辨率为1080X1920的屏幕分辨率下只占到大概十分之一的位置;如果用dp的话,dp是一个相对单位,不会因为屏幕分辨率的改变而改变很大。
比如100dp的button因为ppi的不同就换算为了不同的px,适配了屏幕。

结论:控件尺寸用dp;字体大小用sp,细横线用px(dp太大);

LayoutInflater:用于将xml文件转换成View;
获得LayoutInflater对象的三种方法:

public class MainActivity extends AppCompatActivity {
private LayoutInflater inflater=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        inflater=getLayoutInflater();
        inflater= (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        inflater=LayoutInflater.from(this);
    }
}

在这里插入图片描述
Demo:
//自定义控件:定义一个红色的圆,中间是数字20,每点击一次,数字减一,直到为零。
//自定义控件属性,可以改变圆的颜色,文本的颜色。

MyRedButton.class


//自定义控件:定义一个红色的圆,中间是数字20,每点击一次,数字减一,直到为零。

/*步骤:
1,创建一个MyRedButton继承自View
2,重写构造函数(三个),创建init方法,在init里创建对象,初始化对象,不可以draw方法中创建对象,因为onDraw方法会被频繁调用
3,重写onDraw方法,在里面绘画,不要忘了invalidate()
//自定义控件属性,可以改变圆的颜色,文本的颜色。
1,创建自定义属性的xml资源文件
2,获取对应属性,赋给onDraw作为绘制的参数


*/

public class MyRedButton extends View {
    private Paint paint=null;
    private int number;
    private String numberText;
    private Rect rect;
    private int backgroundColor;

    //    在第一和第二个构造函数中都时候了this,所以无论用哪个构造函数都会调用到init()
    public MyRedButton(Context context) {//在new的时候会调用
        this(context,null);//用this代替super,将会调用第二个构造函数
    }

    public MyRedButton(Context context, @Nullable AttributeSet attrs) {//在xml的时候会调用,AttributeSet指MyRedButton在布局文件属性集
        this(context, attrs,0);//用this代替super,将会调用第三个构造函数
    }

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

    private void init(Context context,AttributeSet attrs) {
        paint =new Paint();
        number=20;
        rect=new Rect();
//获取R.styleable.MyRedButton的自定义属性集合
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyRedButton);
//        获取布局文件中设定的背景颜色
        backgroundColor=typedArray.getColor(R.styleable.MyRedButton_backgroundColorlor,Color.BLUE);
//   每点击一次,数字减一,直到为零。
        setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if(number>0){
                    number--;
                }
                invalidate();
            }
        });
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int x=getWidth()/2;//getWidth()获得的是布局文件中制定控件的宽度,如在布局文件的MyRedButton控件的 android:layout_width="200dp"
        int y=getHeight()/2;//同理
        paint.setColor(backgroundColor);
//        画圆
        canvas.drawCircle(x,y,getWidth()/2,paint);//xy为圆心坐标
        paint.setColor(Color.WHITE);
        paint.setTextSize(200);
        numberText=String.valueOf(number);
        paint.getTextBounds(numberText,0,numberText.length(),rect);//获取能包裹文本的rect,
//start表示开始度量的第一个字符串的下标,end表示比字符串中要度量的最后一个字符多1,所以不是numberText.length()-1
        int textWidth=rect.width();//为了让文本显示在中心,要将文本的绘制x坐标位置设为为圆心x坐标位置-包裹文本的rect的宽/2
        int textHeight=rect.height();//为了让文本显示在中心,要将文本的绘制基线位置设为为圆心坐标位置-+包裹文本的rect的高/2
        canvas.drawText(numberText,x-textWidth/2,y+textHeight/2,paint);//x为文本远点x坐标,y为文本基线位置
        invalidate();
    }

}

如何自定义视图属性:
在res目录下的values目录下创建资源文件,命名为attrs.xml;

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyRedButton">
        <attr name="backgroundColorlor" format="color"></attr>
    </declare-styleable>
</resources>

效果:
在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐