2014-12-18 2 views
0

저는 활동에서 배터리 수명을 나타내는 원주를 그리려합니다.뷰를 프로그램 적으로 활동에 배치하십시오.

부모 레이아웃은 상대 레이아웃입니다.

이 뷰립니다 내부 클래스입니다 : 내가보기 이런 식으로 시작

public class DrawView extends View { 
    Paint mPaint = new Paint(); 

    public DrawView(Context context) { 
     super(context); 
    } 

    @Override 
    public void onDraw(Canvas canvas) { 
     Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG | 
       Paint.DITHER_FLAG | 
       Paint.ANTI_ALIAS_FLAG); 
     mPaint.setDither(true); 
     mPaint.setColor(Color.GRAY); 
     mPaint.setStyle(Paint.Style.STROKE); 
     mPaint.setStrokeWidth(1); 

     int size = 200; 
     int radius = 190; 
     int delta = size - radius; 
     int arcSize = (size - (delta/2)) * 2; 
     int percent = 42; 

     //Thin circle 
     canvas.drawCircle(size, size, radius, mPaint); 

     //Arc 
     mPaint.setColor(getResources().getColor(R.color.eCarBlue)); 
     mPaint.setStrokeWidth(15); 
     RectF box = new RectF(delta,delta,arcSize,arcSize); 
     float sweep = 360 * percent * 0.01f; 
     canvas.drawArc(box, 0, sweep, false, mPaint); 
    } 

} 

그리고에서 onCreate()에서

:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    ... 

    ViewGroup myLayout = (ViewGroup) findViewById(R.id.mainlayout); 
    drawing = new DrawView(this); 
    myLayout.addView(drawing); 
} 

을하지만 레이아웃이보기를 찾아야합니다 , 특히 그것의 중심에있다. 이를 달성하기 위해 onCreate()의 코드를 다음과 같이 수정했습니다.

ViewGroup myLayout = (ViewGroup) findViewById(R.id.mainlayout); 
drawing = new DrawView(this); 
RelativeLayout.LayoutParams layoutParams= new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, 
      RelativeLayout.LayoutParams.WRAP_CONTENT); 
layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE); 
drawing.setLayoutParams(layoutParams); 
myLayout.addView(drawing); 

그러나 뷰에는 영향을 미치지 않습니다. 그러면 뷰의 매개 변수를 정의하는 올바른 방법은 무엇입니까?

답변

1

DrawViewLayoutParams.WRAP_CONTENT으로 추가하고 있습니다. 즉, 시스템이 너비와 높이를 확인해야합니다. 이를 위해 onMeasure()을 구현해야합니다. 그러나 나는 그렇게 한 적이 없으므로 세부 사항을 알지 못합니다.

또 다른 방법은 LayoutParams.MATCH_PARENT을 사용하고 자신을 중심으로 onDraw()에 물건을 그립니다. 이 경우 그리기 호출의 좌표를 계산하기 위해 캔버스의 너비와 높이를 알아야합니다. getWidth()onDraw() (으)로 지정해도 예상 결과가 나올 수 없습니다. 이 같은 새로운 폭과 높이를 onSizeChanged()을 무시하고 기록해야 다음 onSizeChanged() 이미 일어난 때문에

private int canvasWidth; 
private int canvasHeight; 

@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    super.onSizeChanged(w, h, oldw, oldh); 
    canvasWidth = w; 
    canvasHeight = h; 
} 

그런 다음 onDraw() 당신이 canvasWidthcanvasHeight를 사용할 수 있습니다.

+0

글쎄, 나는 몇 분 전에 이런 짓을했다. onDraw에서 뷰를 중앙에 배치 할 수 있다는 것을 알았고 getWidth() 및 getHeight()를 사용하여 뷰를 가운데에 맞췄습니다. 이제는 onSizeChanged를 사용하여 메소드를 변경했습니다. 아마도 더 나은 접근 방법이지만 결과는 같습니다. 어쨌든, 당신의 대답은 옳습니다. – masmic

+0

한 가지 더 ... 오래된 장치에서는보기가 원하는 크기를 갖지만 Galaxy S5에서는 이전 장치보다 작습니다. 나는 이것이'radius' 값과 관련이 있다고 생각합니다. 모든 화면 밀도에서 반경 값을 동일하게 설정하려면 어떻게해야합니까? – masmic

+1

반경은 픽셀 단위이며 픽셀 밀도가 다른 화면에서 다르게 보입니다. 안드로이드는 160 픽셀/인치 스크린상의 물리적 픽셀과 같은 디바이스 독립 픽셀 (dip)이라는 개념을 가지고 있습니다. 따라서 어떤 화면에서나 16 인치는 0.1 인치가됩니다. 나는 그것이 당신이 필요로하는 것이라고 생각합니다. 따라서 딥에서 픽셀로 변환하십시오. 자세한 내용은 [this] (http://stackoverflow.com/questions/4605527/converting-pixels-to-dp)를 참조하십시오. –

관련 문제