2013-11-22 2 views
0

안녕 계기판을 만들 때이 링크를 실제로 따라갔습니다. 내가 에뮬레이터에서 코드를 실행하면계기 눈금이 작동하지 않습니다.

http://mindtherobot.com/blog/272/android-custom-ui-making-a-vintage-thermometer/

하지만, 게이지의 수치가 0으로 판명 난 이유를 알아낼 수 없습니다입니다. 무엇이 잘못 될 수 있는지에 대한 단서가 있습니까? 나는 drawscale 함수의 "i"값을 출력했으나 에뮬레이터를 항상 실행할 때 게이지 뷰의 값은 0입니다.

 package com.mindtherobot.samples.thermometer; 


     import java.util.List; 

    import android.content.Context; 
    import android.graphics.Bitmap; 
    import android.graphics.BitmapFactory; 
    import android.graphics.BitmapShader; 
    import android.graphics.Canvas; 
    import android.graphics.Color; 
    import android.graphics.LightingColorFilter; 
    import android.graphics.LinearGradient; 
    import android.graphics.Matrix; 
    import android.graphics.Paint; 
    import android.graphics.Path; 
    import android.graphics.RadialGradient; 
    import android.graphics.RectF; 
    import android.graphics.Shader; 
    import android.graphics.Typeface; 
    import android.hardware.Sensor; 
    import android.hardware.SensorEvent; 
    import android.hardware.SensorEventListener; 
    import android.hardware.SensorManager; 
     import android.os.Bundle; 
     import android.os.Handler; 
    import android.os.Parcelable; 
    import android.util.AttributeSet; 
    import android.util.Log; 
    import android.view.View; 

    public final class Thermometer extends View implements SensorEventListener { 

private static final String TAG = Thermometer.class.getSimpleName(); 

private Handler handler; 

// drawing tools 
private RectF rimRect; 
private Paint rimPaint; 
private Paint rimCirclePaint; 

private RectF faceRect; 
private Bitmap faceTexture; 
private Paint facePaint; 
private Paint rimShadowPaint; 

private Paint scalePaint; 
private RectF scaleRect; 

private Paint titlePaint; 
private Path titlePath; 

private Paint logoPaint; 
private Bitmap logo; 
private Matrix logoMatrix; 
private float logoScale; 

private Paint handPaint; 
private Path handPath; 
private Paint handScrewPaint; 

private Paint backgroundPaint; 
// end drawing tools 

private Bitmap background; // holds the cached static part 

// scale configuration 


private int totalNotches = 100; 
private int incrementPerLargeNotch = 10; 
private int incrementPerSmallNotch = 2; 
private float degreesPerNotch = 360.0f/totalNotches; 

private int scaleCenterValue = 40; // the one in the top center (12 o'clock) 
private int scaleMinValue = -30; 
private int scaleMaxValue = 110; 

// hand dynamics -- all are angular expressed in F degrees 
private boolean handInitialized = false; 
private float handPosition = scaleCenterValue; 
private float handTarget = scaleCenterValue; 
private float handVelocity = 0.0f; 
private float handAcceleration = 0.0f; 
private long lastHandMoveTime = -1L; 


public Thermometer(Context context) { 
    super(context); 
    init(); 
} 

public Thermometer(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    init(); 
} 

public Thermometer(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    init(); 
} 

@Override 
protected void onAttachedToWindow() { 
    super.onAttachedToWindow(); 
    attachToSensor(); 
} 

@Override 
protected void onDetachedFromWindow() { 
    detachFromSensor(); 
    super.onDetachedFromWindow(); 
} 

@Override 
protected void onRestoreInstanceState(Parcelable state) { 
    Bundle bundle = (Bundle) state; 
    Parcelable superState = bundle.getParcelable("superState"); 
    super.onRestoreInstanceState(superState); 

    handInitialized = bundle.getBoolean("handInitialized"); 
    handPosition = bundle.getFloat("handPosition"); 
    handTarget = bundle.getFloat("handTarget"); 
    handVelocity = bundle.getFloat("handVelocity"); 
    handAcceleration = bundle.getFloat("handAcceleration"); 
    lastHandMoveTime = bundle.getLong("lastHandMoveTime"); 
} 

@Override 
protected Parcelable onSaveInstanceState() { 
    Parcelable superState = super.onSaveInstanceState(); 

    Bundle state = new Bundle(); 
    state.putParcelable("superState", superState); 
    state.putBoolean("handInitialized", handInitialized); 
    state.putFloat("handPosition", handPosition); 
    state.putFloat("handTarget", handTarget); 
    state.putFloat("handVelocity", handVelocity); 
    state.putFloat("handAcceleration", handAcceleration); 
    state.putLong("lastHandMoveTime", lastHandMoveTime); 
    return state; 
} 

private void init() { 
    handler = new Handler(); 

    initDrawingTools(); 
} 

private String getTitle() { 
    return "mindtherobot.com"; 
} 

private SensorManager getSensorManager() { 
    return (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);  
} 

private void attachToSensor() { 
    SensorManager sensorManager = getSensorManager(); 

    List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_TEMPERATURE); 
    if (sensors.size() > 0) { 
     Sensor sensor = sensors.get(0); 
     sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_FASTEST, handler); 
    } else { 
     Log.e(TAG, "No temperature sensor found"); 
    }  
} 

