2017-11-18 519 views
0

我正在嘗試編寫一個應用程序,該應用程序連接到遠程主機並讀取x,y元組的行並將它們實時繪製爲散點圖。數據正在按預期顯示,但是當我修改代碼以嘗試顯示某些標記以測量數據時,該數據未按預期工作。我期望看到20個同心灰色圓圈的黑色背景。隨着數據的滾入,它應該在同心圓上顯示爲綠色圓點。相反,我在遠程主機關閉時看到的是initializeSurface()被調用,並且只顯示外部灰色圓圈(i = 20)。而且,當遠程主機啓動initializeSurface()後,快速調用drawPoint(),並且不顯示灰色圓圈,只顯示綠色圓點。代碼如下,之後是之前描述的2個屏幕截圖。Android:繪製同心圓

package com.balaguru.ggdiagram; 

import android.app.Activity; 
import android.content.Context; 
import android.content.pm.ActivityInfo; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Rect; 
import android.os.Bundle; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.View; 
import android.view.WindowManager; 
import android.widget.Toast; 

import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.io.StringWriter; 
import java.net.Socket; 

class ToastThread implements Runnable { 
    private String ivMessage; 
    private View ivView; 
    ToastThread(View pView, String pMessage) { ivView = pView; ivMessage = pMessage; } 
    public void run() { 
     Toast.makeText(ivView.getContext(), ivMessage, Toast.LENGTH_LONG).show(); 
    } 
} 
class ConnectionThread extends Thread { 

    private GGView ivGGView; 

    ConnectionThread(GGView pGGView) { 
     ivGGView = pGGView; 
    } 

    public void run() { 
     try { 
      ivGGView.initializeSurface(); 
      //Toast.makeText(MainActivity.context, "office-main", Toast.LENGTH_LONG).show(); 
      Socket socket = new Socket("192.168.1.197", 10000); 
      BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      String line = input.readLine(); 
      while (line != null) { 
       if (line.equals("not connected")) { 
        ivGGView.drawPoint(0, 0, Color.GREEN); 
       } else { 
        String[] gg = line.split(","); 
        float x = Float.parseFloat(gg[0]); 
        float y = Float.parseFloat(gg[1]); 
        ivGGView.drawPoint(x, y, Color.GREEN); 
       } 
       line = input.readLine(); 
      } 
     } catch (Throwable e) { 
      StringWriter error = new StringWriter(); 
      e.printStackTrace(new PrintWriter(error)); 
      ToastThread toast = new ToastThread(ivGGView, error.toString()); 
      Activity activity = (Activity) ivGGView.getContext(); 
      activity.runOnUiThread(toast); 
     } 
    } 
} 

class GGView extends SurfaceView implements SurfaceHolder.Callback { 
    private SurfaceHolder ivHolder; 
    public Context ivContext; 
    private int ivWidth; 
    private int ivHeight; 

    public GGView(Context context){ 
     super(context); 
     ivContext = context; 
     ivHolder = getHolder(); 
     ivHolder.addCallback(this); 
    } 
    public void surfaceDestroyed(SurfaceHolder pHolder) {} 
    public void surfaceCreated(SurfaceHolder pHolder) { 
     ConnectionThread thread = new ConnectionThread(this); 
     thread.start(); 
    } 
    public void surfaceChanged(SurfaceHolder pHolder, int pFormat, int pWidth, int pHeight) {} 

    public void initializeSurface() { 
     Canvas canvas = ivHolder.lockCanvas(); 
     ivWidth = canvas.getWidth(); 
     ivHeight = canvas.getHeight(); 
     canvas.drawColor(Color.BLACK); 
     Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); 
     paint.setColor(Color.GRAY); 
     paint.setStrokeWidth(4); 
     paint.setStyle(Paint.Style.STROKE); 
     for (int i = 1; i <= 20; i++) { 
      canvas.drawArc(ivWidth/2 - i/20*ivHeight/2, 
       ivHeight/2 - i/20*ivHeight/2, 
       ivWidth/2 + i/20*ivHeight/2, 
       ivHeight/2 + i/20*ivHeight/2, 
       0, 360, false, paint); 
     } 
     ivHolder.unlockCanvasAndPost(canvas); 
    } 

    public void drawPoint(float pX, float pY, int pColor) { 
     float x = pX/20 * ivHeight/2 + ivWidth/2; 
     float y = pY/20 * ivHeight/2 + ivHeight/2; 
     Canvas canvas = ivHolder.lockCanvas(
       new Rect((int) x-4, (int)y-4, (int) x+4, (int)y+4)); 
     Paint paint = new Paint(); 
     paint.setColor(pColor); 
     paint.setStrokeWidth(4); 
     canvas.drawPoint(x, y, paint); 
     ivHolder.unlockCanvasAndPost(canvas); 

    } 
} 


public class MainActivity extends Activity { 

    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
     GGView ggView = new GGView(this); 
     setContentView(ggView); 
    } 

} 

enter image description here enter image description here

EDIT 如果我改變for循環從20到40中initializeSurface()然後drawArc似乎繪製同心圓當i = 20和i = 40,但沒有其他。下面的屏幕截圖。

enter image description here

回答

0

發現的問題:I/20,正在採取爲整數除法和繪圖電弧時評價爲0。將其更改爲i/10f可解決該問題。 20f畫了太多圈子。 lockCanvas()返回一些緩衝的畫布中的一個,我只在這些畫布中的一個畫圈。因此,隨後對drawPoint()的調用正在繪製到畫布上,而沒有繪製這些圓。爲了解決這個問題,我不得不調用lockCanvas()3次,並畫出我的圈子。這不是一個非常優雅的解決方案,但它似乎工作。下面更正代碼:

public void initializeSurface() { 
     for (int j = 0; j <= 3; j++) { 
      Canvas canvas = ivHolder.lockCanvas(); 
      ivWidth = canvas.getWidth(); 
      ivHeight = canvas.getHeight(); 
      canvas.drawColor(Color.BLACK); 
      Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); 
      paint.setColor(Color.GRAY); 
      paint.setStrokeWidth(4); 
      paint.setStyle(Paint.Style.STROKE); 
      Paint font = new Paint(); 
      font.setTextSize(16); 
      font.setColor(Color.WHITE); 
      float width = ivWidth; 
      float height = ivHeight; 
      for (int i = 1; i <= 10; i++) 
       canvas.drawCircle(width/2, height/2, i/10f * height/2f, paint); 
      ivHolder.unlockCanvasAndPost(canvas); 
     } 
    } 

enter image description here