Android高级应用开发(基础篇) - stage6 - 学习笔记(上)

用户交互设计师 —— 给想法和具体UI设计草图

视觉设计师(美工) —— 实现想法 -> 真正的界面效果图

界面实践 —— 程序员 —— 视觉设计师(编码能力强的)

 

为何我们界面要用XML?

可以分离,程序员可以不用去管xml的layout,由视觉设计师来实现

 

WP开发中通用





UI component

一、UI的呈现和布局

1、呈现的两种方式

(1)XML Layout的呈现(最后也会被转换为View界面)

(2)动态编码呈现:动态布局、画动态空间

2、呈现的核心,牢牢把握住onDraw(平面图像Graphic——Canvas&Drawable简单介绍)


我们可以通过hierarchyviewer.bat来查看一下应用的界面层级关系



最根部的是PhoneWindow的DevorView

他下面的LinearLayout包含两个FrameLayout

上面的FrameLayout是默认的应用程序的标题栏(NOTITLE隐藏的那部分)

下面的FrameLayout是用户定义的界面的父界面,用户定义的界面都在这棵树下


我们查看一下PhoneWindow的源码,我们知道PhoneWindow是对Window的一个实现

我们可以看到DecorView是PhoneWindow的一个内部类,也是一个FrameLayout




实际上显示是需要下层的支持的,看下下层是什么样子


最下面是Surface,是一个平滑过渡的类库(机制),称为SurfaceFlinger(界面显示的基础)

需要FrameBuffer驱动的支持,都是在内核里实现的

Skia是2D图形界面的显示引擎(图形显示库),再次基础上封装View、Widget和Canvas等

OpenGL是3D图形界面的显示引擎


二、UI的事件

1、Android界面事件分类

·KeyEvent

·TouchEvent

·TrackableEvent(轨迹球)

2、Android界面事件的出发及分发

(一)事件触发的两种方法

·扩展View的时候回调事件函数(内部)

·注册事件监听器(外部)

(二)时间分发dispatchKeyEvent

(1)KeyEvent分发

·消息发到当前上下文

·Context发到Window

·Window优先发给输入法窗体

·发给rootView(DecorView)

·发给焦点子View



@Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {

        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER){
            Log.i("log", "center clicked");
        }

        // If you handled the event, return true. 
        // If you want to allow the event to be handled by the next receiver, return false.
        return super.onKeyUp(keyCode, event);
    }


注意:按钮的点击需要View获得焦点,需要在构造其中获取焦点

setFocusable(true);
setFocusableInTouchMode(true);


(2)touchEvent分发

·从下往上

@Override
 public boolean onTouchEvent(MotionEvent event) {
        
        if (event.getAction() == MotionEvent.ACTION_DOWN){
            Log.i("log", "on clicked");    
        } else if (event.getAction() == MotionEvent.ACTION_UP){
	    if(event.getActionTime() - event.getDownTime() > 3000){
                  Log.i("log", "long click");
            }
        }

        
        return super.onTouchEvent(event);
    }




对事件进行处理时,两种事件的处理方式不同




·




根据这些,我们就可以判断事件到底应该由Activity处理,还是在View内处理

一定要理解分发和上传的概念


Canvas & Drawable

用Canvas画图

基本的Canvas用法

1、常用的draw**方法

drawRect长方形

drawCircle圆

drawOval椭圆

drawPath路径

drawLine线

drawPoint点

drawText文字

drawColor颜色、背景色

drawBitmap图片

2、clip & matrix

3、save & restore

@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		
		Paint paint = new Paint();
		paint.setColor(Color.RED);
		
		// drawColor
		canvas.drawColor(Color.LTGRAY);
		
		// drawRect
		canvas.drawRect(10, 10, 90, 90, paint);
		
		paint.setColor(Color.Black);
		
		// drawText
		canvas.drawText("hello", 20, 20, paint);
		
		paint.setColor(Color.BLUE);
		paint.setAntiAlias(true); // 抗锯齿

		//drawOval
		RectF oval = new RectF(20, 20, 120, 120);
		canvas.drawOval(oval, paint);
	}


变形和裁剪

@Override
    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);


        Matrix matrix = new Matrix();
        matrix.setRotate(15.0f); // 旋转
        matrix.setScale(2, 2); // 缩放
        canvas.setMatrix(matrix); // 画布被变形

        // clip 裁剪
        canvas.clipRect(20, 20, 80, 70); 
    }



 

如果不想整个画布都旋转,而是旋转某些部件,怎么办

@Override
    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);

        Paint paint = new Paint();
        paint.setColor(Color.RED);

        // drawColor
        canvas.drawColor(Color.LTGRAY);

        // drawRect
        canvas.drawRect(10, 10, 90, 90, paint);
        
        canvas.rotate(45.0f); // 画布旋转45度
        canvas.save(); // 保存一下画布

        paint.setColor(Color.Black);

        // drawText
        canvas.drawText("hello", 20, 20, paint);

        paint.setColor(Color.BLUE);
        paint.setAntiAlias(true);

        //drawOval
        RectF oval = new RectF(20, 20, 120, 120);
        canvas.drawOval(oval, paint);

        canvas.restore();  // 恢复画布
    }



 了解SurfaceView:双缓存机制


Drawable

常用Drawable

BitmapDrawable,ShapreDrawable,PictureDrawable,LayoutDrawable,……,自定义Drawable

定义和实现Drawable的方法

1、用资源文件中的图片

Android中支持的图片格式:png(推荐),jpg(可接受),gif(不推荐)

public class DrawableView extends View {

    BitmapDrawable mBitmapDrawable;

    public DrawableView(Context context) {
        super(context);

        mBitmapDrawable = (BitmapDrawable)getResources().getDrawable(R.drawable.image);
        mBitmapDrawable.setBounds(10, 10, 135, 160);


    }

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

        // mBitmapDrawable最终要画到画布上
        // 方法1:可以用getBitmap()得到图片
        canvas.drawBitmap(mBitmapDrawable.getBitmap(), ...);
        
        // 方法2:可以把canvas画布当做参数传给BitmapDrawable对象
        mBitmapDrawable.draw(canvas);
    }
}

注意:BitmapDrawable必须设置setBounds属性!!!


2、从XML文件中生成

例如TransitionDrawable可以将两张图片放到XML文件中,然后使用

 res/drawable/transition.xml

<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/on" />
    <item android:drawable="@drawable/off" />
</transition>

<ImageButton
    android:id="@+id/button"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:src="@drawable/transition" />

ImageButton button = (ImageButton) findViewById(R.id.button);
TransitionDrawable drawable = (TransitionDrawable) button.getDrawable();
drawable.startTransition(500);


3、编码构造,自定义Drawable


Nine-Patch (draw9pathc.bat工具)

Nine-Patch是一个标准的PNG图像,它包括额外的1个像素的边界

你必须保存它为9.png并且保持到工程的res/drawable目录中

如果是从apk解压后得到的*.9.png文件,注意它是已将周围的空白像素去掉了的,

再使用时必须加上


注意:

左边跟顶部的线定义的是伸缩区域,定义哪些图像的像素允许在伸缩时被复制

右边跟底部的线是可选的,定义的是相对位置内的图像,视图内容放在这部分区域内




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值