private void detachFromSensor() { 
    SensorManager sensorManager = getSensorManager(); 
    sensorManager.unregisterListener(this); 
} 

private void initDrawingTools() { 
    rimRect = new RectF(0.1f, 0.1f, 0.9f, 0.9f); 

    // the linear gradient is a bit skewed for realism 
    rimPaint = new Paint(); 
    rimPaint.setFlags(Paint.ANTI_ALIAS_FLAG); 
    rimPaint.setShader(new LinearGradient(0.40f, 0.0f, 0.60f, 1.0f, 
             Color.rgb(0xf0, 0xf5, 0xf0), 
             Color.rgb(0x30, 0x31, 0x30), 
             Shader.TileMode.CLAMP));  

    rimCirclePaint = new Paint(); 
    rimCirclePaint.setAntiAlias(true); 
    rimCirclePaint.setStyle(Paint.Style.STROKE); 
    rimCirclePaint.setColor(Color.argb(0x4f, 0x33, 0x36, 0x33)); 
    rimCirclePaint.setStrokeWidth(0.005f); 

    float rimSize = 0.02f; 
    faceRect = new RectF(); 
    faceRect.set(rimRect.left + rimSize, rimRect.top + rimSize, 
      rimRect.right - rimSize, rimRect.bottom - rimSize);   

    faceTexture = BitmapFactory.decodeResource(getContext().getResources(), 
       R.drawable.plastic); 
    BitmapShader paperShader = new BitmapShader(faceTexture, 
               Shader.TileMode.MIRROR, 
               Shader.TileMode.MIRROR); 
    Matrix paperMatrix = new Matrix(); 
    facePaint = new Paint(); 
    facePaint.setFilterBitmap(true); 
    paperMatrix.setScale(1.0f/faceTexture.getWidth(), 
         1.0f/faceTexture.getHeight()); 
    paperShader.setLocalMatrix(paperMatrix); 
    facePaint.setStyle(Paint.Style.FILL); 
    facePaint.setShader(paperShader); 

    rimShadowPaint = new Paint(); 
    rimShadowPaint.setShader(new RadialGradient(0.5f, 0.5f, faceRect.width()/2.0f, 
       new int[] { 0x00000000, 0x00000500, 0x50000500 }, 
       new float[] { 0.96f, 0.96f, 0.99f }, 
       Shader.TileMode.MIRROR)); 
    rimShadowPaint.setStyle(Paint.Style.FILL); 

    scalePaint = new Paint(); 
    scalePaint.setStyle(Paint.Style.STROKE); 
    scalePaint.setColor(0x9f004d0f); 
    scalePaint.setStrokeWidth(0.005f); 
    scalePaint.setAntiAlias(true); 

    scalePaint.setTextSize(0.045f); 
    scalePaint.setTypeface(Typeface.SANS_SERIF); 
    scalePaint.setTextScaleX(0.8f); 
    scalePaint.setTextAlign(Paint.Align.CENTER);   

    float scalePosition = 0.10f; 
    scaleRect = new RectF(); 
    scaleRect.set(faceRect.left + scalePosition, faceRect.top + scalePosition, 
        faceRect.right - scalePosition, faceRect.bottom - scalePosition); 

    titlePaint = new Paint(); 
    titlePaint.setColor(0xaf946109); 
    titlePaint.setAntiAlias(true); 
    titlePaint.setTypeface(Typeface.DEFAULT_BOLD); 
    titlePaint.setTextAlign(Paint.Align.CENTER); 
    titlePaint.setTextSize(0.05f); 
    titlePaint.setTextScaleX(0.8f); 

    titlePath = new Path(); 
    titlePath.addArc(new RectF(0.24f, 0.24f, 0.76f, 0.76f), -180.0f, -180.0f); 

    logoPaint = new Paint(); 
    logoPaint.setFilterBitmap(true); 
    logo = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.logo); 
    logoMatrix = new Matrix(); 
    logoScale = (1.0f/logo.getWidth()) * 0.3f;; 
    logoMatrix.setScale(logoScale, logoScale); 

    handPaint = new Paint(); 
    handPaint.setAntiAlias(true); 
    handPaint.setColor(0xff392f2c);  
    handPaint.setShadowLayer(0.01f, -0.005f, -0.005f, 0x7f000000); 
    handPaint.setStyle(Paint.Style.FILL); 

    handPath = new Path(); 
    handPath.moveTo(0.5f, 0.5f + 0.2f); 
    handPath.lineTo(0.5f - 0.010f, 0.5f + 0.2f - 0.007f); 
    handPath.lineTo(0.5f - 0.002f, 0.5f - 0.32f); 
    handPath.lineTo(0.5f + 0.002f, 0.5f - 0.32f); 
    handPath.lineTo(0.5f + 0.010f, 0.5f + 0.2f - 0.007f); 
    handPath.lineTo(0.5f, 0.5f + 0.2f); 
    handPath.addCircle(0.5f, 0.5f, 0.025f, Path.Direction.CW); 

    handScrewPaint = new Paint(); 
    handScrewPaint.setAntiAlias(true); 
    handScrewPaint.setColor(0xff493f3c); 
    handScrewPaint.setStyle(Paint.Style.FILL); 

    backgroundPaint = new Paint(); 
    backgroundPaint.setFilterBitmap(true); 
} 

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    Log.d(TAG, "Width spec: " + MeasureSpec.toString(widthMeasureSpec)); 
    Log.d(TAG, "Height spec: " + MeasureSpec.toString(heightMeasureSpec)); 

    int widthMode = MeasureSpec.getMode(widthMeasureSpec); 
    int widthSize = MeasureSpec.getSize(widthMeasureSpec); 

    int heightMode = MeasureSpec.getMode(heightMeasureSpec); 
    int heightSize = MeasureSpec.getSize(heightMeasureSpec); 

    int chosenWidth = chooseDimension(widthMode, widthSize); 
    int chosenHeight = chooseDimension(heightMode, heightSize); 

    int chosenDimension = Math.min(chosenWidth, chosenHeight); 

    setMeasuredDimension(chosenDimension, chosenDimension); 
} 

