我一直都沒有太搞明白Android到底是怎麼繪圖的,和繪圖有關的概念實在太多了,我從來就沒搞清楚過……
幸好,我也算是琢磨出了一套畫圖的解決方案吧,主要是利用view的onDraw函數來畫的。
onDraw函數是一個回調函數,系統會在他覺得這個view需要重繪的時候調用這個函數,所以他畫的圖肯定是對的,不過他一重繪就是全部重繪,如果你每次只是額外添加東西的話,我總感覺不值…… 不像Windows GDI,你可以獲取DC以後隨便搞,安卓似乎不行,最保險的方法還是用onDraw。
怎麼用onDraw呢?首先我們需要自己寫一個類來繼承ImageView類,當然繼承View也可以……
public class SuperImageView extends ImageView
{
Paint paint;
Bitmap bmp=BitmapFactory.decodeResource(this.getContext().getResources(), R.drawable.pic2);//如果要畫文件裏的圖,需要先decode
PointType touchPoint;
PointType MAP_ORIGIN;
List<PointType> toDraw;
public SuperImageView(Context context)
{
super(context);
// TODO Auto-generated constructor stub
}
public SuperImageView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
public SuperImageView(Context context, AttributeSet attrs)
{
super(context, attrs);
// TODO Auto-generated constructor stub
}
//以上都是構造函數,照抄即可,對我們沒用
public void setTouchPoint(PointType p)
{
touchPoint = p;
return;
}
public void setPointList(List<PointType> list)
{
toDraw = list;
return;
}
public void setMapOrigin(PointType origin)
{
MAP_ORIGIN = origin;
return;
}
//一般都是把信息設好,然後讓他重畫
@Override
//這裏就是神奇的onDraw函數,已經給你提供canvas了,就在這兒隨便怎麼畫都是對的,比如這裏會把一個List裏面所有的點畫出來,以及如果TouchPoint不爲空的話,也把TouchPoint畫出來
protected void onDraw(Canvas canvas)
{
// TODO Auto-generated method stub
super.onDraw(canvas);
canvas.drawBitmap(bmp, 0, 0, null);
Paint paint = new Paint();
paint.setColor(Color.BLUE);
int i;
for(i=0; i<toDraw.size();i++)
{
PointType now = toDraw.get(i);
PointType tmp = new PointType(now.x, now.y);
tmp = tmp.XYtoView(MAP_ORIGIN);
canvas.drawCircle((float)tmp.x, (float)tmp.y, 2, paint);
}
//Draw touchPoint
paint.setColor(Color.RED);
if(touchPoint != null)
canvas.drawCircle( (float)touchPoint.x, (float)touchPoint.y, 10, paint);
return;
}
}
<com.example.remoteapp.SuperImageView
android:id="@+id/picView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="center"
android:src="@drawable/pic2" />
然後,需要重繪的時候,調用一下這個類的invalidate()方法就行了,就像這樣:
imageView.setOnTouchListener(new OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent e)
{
// TODO Auto-generated method stub
PointType point = new PointType();
point.x=e.getX();
point.y=e.getY();
point = point.screenToView(currentDegree/180*Math.PI);
now_point = point;
imageView.setTouchPoint(now_point);//set信息
imageView.invalidate();//重畫
return false;
}
});