1-什么是UI?
用户界面,所有UI控件都是继承View
通读View的源码
UI的呈现
需要掌握本身的呈现和放在哪里(布局)
呈现方式
- xml
- 动态代码(动态布局和动态绘制控件)
UI的事件
Canvas
SurfaceView
使得UI的呈现更加高效、平滑、高效
View的设置
myView = new MyView(this);
setContentView(myView); //设置新的样式
每次准备重画的时候调用invalidate
- 如果想在一个线程中请求
invalidate
而不是在main activity's thread
中,你必须调用postInvalidate()
2-view、window、activity的关系
链接:http://www.cnblogs.com/loulijun/archive/2012/02/09/2344681.html
3-动态获得控件
方法一
//动态设置控件
LinearLayout linearLayout = new LinearLayout(this);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
linearLayout.setLayoutParams(layoutParams);//设置
Button button = new Button(this);
button.setText("Hello");
linearLayout.addView(button);//增加到线型布局中
setContentView(linearLayout); //显示到Window中
这段代码,实际上存在两个
FrameLayout
,第一个中具有TextView
,第二个中包含LinearLayout
和Button
DecorView是Window最顶层的View
链接:http://blog.csdn.net/sunny2come/article/details/8899138
方法二
Button button = new Button(this);
button.setText("Hello");
button.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
setContentView(button); //显示到Window中
因为本身就有一个LinearLayout因此,直接setContentView()
是可以的
4-自定义View的简单示例
CustomView
public class CustomView extends View {
public CustomView(Context context) {
super(context);
}
//canvas画布
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画笔
Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawRect(10, 10, 90, 90, paint);//画矩形
}
}
- 重载
overide
使用自定义View
CustomView customView = new CustomView(this);
setContentView(customView); //显示到Window中
- 因为父控件是
framelayout
因此,是铺满的。
5-界面Compoent是如何呈现出来的?
- Application
- Java View/Widget/Canvas 2D | OpenGL 3D
- Skia(负责界面的呈现,进行封装后就是上层的
View/Widget/Canvas
) - Surface
framebuffer是什么?
图像驱动
6-Andorid界面事件
分类
- KeyEvent—硬按键,如:回退键、Home键
- TouchEvent—按下,拖动,多点触控,长按等
- TrackballEvent—轨迹球(基本废弃)
使用
- 注册事件监听器(外部的)
- 扩展View的时候回调事件函数(内部的)
代码实例-硬按键
- 在CustomView重载相应方法
//点击键盘
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {//用于检测按了一下,如果用DOWN一般是长按
if(keyCode == KeyEvent.KEYCODE_DPAD_DOWN)
{
Log.i("feather_log", "Center Clicked");
}
return super.onKeyUp(keyCode, event);
}
代码实例-按下、长按等
//触摸事件
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) //按下时触发
{
Log.i("feather_log", "onTouchEvent");
}
return super.onTouchEvent(event);
}
按键消息的传递流程
先递交给上下文,然后发给window
然后给ViewTree
,然后从根源处找到焦点元素,然后进行处理
事件分发(dispatch)和上传机制
例如:listview不是直接在每个TextView之类控件里调用onClick
而是全部将事件上传。由index
属性来处理。
- 自定义复杂控件的时候也需要考虑这种机制
长按监听器实例
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) //按下
{
Log.i("feather_log", "CustomViewActivity action down");
}
else if(event.getAction() == MotionEvent.ACTION_UP)//松开
{
Log.i("feather_log", "CustomViewActivity action up");
event.getDownTime();//返回开始按下(导致位置事件发生)后的时间
event.getEventTime(); //返回事件发生的时间
if(event.getEventTime() - event.getDownTime() > 3000)
{
Log.i("feather_log", "CustomViewActivity long click");
}
}
return super.onTouchEvent(event);
}
7-Canvas/Drawble
Canvas绘图实例
onDraw中
//canvas画布
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画笔
Paint paint = new Paint();
paint.setColor(Color.RED);
//画矩形
canvas.drawRect(100, 100, 200, 200, paint);
//绘制文本
paint.setColor(Color.BLACK);
canvas.drawText("Hello world", 100, 100, paint);
//绘制椭圆
paint.setColor(Color.BLUE);//颜色
paint.setAntiAlias(true);//抗锯齿
paint.setStrokeWidth(10);
RectF rectF = new RectF(120, 120, 200, 250);//
canvas.drawOval(rectF, paint);//绘制
}
- 商业界面更多的是画图,很少需要这些内容
Matrix
//使用matrix
Matrix matrix = new Matrix();
matrix.setRotate(15f); //旋转
matrix.setScale(2,2); //大小
canvas.setMatrix(matrix);
Clip裁剪
canvas.clipRect(210, 210, 298, 297); //裁剪矩形
教学链接:http://ipjmc.iteye.com/blog/1299476
Canvas的save和restore
//画布旋转等相应操作
canvas.save();
链接:http://www.cnblogs.com/xirihanlin/archive/2009/07/24/1530246.html
Drawble绘制组件
- Drawble是抽象类,用于所有能画出的内容
setBounds
方法一定会被调用drawble
推荐使用png,可以使用jpg
,不推荐jpg
Drawble
有很多,常用的是BitmapDrawble
此外有动画等各种Drawble
简单实例
public class DrawableView extends View {
BitmapDrawable bitmapDrawable = null;
public DrawableView(Context context) {
super(context);
bitmapDrawable = (BitmapDrawable)getResources().getDrawable(R.drawable.question_correct_24dp); //初始化
bitmapDrawable.setBounds(100, 100, 150, 150);//设置范围大小
//bitmapDrawable.getBitmap(); //获取bitmap
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
bitmapDrawable.draw(canvas); //绘制
}
}
nine patch(九宫图)
例如Button
应该自适应内容,这就是九宫图
的作用
使用:tool/draw9patch.bat
UI相关问题
View类是所有控件的基类,他和Activity的关系是什么?
- activity相当于控制部分,view相当于显示部分。两者之间是多对多的关系,所有东西必须用view来显示。
viewGroup继承自view,实现了ViewManager,ViewParent接口,主要用作layout方面。 - Activity中加载相应的view才能显示出画面来,view是具体的画面布局(layout),由wegit控件组成。
好比view是jsp实现前台画面,activity是java程序,处理具体业务逻辑 - 基本上每个activity都有对应的view,
activity用于控制view中的响应,如button的点击事件等可以在activity中实现,但是你得把这个button给用户看到啊,所以就用view现实了~ - activity就是一个容器,view只能在这个container里才能正常工作。
- Activity主要是控制部分;View主要负责显示界面
View的核心是什么,介绍里面的onDraw函数
自定义组件如何实现自定义事件
如自定义事件OnFeatherClick
如何实现?