編輯:關於Android編程
代碼在注釋中,與柱狀圖的實現類似
import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.DashPathEffect; import android.graphics.Paint; import android.graphics.Path; import android.util.AttributeSet; import android.view.View; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; /** * Created by wangliang on 0013/2016/9/13. * 思路:每傳遞一次坐標名稱則更新一次視圖,坐標的傳遞采用動態計算的方法,當更改坐標軸名稱的時候,所有視圖清空進行重繪,柱狀圖顯示數量由所傳遞的徐州的名稱決定 */ public class BrokenLineGrapNoScrollView extends View { private Context context; private final String TAG = "HistogramNoScrollView"; private Integer defaultAxisColor = Color.BLACK; private Integer defaultAxisWidth; private ListxAxisListNames; private List yAxisListNames; private List xAxisCoordinateList;//所有x軸基准點坐標 private List yAxisCoordinateList;//所有y軸基准點坐標 private List xAxisTextCoordinateList;//所有x軸文字坐標 private List yAxisTextCoordinateList;//所有y軸文字坐標 private List listAllNoAxisCoordinate;//除軸上坐標之外的其他柱狀圖的坐標 private Paint xAxisTextPaint;//x軸文字畫筆 private Paint yAxisTextPaint;//y軸文字畫筆 private Paint xAxisPaint;//x軸畫筆 private Paint yAxisPaint;//y軸畫筆 private Paint brokenLineGrapPaint;//柱狀圖畫筆 private Paint averageValuePaint;//平均值線 private Path averageValuePath;//平均值線 private Integer axisTextColor; private Integer axisTextSize; private Integer defaultBetweenXAxisAndTextSpace; private Integer defaultBetweenYAxisAndTextSpace; private int xCoordinateDistance;//x軸每段的寬度 private Double maxValue;//柱狀圖所能顯示的最大值 private Double averageValue;//柱狀圖的平均值 private Map histogramValue;//柱狀圖所喲柱子的值 private float histogramShowFanWei;//柱狀圖所能顯示的范圍 private Boolean whetherShowXAxis;//是否顯示y軸 private Boolean whetherShowYAxis;//是否顯示x軸 private Boolean whetherShowAverageValue;//是否顯示柱狀圖平均值 public BrokenLineGrapNoScrollView(Context context) { super(context); initSetting(context,null); } public BrokenLineGrapNoScrollView(Context context, AttributeSet attrs) { super(context, attrs); initSetting(context,null); } public BrokenLineGrapNoScrollView(Context context, AttributeSet attrs, Integer defStyleAttr) { super(context, attrs, defStyleAttr); initSetting(context,defStyleAttr); } private void initSetting(Context context, Integer defStyleAttr) { this.context = context; defaultBetweenXAxisAndTextSpace = 0; defaultBetweenYAxisAndTextSpace = 0; defaultAxisColor = Color.BLACK; defaultAxisWidth = context.getResources().getDimensionPixelOffset(R.dimen.common_dp_0_1); axisTextColor = Color.RED; axisTextSize = context.getResources().getDimensionPixelOffset(R.dimen.default_text_medium); xAxisTextPaint = new Paint(); xAxisTextPaint.setTextSize(axisTextSize); xAxisTextPaint.setColor(axisTextColor); yAxisTextPaint = new Paint(); yAxisTextPaint.setTextSize(axisTextSize); yAxisTextPaint.setColor(axisTextColor); xAxisPaint = new Paint(); xAxisPaint.setColor(defaultAxisColor); // xAxisPaint.setStrokeWidth(defaultAxisWidth); xAxisPaint.setAntiAlias(true); yAxisPaint = new Paint(); yAxisPaint.setColor(defaultAxisColor); // yAxisPaint.setStrokeWidth(defaultAxisWidth); yAxisPaint.setAntiAlias(true); brokenLineGrapPaint = new Paint(); brokenLineGrapPaint.setColor(Color.BLACK); brokenLineGrapPaint.setTextSize(axisTextSize); brokenLineGrapPaint.setAntiAlias(true); averageValuePaint = new Paint ( ) ; averageValuePaint.setColor ( Color.BLACK ) ; //設置畫直線格式 averageValuePaint.setStyle ( Paint.Style.STROKE ) ; /**設置虛線效果 * 裡邊的float數組的意思是:先畫長度為3的實線,再間隔長度為2的空白,之後一直重復這個單元。 * 這個數組的長度只要大於等於2就行,你可以設置多個數值,產生不同效果,最後這個0指的是與起始位置的偏移量。 */ averageValuePaint.setPathEffect ( new DashPathEffect( new float [ ] { 3, 2 }, 0 ) ) ; } /** * 設置x軸坐標文字 * @param xAxisListNames * @return */ public BrokenLineGrapNoScrollView setXAxisNames(List xAxisListNames, boolean whetherShowXAxis){ this.xAxisListNames = xAxisListNames; this.whetherShowXAxis = whetherShowXAxis; xAxisCoordinateList = null;//所有x軸基准點坐標 yAxisCoordinateList = null;//所有y軸基准點坐標 xAxisTextCoordinateList = null;//所有x軸文字坐標 listAllNoAxisCoordinate = null;//除軸上坐標之外的其他柱狀圖的坐標 return this; } /** * 設置y軸坐標文字 * @param yAxisListNames * @return */ public BrokenLineGrapNoScrollView setYAxisNames(List yAxisListNames, boolean whetherShowYAxis){ this.yAxisListNames = yAxisListNames; this.whetherShowYAxis = whetherShowYAxis; yAxisCoordinateList = null;//所有y軸基准點坐標 yAxisTextCoordinateList = null; listAllNoAxisCoordinate = null;//除軸上坐標之外的其他柱狀圖的坐標 return this; } /** * 設置柱狀圖所要顯示的最大值以及平均值 * @param maxValue 最大值 * @param averageValue 平均值 * @param whetherShowAverageValue 是否顯示平均值線 * @return */ public BrokenLineGrapNoScrollView setMaxValueAndAverageValue(double maxValue, double averageValue, boolean whetherShowAverageValue){ this.maxValue = maxValue; this.averageValue = averageValue; this.whetherShowAverageValue = whetherShowAverageValue; listAllNoAxisCoordinate = null;//除軸上坐標之外的其他柱狀圖的坐標 return this; } public BrokenLineGrapNoScrollView setHistogramValue(Map histogramValue){ this.histogramValue = histogramValue; listAllNoAxisCoordinate = null;//除軸上坐標之外的其他柱狀圖的坐標 return this; } @Override protected void onDraw(Canvas canvas) { if(xAxisTextCoordinateList == null){ getXAxisTextCoordinateList(); } if(xAxisCoordinateList == null){ getXAxisCoordinateList(); } if(yAxisTextCoordinateList == null){ getYAxisTextCoordinateList(); } if(yAxisCoordinateList == null){ getYAxisCoordinateList(); } if(listAllNoAxisCoordinate == null){ getListAllNoAxisCoordinate(); } /** * 獲取所要畫的虛線的path */ if(averageValuePath == null && maxValue != null && averageValue != null){ histogramShowFanWei = getHeight() - (fm.descent - fm.ascent) - defaultBetweenXAxisAndTextSpace; averageValuePath = new Path(); averageValuePath.moveTo(0, (float) (histogramShowFanWei - histogramShowFanWei * (averageValue / maxValue))); averageValuePath.lineTo(getWidth() - defaultBetweenYAxisAndTextSpace, (float) (histogramShowFanWei - histogramShowFanWei * (averageValue / maxValue))); } /** * 畫x軸 */ if(xAxisTextCoordinateList.size() > 0 && whetherShowXAxis) { canvas.drawLine(getX() - defaultBetweenYAxisAndTextSpace, getHeight() - (fm.descent - fm.ascent) - defaultBetweenXAxisAndTextSpace, getWidth(), getHeight() - (fm.descent - fm.ascent) - defaultBetweenXAxisAndTextSpace , xAxisPaint); } /** * 畫y軸 */ if(yAxisTextCoordinateList.size() > 0 && whetherShowYAxis) { canvas.drawLine(getX() - defaultBetweenYAxisAndTextSpace, 0, getX() - defaultBetweenYAxisAndTextSpace, getHeight() - (fm.descent - fm.ascent) - defaultBetweenXAxisAndTextSpace , xAxisPaint); } /** * 畫虛線,代表著平均值 */ if(listAllNoAxisCoordinate.size() > 0 && whetherShowAverageValue){ canvas.drawPath(averageValuePath,averageValuePaint); } /** * 繪制x軸上的坐標刻度文字 */ for(int i = 0 ; i < xAxisTextCoordinateList.size() ; i++){ canvas.drawText(xAxisTextCoordinateList.get(i).getCoordinatename(), xAxisTextCoordinateList.get(i).getxCoordinate(), xAxisTextCoordinateList.get(i).getyCoordinate(), xAxisTextPaint); } /** * 繪制折線圖 */ for(int i = 0 ; i < listAllNoAxisCoordinate.size() ; i++){ float textWidth = brokenLineGrapPaint.measureText(listAllNoAxisCoordinate.get(i).getCoordinatename()); Integer circleRadius = null; if(circleRadius == null){ circleRadius = 10; } canvas.drawCircle(listAllNoAxisCoordinate.get(i).getxCoordinate(), listAllNoAxisCoordinate.get(i).getyCoordinate(),circleRadius,brokenLineGrapPaint); if(listAllNoAxisCoordinate.get(i).getxCoordinate() <= getX() + defaultBetweenYAxisAndTextSpace){ canvas.drawText(listAllNoAxisCoordinate.get(i).getCoordinatename(), listAllNoAxisCoordinate.get(i).getxCoordinate(), listAllNoAxisCoordinate.get(i).getyCoordinate() - circleRadius - 10 ,brokenLineGrapPaint); }else if(listAllNoAxisCoordinate.get(i).getxCoordinate() >= getWidth()){ canvas.drawText(listAllNoAxisCoordinate.get(i).getCoordinatename(), listAllNoAxisCoordinate.get(i).getxCoordinate() - textWidth, listAllNoAxisCoordinate.get(i).getyCoordinate() - circleRadius - 10 ,brokenLineGrapPaint); }else { canvas.drawText(listAllNoAxisCoordinate.get(i).getCoordinatename(), listAllNoAxisCoordinate.get(i).getxCoordinate() - textWidth / 2, listAllNoAxisCoordinate.get(i).getyCoordinate() - circleRadius - 10 ,brokenLineGrapPaint); } if(i > 0){ canvas.drawLine(listAllNoAxisCoordinate.get(i - 1).getxCoordinate(), listAllNoAxisCoordinate.get(i - 1).getyCoordinate(), listAllNoAxisCoordinate.get(i).getxCoordinate(), listAllNoAxisCoordinate.get(i).getyCoordinate(),brokenLineGrapPaint); } } } private Paint.FontMetrics fm; /** * 根據文字獲得文字相對於x軸的坐標 * @param text * @param xCoordinateDistance * @return */ private float[] getXtextCoordinate(String text,float xCoordinateDistance){ float[] xy = new float[2]; fm = xAxisTextPaint.getFontMetrics(); float textWidth = xAxisTextPaint.measureText(text); float textHeight = fm.descent - fm.ascent; xy[0] = xCoordinateDistance - textWidth / 2; xy[1] = getHeight(); return xy; } /** * 獲取x軸刻度文字坐標 */ private void getXAxisTextCoordinateList(){ xAxisTextCoordinateList = new ArrayList<>(); if(xAxisListNames != null) { xCoordinateDistance = getWidth() / (xAxisListNames.size() + 1); for (int i = 0; i < xAxisListNames.size(); i++) { float[] xtextCoordinate = getXtextCoordinate(xAxisListNames.get(i), xCoordinateDistance * (i + 1)); xAxisTextCoordinateList.add(new Coordinate(xtextCoordinate[0], xtextCoordinate[1], xAxisListNames.get(i))); } } } /** * 獲取x軸線坐標 */ private void getXAxisCoordinateList(){ xAxisCoordinateList = new ArrayList<>(); if(xAxisListNames != null) { fm = xAxisTextPaint.getFontMetrics(); float textHeight = fm.descent - fm.ascent; xCoordinateDistance = getWidth() / (xAxisListNames.size() + 1); for (int i = 0; i < xAxisListNames.size(); i++) { xAxisCoordinateList.add(new Coordinate(getX() + xCoordinateDistance * (i + 1) , getHeight() - textHeight, xAxisListNames.get(i))); } } } /** * 獲取y軸刻度文字坐標 */ private void getYAxisTextCoordinateList(){ yAxisTextCoordinateList = new ArrayList<>(); } /** * 獲取y軸線坐標 */ private void getYAxisCoordinateList(){ yAxisCoordinateList = new ArrayList<>(); } private void getListAllNoAxisCoordinate(){ listAllNoAxisCoordinate = new ArrayList<>(); histogramShowFanWei = getHeight() - (fm.descent - fm.ascent) - defaultBetweenXAxisAndTextSpace; if(maxValue != null && xAxisListNames != null && xAxisCoordinateList != null){ for(int i = 0 ; i < xAxisListNames.size() ; i++) { if (histogramValue.get(xAxisListNames.get(i)) != null) { listAllNoAxisCoordinate.add(new Coordinate(xAxisCoordinateList.get(i).getxCoordinate(), (float) (xAxisCoordinateList.get(i).getyCoordinate() - (histogramShowFanWei * (histogramValue.get(xAxisListNames.get(i)) / maxValue))), xAxisCoordinateList.get(i).getCoordinatename())); } } Collections.sort(listAllNoAxisCoordinate,new Coordinate()); } } }
調用方法:
Listlist = new ArrayList<>(); list.add("123"); list.add("456"); list.add("789"); list.add("147"); list.add("258"); Map map = new HashMap<>(); map.put(list.get(0),10d); map.put(list.get(1),15d); map.put(list.get(3),7d); ((HistogramNoScrollView)findViewById(R.id.test1)).setXAxisNames(list,true); ((HistogramNoScrollView)findViewById(R.id.test1)).setMaxValueAndAverageValue(20,10,true); ((HistogramNoScrollView)findViewById(R.id.test1)).setHistogramValue(map);
引言動畫Animations在App中的作用有多重要勿需多言,彈出式的PopupWindow、Tab切換、Loding等等。Android 3.0前,Android只支持
這次做一個圖片加載器,裡面涉及到線程池,bitmap的高效加載,LruCache,DiskLruCache。接下來我先介紹這四個知識點一.線程池優點:(1)重用線程池中的
前言MVC、MVP、MVVP相信大家已經耳熟能詳了,作為Android最出名的三個框架,它們的應用是非常的廣泛。這篇博客就來簡單介紹下其中二種框架。也加強下自己對這方面的
1.屬性動畫概述動畫一直是App增強用戶交互和用戶體驗的一個重要環節,特別是在某些提示場景或者廣告場景中,合理使用動畫可以給用戶帶來更加愉悅的使用體驗,因此我們很有必要掌