基于Android UI组件的实现原理,开发者完全可以开发出项目定制的组件,即当Android系统提供的UI组件不足以满足项目需要时,开发者可以通过继承View来派生自定义组件。
当开发者打算派生自己的UI组件时,首先定义一个继承View基类的子类,然后重写View类的一个或多个方法。通常可以被用户重写的方法下:
View的方法
当需要自定义开发View时,不需要重写下面的所有方法,可以根据业务的需求重写下面的方法
构造器:重写构造器是定制View的最基本的方式,当Java代码创建一个View实例,或根据XML布局文件加载并构建界面是将需要调用该构造器
onFinishInflate():这是一个回调方法,当应用从XML布局文件加载该组件并利用它来构建界面之后,该方法将会被回调。
onLayout(boolean,int,int,int,int):当该组件需要分配其子组件位置的、大小时,该方法就会被回调。
onSizeChanged(int,int,int,int): 当该组件的大小发生改变时回调该方法。
onDraw(Canvas):当该组件将要回执它的内容时回调该方法进行绘制。
onKeyDown(int,KeyEvent):当某个键被按下时出发该方法。
onKeyUp(int,KeyEvent):当松开摸个键时触发该方法。
onTrackballEvent(MotionEvent):放发生轨迹球时间时触发该方法
onTouchEvent(MotionEvent):当发生触摸屏事件时触发该方法。
onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect):当该组件焦点发生改变时触发该方法。
onWindowFocusChanged(boolean):当包含该组件的窗口失去或得到焦点时触发该方法。
onAttachedToWindow():当把该组件放入某个窗口时触发该方法。
onDetachedFromWindow():当把该组件从某个窗口上分离时触发该方法。
onWindowVisibilityChanged(int):当包含该组件的窗口的可见性发生改变时触发该方法。举例
自定义一个子类继承自View
public class CustomView extends View{}
在布局界面定义该控件 为该类的 包名.类名
<包名.CustomView
android:id="@+id/***"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
画图
@Override
protected void onDraw(Canvas canvas) {
try {
Paint paint=new Paint();
paint.setColor(Color.RED);
//用矩形画背景
Rect rect=new Rect
(0, 0, viewWidth, viewHeight);
canvas.drawRect(rect, paint);
//在布局文件中单位可以是dp,sp,px
//在代码的单位是px
paint.setTextSize(30);
//得文字宽度
Rect stringSizeRect=new Rect();
String lastTime=list.get(list.size()-1)
.get("time");
paint.getTextBounds
(lastTime, 0, lastTime.length(),
stringSizeRect);
int lastTimeWidth=stringSizeRect.width();
gap=(viewWidth-lastTimeWidth*2)/(list.size()-1);
paint.setColor(Color.WHITE);
int priceHeight=viewHeight-
stringSizeRect.height();
//画时间
for(int i=0;i<list.size();i++)
{
HashMap<String, String> map=
list.get(i);
String time=map.get("time");
canvas.drawText
(time, i*gap, viewHeight, paint);
//画价格
String strCurrentPrice=map.get("price");
int intCurrentPrice=Integer.parseInt
(strCurrentPrice);
int priceY=intCurrentPrice*priceHeight
/maxPrice;
priceY=priceHeight-priceY;
//最大的价格画到控件外面,要向下移
priceY=priceY+stringSizeRect.height();
canvas.drawText(strCurrentPrice,
i*gap, priceY, paint);
//画线
if (i<list.size()-1)
{
int startX=i*gap;
int startY=priceY;
int stopX=(i+1)*gap;
int stopY=0;
int nextPrice=Integer.parseInt
(list.get(i+1).get("price"));
stopY=nextPrice*priceHeight/maxPrice;
stopY=priceHeight-stopY;
stopY=stopY+stringSizeRect.height();
canvas.drawLine
(startX, startY, stopX, stopY, paint);
}
}
//从左到右画线
if (lineY>0)
{
canvas.drawLine
(0, lineY, viewWidth, lineY, paint);
}
} catch (Exception e) {
e.printStackTrace();
}
}
在MainActivity 中
Handler handler = new Handler();
boolean isRunning = true;
boolean isExit=false;
@Override
protected void onDestroy() {
isExit=true;
super.onDestroy();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
Log.i("onTouchEvent", "" + action);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
isRunning = !isRunning;
}
Log.i("onTouchEvent", "isRunning=" + isRunning);
return super.onTouchEvent(event);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<HashMap<String, String>> list = getData();
Log.i("", "" + list.size());
final CustomView customView = (CustomView) findViewById(R.id.customView);
customView.setData(list);
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (isRunning) {
customView.setData(getData());
// 调用onDraw()
// 直接调不行
// customView.onDraw(canvas);
// 间接调onDraw()
// invalidate 无效--》屏幕无效--》重新绘制
// handler.sendMessage 间接调用handleMessage
// sendBroadcast间接调用onReceiver
// 更新view 1,invalidate 2,notifyDataSetchanged
customView.invalidate();
}
//用到线程,必须保存线程能结束。
if (isExit==false)
{
handler.postDelayed(this, 1000);
}
Log.i("handler.postDelayed", "run" + System.currentTimeMillis());
}
}, 1000);
}
Random random = new Random();
public ArrayList<HashMap<String, String>> getData() {
// 9 3200
// 10 5000
// 数据类型表示
ArrayList<HashMap<String, String>> list = new ArrayList();
HashMap<String, String> map = new HashMap();
map.put("time", "9");
map.put("price", String.valueOf(random.nextInt(8000)));
list.add(map);
map = new HashMap();
map.put("time", "10");
map.put("price", String.valueOf(random.nextInt(8000)));
list.add(map);
map = new HashMap();
map.put("time", "11");
map.put("price", String.valueOf(random.nextInt(8000)));
list.add(map);
map = new HashMap();
map.put("time", "13");
map.put("price", String.valueOf(random.nextInt(8000)));
list.add(map);
return list;
}
这是一个图表的项目,希望对大家能有帮助