2015-07-03 53 views
-3

我知道這個問題是重複的,但我無法找到我的代碼合適的答案,請參見下面我有一個自定義視圖(A圖)自定義視圖不會無效

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Rect; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.View; 


import java.util.ArrayList; 


public class BarView extends View { 


    private final int TEXT_COLOR = Color.parseColor("#9B9A9B"); 
    private final int LINE_COLOR = Color.parseColor("#9B9A9B"); 
    private final int BAR_RIGHT_COLOR = Color.parseColor("#e45d97"); 
    private final int BAR_LEFT_COLOR = Color.parseColor("#C0C0C0"); 
    private ArrayList<Integer> dataList; 
    private Paint textPaint; 
    private Paint rightBarPaint; 
    private Paint leftBarPaint; 
    private Paint linePaint; 
    private Rect rect; 

    private ArrayList<String> leftTextList = new ArrayList<String>(); 

    // Bar 
    private int barWidth; 
    private ArrayList<Integer> barTop = new ArrayList<>(); 
    private ArrayList<Integer> barBottom = new ArrayList<>(); 
    private ArrayList<Integer> barPercentage = new ArrayList<>(); 
    //Bar box calculation 
    private int totalViewHeight; 
    private int totalViewWidth; 
    private int leftViewPadding; 
    private int topViewPadding; 
    private int rightViewPadding; 
    private int bottomViewPadding; 
    private int totalBarRatio = 60; 
    private int totalBottomCount = 6; 
    private int centerX; 
    private int leftX; 


    public BarView(Context context) { 
     this(context, null); 
    } 