private int chooseDimension(int mode, int size) { 
    if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) { 
     return size; 
    } else { // (mode == MeasureSpec.UNSPECIFIED) 
     return getPreferredSize(); 
    } 
} 

// in case there is no size specified 
private int getPreferredSize() { 
    return 300; 
} 

private void drawRim(Canvas canvas) { 
    // first, draw the metallic body 
    canvas.drawOval(rimRect, rimPaint); 
    // now the outer rim circle 
    canvas.drawOval(rimRect, rimCirclePaint); 
} 

private void drawFace(Canvas canvas) {  
    canvas.drawOval(faceRect, facePaint); 
    // draw the inner rim circle 
    canvas.drawOval(faceRect, rimCirclePaint); 
    // draw the rim shadow inside the face 
    canvas.drawOval(faceRect, rimShadowPaint); 
} 

private void drawScale(Canvas canvas) { 
    // Draw a large notch every large increment, and a small 
    // notch every small increment. 

    canvas.drawOval(scaleRect, scalePaint); 

    canvas.save(Canvas.MATRIX_SAVE_FLAG); 
    for (int i = 0; i < totalNotches; ++i) { 
     float y1 = scaleRect.top; 
     float y2 = y1 - 0.015f; 
     float y3 = y1 - 0.025f; 
     System.out.println("The value of i is "+i); 

     int value = notchToValue(i); 
     System.out.println("The value of value is "+value); 
     if (i % (incrementPerLargeNotch/incrementPerSmallNotch) == 0) { 
      System.out.println("inside loop i"+i); 
      if (value >= scaleMinValue && value <= scaleMaxValue) { 
       // draw a nick 
       canvas.drawLine(0.5f, y1, 0.5f, y3, scalePaint); 

       String valueString = Integer.toString(value); 
       System.out.println("the value of value string is "+valueString); 
       // Draw the text 0.15 away from y3 which is the long nick. 
       canvas.drawText(valueString, 0.5f, y3 - 0.015f, scalePaint); 
      } 
     } 
     else{ 
      if (value >= scaleMinValue && value <= scaleMaxValue) { 
       // draw a nick 
       canvas.drawLine(0.5f, y1, 0.5f, y2, scalePaint); 
      } 
     } 

     canvas.rotate(degreesPerNotch, 0.5f, 0.5f); 
    } 
    canvas.restore();  
} 

