編輯:關於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 List xAxisListNames;
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);
Android入門——補間動畫和幀動畫應用小結
引言動畫Animations在App中的作用有多重要勿需多言,彈出式的PopupWindow、Tab切換、Loding等等。Android 3.0前,Android只支持
ImageLoader
這次做一個圖片加載器,裡面涉及到線程池,bitmap的高效加載,LruCache,DiskLruCache。接下來我先介紹這四個知識點一.線程池優點:(1)重用線程池中的
Android 初識 MVC、MVP框架
前言MVC、MVP、MVVP相信大家已經耳熟能詳了,作為Android最出名的三個框架,它們的應用是非常的廣泛。這篇博客就來簡單介紹下其中二種框架。也加強下自己對這方面的
走進絢爛多彩的屬性動畫-Property Animation(上篇)
1.屬性動畫概述動畫一直是App增強用戶交互和用戶體驗的一個重要環節,特別是在某些提示場景或者廣告場景中,合理使用動畫可以給用戶帶來更加愉悅的使用體驗,因此我們很有必要掌