Android利用Canvas標點畫線并加入位移動畫(2)
本文實例為大家分享了Android利用Canvas標點畫線,并加入位移動畫的具體代碼,供大家參考,具體內容如下
1.背景
繼上次公司需求實現Canvas面板標記點,畫折現,并利用屬性動畫進行沿線移動之后,又有了新問題。
發(fā)現公司提供的坐標有正值有負值,并且值很大,很容易超出屏幕范圍,而且由于我們Canvas坐標方向與正常坐標系不符合,由此發(fā)現做的圖方向也不對。
2.問題
Canvas坐標系位于屏幕左上角,且Y正向坐標向下,如何轉換?
由于坐標有正有負,而Canvas默認只顯示正方向,如何解決顯示點問題?
坐標數值很大,采用哪種方法進行顯示?
隨之而來的動畫坐標,移動問題?
3.先看最終實現效果圖
這次繼續(xù)圖片顯示哈,小人依然能沿線移動!
4. 思路
首先我看到拿到的數據坐標是這樣的
這是正常坐標系坐標,有±,且數值大。而Canvas默認坐標系是這樣的,且屏幕內坐標很小
知道問題,那么開始解決!!
首先要轉換Canvas坐標系,并且采用采用縮小坐標的方式,容納值很大的坐標點,并且將做坐標原點移動到屏幕中央。
Canvas有縮放方法,且能改變原點位置,改變坐標系方向!
final void scale(float sx, float sy, float px, float py)
sx,sy即為放大縮放倍數,±代表方向,px,py則為縮放/放大后,,原點移動的位置?,F在倒是可以顯示點,畫線了。那么屬性動畫的坐標原點系依然在左上角,而它沒有縮放方法,怎么實現小人沿著軌跡移動呢?
那只能利用坐標系進行換算了!
/** ?* ? canvas.scale(0.4F,0.4F,850,1500); ?* ? 則動畫坐標 ?X: x*0.4+850*0.6 ? ? ?* ? ? ? ? ? ? Y: y*0.4+1500*0.6 ?? ?* ?----------------new------------------ ?* ? canvas.scale(0.5F,0.5F,1000,2200); ?* ? 則動畫坐標 ?X: x*0.5+850*0.5 ? ? ?* ? ? ? ? ? ? ?Y: y*0.5+1500*0.5 ? ?* ? ? ? ? 即 ? X: (x+850)*0.5 ?* ? ? ? ? ? ? ?Y: (y+1100)*0.5 * */
具體實現代碼
DrawView
class DrawView extends View { ? ? ? private Boolean bool=false; ? ? private String num; ? ? private Path path; ? ? ? public DrawView(Context context) { ? ? ? ? super(context); ? ? } ? ? public void setBool(Boolean isDraw,String number){ ? ? ? ? this.bool=isDraw; ? ? ? ? this.num=number; ? ? } ? ? ? public void DrawLines(Canvas canvas){ ? ? ? ? Paint mPaint3 = new Paint(); ? ? ? ? mPaint3.setAntiAlias(true); ? ? ? ? mPaint3.setColor(Color.GREEN); ? ? ? ? mPaint3.setTextSize(36); ? ? ? ? mPaint3.setStrokeWidth(20); ? ? ? ? float[] points3=new float[]{450,100,480,350,480,350,330,500,330,500,510,650,510,650,780,800,780,800,450,900,450,900,450,1200,450,1200,550,1400,550,1400,600,1500}; ? ? ? ? canvas.drawLines(points3,mPaint3); ? ? } ? ? ? @Override ? ? public void onDraw(Canvas canvas) { ? ? ? ? super.onDraw(canvas); ? ? // ? canvas.scale(0.4F,0.4F,850,1500); ? ? ? ? canvas.scale(0.5F,0.5F,1000,2200); ? ? ? ? ? ?path = new Path(); ? ? ? ? /* ? ? ? ? ?* 方法 說明 drawRect 繪制矩形 drawCircle 繪制圓形 drawOval 繪制橢圓 drawPath 繪制任意多邊形 ? ? ? ? ?* drawLine 繪制直線 drawPoin 繪制點 ? ? ? ? ?*/ ? ? ? ? // 創(chuàng)建畫筆 ? ? ? ? Paint mPaint = new Paint(); ? ? ? ? mPaint.setStrokeWidth(20); ? ? ? ? mPaint.setColor(Color.BLACK);// 設置紅色 ? ? ? ? ? mPaint.setAntiAlias(true); ? ? ? ? mPaint.setTextSize(36); ? ? ? ? ? //繪制Cap為BUTT的點 ? ? ? ? Paint mPaint2 = new Paint(); ? ? ? ? mPaint2.setStrokeWidth(40); ? ? ? ? mPaint2.setColor(Color.BLUE); ? ? ? ? mPaint2.setStrokeCap(Paint.Cap.ROUND); ? ? ? ? ? Paint mPaint3 = new Paint(); ? ? ? ? mPaint3.setAntiAlias(true); ? ? ? ? mPaint3.setColor(Color.GREEN); ? ? ? ? mPaint3.setTextSize(36); ? ? ? ? mPaint3.setStrokeWidth(20); ? ? ? ? ? Paint mPaintxy = new Paint(); ? ? ? ? mPaintxy.setStrokeWidth(20); ? ? ? ? mPaintxy.setColor(Color.WHITE);// 設置紅色 ? ? ? ? mPaintxy.setAntiAlias(true); ? ? ? ? mPaintxy.setTextSize(36); ? ? ? ? ? ? /** ? ? ? ? ?* ?1.拿到接口請求數據 ? ? ? ? ?* ?2.遍歷數據num【i】并將數據傳給DrawView ? ? ? ? ?* ?3.利用canvas將數組進行點的繪制 ? ? ? ? ?* ?4.利用canvas將數組進行線段繪制(需要改變數組格式) ? ? ? ? ?* ?5.繪制綠線,遍歷數據,將數組position和數組進行對應 將傳過來的num進行對比繪制 position.equals(num){...} ? ? ? ? ?*/ ? ? ? ? float[] nums = {(float) -143.798, (float) -683.477, (float) -199.472, (float) -943.149, (float) -317.205, (float) -1496.94, (float) -500.871, (float) -1801.28, (float) -515.062, (float) -2142.18}; ? ? ? ? float[] nums2 = {(float) -584.18, (float) -2741.83, (float) -519.028, (float) -3090.7, (float) -655.9, (float) -3082.98, (float) -721.497, (float) -3395.15, (float) -684.025, (float) -3403.24}; ? ? ? ? ? canvas.drawPoint(0, 0, mPaint3); ? ? ? ? canvas.drawPoint(100, 100, mPaint3); ? ? ? ? canvas.drawPoint(100, -100, mPaint3); ? ? ? ? canvas.drawPoint(-100, 100, mPaint3); ? ? ? ? canvas.drawPoint(-100, -100, mPaint3); ? ? ? ? canvas.drawText("A1(100,100)", 100, 100, mPaint3); ? ? ? ? canvas.drawText("A1(100,-100)", 100, -100, mPaint3); ? ? ? ? canvas.drawText("A1(-100,100)", -100, 100, mPaint3); ? ? ? ? canvas.drawText("A1(-100,-100)", -100, -100, mPaint3); ? ? ? ? ? ? canvas.drawPoints(new float[]{20,100,100,350,150,430,200,510,250,560,350,650,550,730,670,890,750,1000}, mPaint2); ? ? ? ? canvas.drawPoints(new float[]{170,100,170,200,170,400,170,510,170,730,170,850}, mPaint2); ? ? ? ? canvas.drawPoints(new float[]{450,100,480,350,330,500,510,650,780,800,450,900,450,1200,550,1400,600,1500}, mPaint2); ? ? ? ? canvas.drawPoints(new float[]{140,1200,230,1250,370,1140,500,1220,570,1310,680,1280,750,1300,850,1260}, mPaint2); ? ? ? ? canvas.drawPoints(nums, mPaint2); ? ? ? ? canvas.drawPoints(nums2, mPaint2); ? ? ? ? ? float[] pointsx=new float[]{-1500,0,1500,0};//至少4個值,即能夠繪制一條直線 ? ? ? ? canvas.drawLines(pointsx,mPaintxy); ? ? ? ? float[] pointsy=new float[]{0,1500,0,-1500};//至少4個值,即能夠繪制一條直線 ? ? ? ? canvas.drawLines(pointsy,mPaintxy); ? ? ? ? ? ? float[] points=new float[]{20,100,100,350,100,350,150,430,150,430,200,510,200,510,250,560,250,560,350,650,350,650,550,730,550,730,670,890,670,890,750,1000};//至少4個值,即能夠繪制一條直線 ? ? ? ? canvas.drawLines(points,mPaint); ? ? ? // ?float[] points2=new float[]{170,100,170,200,170,200,170,400,170,400,170,510,170,510,170,730,170,730,170,850};//至少4個值,即能夠繪制一條直線 ? ? ? // ?canvas.drawLines(points2,mPaint); ? ? ? ? //縮小1/2 ? ? ? ? float[] points2=new float[]{85,50,85,100,85,100,85,200,85,200,85,255,85,255,85,365,85,365,85,425};//至少4個值,即能夠繪制一條直線 ? ? ? ? canvas.drawLines(points2,mPaint); ? ? ? ? ? float[] points3=new float[]{450,100,480,350,480,350,330,500,330,500,510,650,510,650,780,800,780,800,450,900,450,900,450,1200,450,1200,550,1400,550,1400,600,1500}; ? ? ? ? canvas.drawLines(points3,mPaint); ? ? ? ? float[] points4=new float[]{140,1200,230,1250,230,1250,370,1140,370,1140,500,1220,500,1220,570,1310,570,1310,680,1280,680,1280,750,1300,750,1300,850,1260};//至少4個值,即能夠繪制一條直線 ? ? ? ? canvas.drawLines(points4,mPaint); ? ? ? ? ? ? float[] pointsZ=new float[]{(float) -143.798, (float) -683.477, (float) -199.472, (float) -943.149, (float) -199.472, (float) -943.149,(float) -317.205, (float) -1496.94,(float) -317.205, (float) -1496.94, (float) -500.871, (float) -1801.28, (float) -500.871, (float) -1801.28,(float) -515.062, (float) -2142.18}; ? ? ? ? canvas.drawLines(pointsZ,mPaint); ? ? ? ? float[] pointsZ2=new float[]{(float) -584.18, (float) -2741.83, (float) -519.028, (float) -3090.7, (float) ?-519.028, (float) -3090.7,(float) -655.9, (float) -3082.98 ? ? ? ? ? ? ? ? ,(float) -655.9, (float) -3082.98, (float) -721.497, (float) -3395.15, (float) -721.497, (float) -3395.15,(float) -684.025, (float) -3403.24}; ? ? ? ? canvas.drawLines(pointsZ2,mPaint); ? ? ? ? ? if (bool==true){ ? ? ? ? ? ? if (num.equals("1")){ ? ? ? ? ? ? ? ? DrawLines(canvas); ? ? ? ? ? ? } ? ? ? ? ? ? else if (num.equals("2")){ ? ? ? ? ? ? ? ? canvas.drawLines(points2,mPaint3); ? ? ? ? ? ? } ? ? ? ? ? ? else if (num.equals("3")){ ? ? ? ? ? ? ? ? canvas.drawLines(points,mPaint3); ? ? ? ? ? ? } ? ? ? ? ? ? else if (num.equals("4")){ ? ? ? ? ? ? ? ? canvas.drawLines(points4,mPaint3); ? ? ? ? ? ? } ? ? ? ? ? ? else if (num.equals("5")){ ? ? ? ? ? ? ? ? canvas.drawLines(pointsZ,mPaint3); ? ? ? ? ? ? } ? ? ? ? } ? ? }
MainActivity
public class MainActivity extends AppCompatActivity { ? ? ? private EditText mEdiet; ? ? private Button ?mButton; ? ? private ImageView mtv; ? ? ObjectAnimator ?objectAnimatorX,objectAnimatorY; ? ? ? @Override ? ? protected void onCreate(Bundle savedInstanceState) { ? ? ? ? super.onCreate(savedInstanceState); ? ? ? ? setContentView(R.layout.activity_main); ? ?? ? ? ? ? initView(); ? ? } ? ? ? ? private void initView() { ? ? ? ? RelativeLayout layout=(RelativeLayout) findViewById(R.id.root); ? ? ? ? ? DrawView views=new DrawView(this); ? ? ? ? views.setMinimumHeight(500); ? ? ? ? views.setMinimumWidth(300); ? ? ? ? //通知view組件重繪 ? ? ? ? views.invalidate(); ? ? ? ? layout.addView(views); ? ? ? ? mEdiet=findViewById(R.id.qd); ? ? ? ? mButton=findViewById(R.id.qd2); ? ? ? ? mtv=findViewById(R.id.dw); ? ? ?? ? ? ? ? mButton.setOnClickListener(new View.OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View view) { ? ? ? ? ? ? ? ? String number=mEdiet.getText().toString(); ? ? ? ? ? ? ? ? /** ? ? ? ? ? ? ? ? ?* ? canvas.scale(0.4F,0.4F,850,1500); ? ? ? ? ? ? ? ? ?* ? 則動畫坐標 ?X: x*0.4+850*0.6 ? ?510 ? ? ? ? ? ? ? ? ?* ? ? ? ? ? ? Y: y*0.4+1500*0.6 ? 900 ? ? ? ? ? ? ? ? ?* ?----------------new------------------ ? ? ? ? ? ? ? ? ?* ? canvas.scale(0.5F,0.5F,1000,2200); ? ? ? ? ? ? ? ? ?* ? 則動畫坐標 ?X: x*0.5+850*0.5 ? ?500 ? ? ? ? ? ? ? ? ?* ? ? ? ? ? ? Y: y*0.5+1500*0.5 ?1100 ? ? ? ? ? ? ? ? ?* ? ? ? ? 即 ?X: (x+850)*0.5 ? ? ? ? ? ? ? ? ?* ? ? ? ? ? ? Y: (y+1100)*0.5 ? ? ? ? ? ? ? ? ?* */ ? ? ? ? ? ? ? ? if (number.equals("1")){ ? ? ? ? ? ? ? ? ? ? ? float [] x= {725,740,665, 755,890,725,725,775,800}; ? ? ? ? ? ? ? ? ? ? ? float [] y= {1150,1275,1350,1425,1500,1550,1700,1800,1850}; ? ? ? ? ? ? ? ? ? ? ?startPopsAnimTrans(mtv,x,y); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? else if (number.equals("2")){ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? float [] x= {585,585,585, 585,585,585}; ? ? ? ? ? ? ? ? ? ? ? float [] y= {1150,1200,1300,1355,1465,1525}; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? startPopsAnimTrans(mtv,x,y); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? else if (number.equals("5")){ ? ? ? ? ? ? ? ? ? ? float [] x= {429,400,342, 250, 243}; ? ? ? ? ? ? ? ? ? ? float [] y= {757,629,352,200,29}; ? ? ? ? ? ? ? ? ? ? startPopsAnimTrans(mtv,x,y); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? views.setBool(true,number); ? ? ? ? ? ? ? ? views.invalidate(); ? ? ? ? ? ? ? } ? ? ? ? }); ? ? ? } ? ? private void startPopsAnimTrans(ImageView b,float [] x,float [] y){ ? ? ? ? ? ? objectAnimatorX = ObjectAnimator.ofFloat(b,"translationX", x); ? ? ? ? ? ? objectAnimatorX.setDuration(10000); ? ? ? ? ? ? objectAnimatorY = ObjectAnimator.ofFloat(b,"translationY", y); ? ? ? ? ? ? objectAnimatorY.setDuration(10000); ? ? ? ? ? ? objectAnimatorX.start(); ? ? ? ? ? ? objectAnimatorY.start(); ? ? } ? ? }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android自定義ScrollView使用自定義監(jiān)聽
這篇文章主要介紹了Android自定義ScrollView使用自定義監(jiān)聽 ,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12Android自定義StickinessView粘性滑動效果
這篇文章主要為大家詳細介紹了Android自定義StickinessView粘性滑動效果的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-03-03Android FrameWork之SytemServer進程fork示例
這篇文章主要為大家介紹了Android FrameWork之SytemServer進程fork示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07