Geekband003第三周笔记分享

px dp sp 的区别

  1. px : 一个像素点 ,如手机分辨率320*480表示宽有320像素,高有480像素。
  2. dpi : dots per inch, 打印分辨率 (每英寸所能打印的点数,即打印精度)假如我们知道一部手机的分辨率是1080×1920,屏幕大小是5英寸,根据公式计算结果是440dpi。
    dp=dip(Density-independent pixels),基于屏幕物理分辨率一个抽象的单位,用于说明与密度无关的尺寸和位置。
    px = dp*dpi/160
    dp = px*160/dpi
    从公式可以看出,公式的由来是已160dpi的屏幕为基准,此时该屏幕1dp=1px。如果320dpi的屏幕上,公式推导可得1dp = 2px。
    dp更类似一个物理尺寸,比如一张宽和高均为100dp的图片在320×480和480×800的手机上“看起来”一样大。而实际上,它们的像素值并不一样。dp正是这样一个尺寸,不管这个屏幕的密度是多少,屏幕上相同dp大小的元素看起来始终差不多大。
  3. sp :Scale-independent Pixels - 和dp单位很像,不过sp可以通过用户设置的字体大小而缩放. 为了能够自适应屏幕密度和用户的设置,建议设置字体大小时候用sp.当安卓系统字号设为“普通”时,sp=dp.
    系统定义dpi图解
    这里写图片描述

Inflater
将xml布局解析成视图view
在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;而findViewById()是找xml布局文件下的具体widget控件(如Button、TextView等)。 具体作用: 1、对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入;

获得 LayoutInflater 实例的三种方式

1.LayoutInflater inflater = getLayoutInflater(); //调用Activity的getLayoutInflater()

2.LayoutInflater localinflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
3. LayoutInflater inflater = LayoutInflater.from(context);

这三种方式最终本质是都是调用的Context.getSystemService()。

style/theme
可以将共同的属性拿出来放在styles.xml文件中

自定义控件
自定义的控件继承自View,初始化代码应该使用如下形式

public class CircleBackgroundView extends View {
    public CircleBackgroundView(Context context) {
        this(context, null);
    }

    public CircleBackgroundView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CircleBackgroundView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }
}

之后在xml中跟正常控件一样使用就可以

对图像界面的刷新可以使用invalidate();

如下为画一个圆以及可以指定角度的圆弧的代码

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // draw background circle
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(Color.WHITE);
        mPaint.setStrokeWidth(5);
        mPaint.setAntiAlias(true);
        mCircleRectf.set(getWidth()/32, getWidth()/32, getWidth()*31/32, getWidth()*31/32);
        canvas.drawArc(mCircleRectf,0,360,false,mPaint);

        // draw the red Arc
        mPaint.setColor(ContextCompat.getColor(getContext(),R.color.red));
        mPaint.setAntiAlias(true);
        canvas.drawArc(mCircleRectf, 270, mAngle, false, mPaint);
    }

如下为暂停按钮的代码

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int width = getWidth();
        int height = getHeight();

        // draw red background circle
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(ContextCompat.getColor(getContext(),R.color.red));
        canvas.drawCircle(width/2,width/2,width/2,mPaint);


        mPaint.setColor(Color.WHITE);
        mPaint.setStrokeWidth(5);
        canvas.drawLine(width*4/10, width*3/10, width*4/10, width*7/10,mPaint);
        canvas.drawLine(width*6/10, width*3/10, width*6/10, width*7/10,mPaint);
    }

如下为开始按钮的代码

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int width = getWidth();
        int height = getHeight();

        // draw red background circle
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(ContextCompat.getColor(getContext(),R.color.red));
        canvas.drawCircle(width/2,width/2,width/2,mPaint);

        mPaint.setColor(Color.WHITE);
        mPaint.setStrokeWidth(5);

        mPath.moveTo(width*4/10,width*3/10);
        mPath.lineTo(width*3/4,width/2);
        mPath.lineTo(width*4/10,width*7/10);
        mPath.close(); // 使这些点构成封闭的多边形
        canvas.drawPath(mPath, mPaint);

    }

如下为清空按钮的代码

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int width = getWidth();
        int height = getHeight();

        // draw red background circle
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(Color.WHITE);
        mPaint.setStrokeWidth(5);
        mCircleRectf.set(width/8, width/8, width*7/8, width*7/8);
        canvas.drawArc(mCircleRectf, 270, 315, false, mPaint);
        canvas.drawLine(width/8,width/8,width*7/20,width*7/20,mPaint);
    }

其效果如下图

Fragment
Fragment必须是依存与Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期。官网这张图很好的说明了两者生命周期的关系:
这里写图片描述

使用Fragment最简单的一种方式,把Fragment当成普通的控件,直接写在Activity的布局文件中。步骤:
1、继承Fragment,重写onCreateView决定Fragemnt的布局
2、在Activity中声明此Fragment,就当和普通的View一样

如何管理Fragment?
查找Fragment
1. findFragmentById()
2. findFragmentByTag()
Fragment的后退
1. Fragment Stack
2. popBackStack()
3. addOnBackStackChangedListerner()
Fragment的管理
1. FragmentManager
2. FragmentTransaction
3. Add/Remove

Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。

Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。

MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。

Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。

Thread:线程,负责调度整个消息循环,即消息循环的执行场所。

在主线程中,使用handler很简单,new一个Handler对象实现其handleMessage方法,在handleMessage中
提供收到消息后相应的处理方法即可

新建message并通过handler发送消息代码

void startTimer() {
        timer = new Timer();
        timerTask = new TimerTask() {
            @Override
            public void run() {
                timeMessage = timeHandler.obtainMessage();
                timeMessage.what = START_MESSAGE_CODE;
                timeHandler.sendMessage(timeMessage);
            }
        };
        timer.schedule(timerTask,0,10);
    }

在handler类中重写一个handlerMessage的函数进行处理message

@Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            MainActivity mainActivity = mainActivityWeakReference.get();
            switch (msg.what) {
                case START_MESSAGE_CODE:
                    totalCentiSceond++;
                    partCentiSecond++;
                    mainActivity.repaint(totalCentiSceond);
                    break;
                case COUNT_MESSAGE_CODE:
                    mainActivity.repaint(totalCentiSceond);
                    mainActivity.addResult(partCentiSecond,totalCentiSceond);
                    partCentiSecond = 0;
                    break;
                case CLEAR_MESSAGE_CODE:
                    totalCentiSceond = 0;
                    partCentiSecond = 0;
                    mainActivity.repaint(0);
                    mainActivity.clearResult();
                    break;
            }
        }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值