private int notchToValue(int value) { 
    int rawValue = ((value < totalNotches/2) ? value : (value - totalNotches)) * incrementPerSmallNotch; 
    int shiftedValue = rawValue + scaleCenterValue; 
    return shiftedValue; 
} 

private float valueToAngle(float value) { 
    return (value - scaleCenterValue)/2.0f * degreesPerNotch; 
} 
private void drawTitle(Canvas canvas) { 
    String title = getTitle(); 
    canvas.drawTextOnPath(title, titlePath, 0.0f,0.0f, titlePaint);    
} 

private void drawLogo(Canvas canvas) { 
    canvas.save(Canvas.MATRIX_SAVE_FLAG); 
    canvas.translate(0.5f - logo.getWidth() * logoScale/2.0f, 
        0.5f - logo.getHeight() * logoScale/2.0f); 

    int color = 0x00000000; 
    float position = getRelativeTemperaturePosition(); 
    if (position < 0) { 
     color |= (int) ((0xf0) * -position); // blue 
    } else { 
     color |= ((int) ((0xf0) * position)) << 16; // red   
    } 
    //Log.d(TAG, "*** " + Integer.toHexString(color)); 
    LightingColorFilter logoFilter = new LightingColorFilter(0xff338822, color); 
    logoPaint.setColorFilter(logoFilter); 

    canvas.drawBitmap(logo, logoMatrix, logoPaint); 
    canvas.restore();  
} 

private void drawHand(Canvas canvas) { 
    if (handInitialized) { 
     float handAngle = valueToAngle(handPosition); 
     canvas.save(Canvas.MATRIX_SAVE_FLAG); 
     canvas.rotate(handAngle, 0.5f, 0.5f); 
     canvas.drawPath(handPath, handPaint); 
     canvas.restore(); 

     canvas.drawCircle(0.5f, 0.5f, 0.01f, handScrewPaint); 
    } 
} 

private void drawBackground(Canvas canvas) { 
    if (background == null) { 
     Log.w(TAG, "Background not created"); 
    } else { 
     canvas.drawBitmap(background, 0, 0, backgroundPaint); 
    } 
} 

@Override 
protected void onDraw(Canvas canvas) { 
    drawBackground(canvas); 

    float scale = (float) getWidth();  
    canvas.save(Canvas.MATRIX_SAVE_FLAG); 
    canvas.scale(scale, scale); 

    drawLogo(canvas); 
    drawHand(canvas); 

    canvas.restore(); 

    if (handNeedsToMove()) { 
     moveHand(); 
    } 
} 