    //Initialize components 
    public BarView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     rightBarPaint = new Paint(); 
     rightBarPaint.setAntiAlias(true); 
     rightBarPaint.setColor(BAR_RIGHT_COLOR); 
     leftBarPaint = new Paint(rightBarPaint); 
     leftBarPaint.setColor(BAR_LEFT_COLOR); 
     rect = new Rect(); 
     leftViewPadding = GraphUtils.dip2px(context, 5); 
     int textSize = GraphUtils.sp2px(context, 12); 
     barWidth = GraphUtils.dip2px(context, 22); 
     topViewPadding = GraphUtils.dip2px(context, 50); 
     bottomViewPadding = GraphUtils.dip2px(context, 50); 
     rightViewPadding = GraphUtils.dip2px(context, 15); 
     textPaint = new Paint(); 
     textPaint.setAntiAlias(true); 
     textPaint.setColor(TEXT_COLOR); 
     textPaint.setTextSize(textSize); 
     textPaint.setTypeface(Util.setCustomFont(context)); 
     textPaint.setTextAlign(Paint.Align.CENTER); 
     linePaint = new Paint(); 
     linePaint.setAntiAlias(true); 
     linePaint.setColor(LINE_COLOR); 
     dataList = new ArrayList<Integer>(); 
    } 

    /** 
    * dataList will be reset when called is method. 
    * 
    * @param leftStringList The String ArrayList in the left. 
    */ 
    public void setLeftTextList(ArrayList<String> leftStringList) { 
//  this.dataList = null; 
     this.leftTextList = leftStringList; 
     setMinimumWidth(2); 
    } 

    /** 
    * @param list The ArrayList of Integer with the range of [0-max]. 
    */ 
    public void setDataList(ArrayList<Integer> list) { 
     dataList = list; 
     postInvalidate(); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     totalViewHeight = getHeight(); 
     totalViewWidth = getWidth(); 
     //Draw OuterBox 
     drawOuterBox(canvas); 
     int i = 0; 
     if (dataList != null && !dataList.isEmpty()) { 
      for (Integer data : dataList) { 
       //Draw left graph value 
       if (data < totalBarRatio/2 && data >= 0) { 
        rect.set(barPercentage.get(data - 1), barTop.get(i), centerX, barBottom.get(i)); 
        canvas.drawRect(rect, leftBarPaint); 
       } 
       if (data > totalBarRatio/2 && data <= totalBarRatio) { 
        //Draw Right graph Value 
        rect.set(centerX, barTop.get(i), barPercentage.get(data - 1), barBottom.get(i)); 
        canvas.drawRect(rect, rightBarPaint); 

       } 
       i++; 
      } 
     } 


    } 


    private void drawOuterBox(Canvas canvas) { 
     //Draw Horizontal lines 
     leftX = leftViewPadding + Math.round(getHighestLeftTextWidth()) + leftViewPadding; 
     int availableHeight = (totalViewHeight - (topViewPadding + bottomViewPadding)); 
     int unitHeight = availableHeight/leftTextList.size() + 1; 
     if (leftTextList != null && !leftTextList.isEmpty()) { 
      //Draw first line with top padding 
      canvas.drawLine(leftX, topViewPadding, totalViewWidth - rightViewPadding, topViewPadding, linePaint); 
      barTop.add(topViewPadding + unitHeight/4); 
      barBottom.add(topViewPadding + (unitHeight/4) * 3); 
      for (int i = 1; i < leftTextList.size(); i++) { 
       barTop.add(topViewPadding + unitHeight * i + unitHeight/4); 
       barBottom.add(topViewPadding + unitHeight * i + (unitHeight/4) * 3); 
       canvas.drawLine(leftX, topViewPadding + unitHeight * i, totalViewWidth - rightViewPadding, topViewPadding + unitHeight * i, linePaint); 
      } 
      //Draw last line with top padding 
      canvas.drawLine(0, totalViewHeight - bottomViewPadding, totalViewWidth, totalViewHeight - bottomViewPadding, linePaint); 
     } 
     //Draw Vertical lines 
     //Right line 
     canvas.drawLine(totalViewWidth - rightViewPadding, topViewPadding, totalViewWidth - rightViewPadding, totalViewHeight - bottomViewPadding, linePaint); 
     //Center Line 
     centerX = (totalViewWidth - rightViewPadding + leftX)/2; 
     canvas.drawLine(centerX, topViewPadding, centerX, totalViewHeight - bottomViewPadding, linePaint); 
     //Left Vertical Line 
     canvas.drawLine(leftX, topViewPadding, leftX, totalViewHeight - bottomViewPadding, linePaint); 

//  Draw left Text 
     if (leftTextList != null && !leftTextList.isEmpty()) { 
      int i = 1; 
      for (String s : leftTextList) { 
       canvas.drawText(s, leftViewPadding + (getHighestLeftTextWidth()/2), ((topViewPadding + unitHeight * i) - unitHeight/2) + (textPaint.getTextSize()/2), textPaint); 
       i++; 
      } 
     } 

//  Draw bottom arrow 
     int boxWidth = totalViewWidth - (rightViewPadding + leftX); 
     int width = boxWidth/totalBottomCount; 
     int lineHeight = bottomViewPadding/4; 
     canvas.drawLine(leftX, totalViewHeight - bottomViewPadding, leftX, (totalViewHeight - bottomViewPadding) + lineHeight, linePaint); 
     canvas.drawLine(centerX, totalViewHeight - bottomViewPadding, centerX, (totalViewHeight - bottomViewPadding) + lineHeight, linePaint); 
     canvas.drawLine(totalViewWidth - rightViewPadding, totalViewHeight - bottomViewPadding, totalViewWidth - rightViewPadding, (totalViewHeight - bottomViewPadding) + lineHeight, linePaint); 
     canvas.drawText("-30", leftX, totalViewHeight - (bottomViewPadding/2) + (textPaint.getTextSize()/2), textPaint); 
     canvas.drawText("0", centerX, totalViewHeight - (bottomViewPadding/2) + (textPaint.getTextSize()/2), textPaint); 
     canvas.drawText("30", totalViewWidth - rightViewPadding, totalViewHeight - (bottomViewPadding/2) + (textPaint.getTextSize()/2), textPaint); 

     for (int i = 1; i < totalBottomCount; i++) { 
      if (i != totalBottomCount/2) { 
       canvas.drawLine(leftX + (width * i), totalViewHeight - bottomViewPadding, leftX + (width * i), (totalViewHeight - bottomViewPadding) + lineHeight, linePaint); 
       canvas.drawText((i * 10) - 30 + "", leftX + (width * i), totalViewHeight - (bottomViewPadding/2) + (textPaint.getTextSize()/2), textPaint); 

      } 
     } 


     int unitWidth = boxWidth/totalBarRatio; 
     for (int i = 1; i <= totalBarRatio; i++) { 
      barPercentage.add(leftX + (unitWidth * i)); 
     } 

    } 

    private float getHighestLeftTextWidth() { 
     String text = ""; 
     for (String s : leftTextList) { 
      if (s.length() > text.length()) { 
       text = s; 
      } 
     } 
     return textPaint.measureText(text); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     int mViewWidth = measureWidth(widthMeasureSpec); 
     int mViewHeight = measureHeight(heightMeasureSpec); 
     setMeasuredDimension(mViewWidth, mViewHeight); 
    } 

    private int measureWidth(int measureSpec) { 
     int preferred = 0; 
     if (leftTextList != null) { 
      preferred = leftTextList.size() * (barWidth); 
     } 
     return getMeasurement(measureSpec, preferred); 
    } 

    private int measureHeight(int measureSpec) { 
     int preferred = 222; 
     return getMeasurement(measureSpec, preferred); 
    } 

    private int getMeasurement(int measureSpec, int preferred) { 
     int specSize = MeasureSpec.getSize(measureSpec); 
     int measurement; 
     switch (MeasureSpec.getMode(measureSpec)) { 
      case MeasureSpec.EXACTLY: 
       measurement = specSize; 
       break; 
      case MeasureSpec.AT_MOST: 
       measurement = Math.min(preferred, specSize); 
       break; 
      default: 
       measurement = preferred; 
       break; 
     } 
     return measurement; 
    } 

} 

,我已經使用

public void setDataList(ArrayList<Integer> list) { 
    dataList = list; 
    postInvalidate(); 
} 

若要使用我的Activity中的新數據更新視圖,但postInvalidate不會調用onDraw。

回答

1

根據android文檔postInvalidate()只有當此視圖附加到窗口時纔可以從UI線程之外調用方法。因此,您必須從其他UI線程中調用您的setDataList(),或者使用invalidate()方法從UI線程更新View,如下所示。

public void setDataList(ArrayList<Integer> list) { 
    dataList = list; 
    invalidate(); 
} 
+0

嗨Chandrakanth我打電話setDataList從onProgressChanged方法我怎麼能調用setDataList從那個方法我需要使用view.post? –

+0

onProgressChanged()?那個方法在哪裏? – Chandrakanth

+0

在我的活動我有一個seekBar我需要更新對應的進度變化圖 –