@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    Log.d(TAG, "Size changed to " + w + "x" + h); 

    regenerateBackground(); 
} 

private void regenerateBackground() { 
    // free the old bitmap 
    if (background != null) { 
     background.recycle(); 
    } 

    background = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); 
    Canvas backgroundCanvas = new Canvas(background); 
    float scale = (float) getWidth();  
    backgroundCanvas.scale(scale, scale); 

    drawRim(backgroundCanvas); 
    drawFace(backgroundCanvas); 
    drawScale(backgroundCanvas); 
    drawTitle(backgroundCanvas);   
} 

private boolean handNeedsToMove() { 
    return Math.abs(handPosition - handTarget) > 0.01f; 
} 

private void moveHand() { 
    if (! handNeedsToMove()) { 
     return; 
    } 

    if (lastHandMoveTime != -1L) { 
     long currentTime = System.currentTimeMillis(); 
     float delta = (currentTime - lastHandMoveTime)/1000.0f; 

     float direction = Math.signum(handVelocity); 
     if (Math.abs(handVelocity) < 90.0f) { 
      handAcceleration = 5.0f * (handTarget - handPosition); 
     } else { 
      handAcceleration = 0.0f; 
     } 
     handPosition += handVelocity * delta; 
     handVelocity += handAcceleration * delta; 
     if ((handTarget - handPosition) * direction < 0.01f * direction) { 
      handPosition = handTarget; 
      handVelocity = 0.0f; 
      handAcceleration = 0.0f; 
      lastHandMoveTime = -1L; 
     } else { 
      lastHandMoveTime = System.currentTimeMillis();    
     } 
     invalidate(); 
    } else { 
     lastHandMoveTime = System.currentTimeMillis(); 
     moveHand(); 
    } 
} 

@Override 
public void onAccuracyChanged(Sensor sensor, int accuracy) { 

} 

@Override 
public void onSensorChanged(SensorEvent sensorEvent) { 
    if (sensorEvent.values.length > 0) { 
     float temperatureC = sensorEvent.values[0]; 
     //Log.i(TAG, "*** Temperature: " + temperatureC); 

     float temperatureF = (9.0f/5.0f) * temperatureC + 32.0f; 
     setHandTarget(temperatureF); 
    } else { 
     Log.w(TAG, "Empty sensor event received"); 
    } 
} 

private float getRelativeTemperaturePosition() { 
    if (handPosition < scaleCenterValue) { 
     return - (scaleCenterValue - handPosition)/(float) (scaleCenterValue - scaleMinValue); 
    } else { 
     return (handPosition - scaleCenterValue)/(float) (scaleMaxValue - scaleCenterValue); 
    } 
} 

private void setHandTarget(float temperature) { 
    if (temperature < scaleMinValue) { 
     temperature = scaleMinValue; 
    } else if (temperature > scaleMaxValue) { 
     temperature = scaleMaxValue; 
    } 
    handTarget = temperature; 
    handInitialized = true; 
    invalidate(); 
} 

}

답변

3

나는 이것이 오래된 질문이라는 것을 알고 있지만 어제 같은 문제가 발생했습니다.

OP가 묘사 한 것으로 생각하는 것은 눈금에 표시된 모든 숫자 값이 0 인 것으로 나타납니다. setLinearText(true) ~ scalePaint으로 설정하면이를 수정했습니다.

0

가 무슨 잘못? 온도계가 어떤 값도 표시하지 않는 이유는 프로그램이 SensorManager를 사용하여 TEMPERATURE 값을 받기 때문입니다. 에뮬레이터에는 any가 없으므로 반환되는 값은 항상 0입니다.

0

예, scalePaint의 모든 세트를 작성한 후이 라인을 initDrawingTools() 메소드에 추가했습니다.

scalePaint.setLinearText(true); 

그리고 효과가있었습니다.

관련 문제