本源码整理于安卓源码:
http://www.apkbus.com/forum.php?mod=viewthread&tid=267170&highlight=%E9%97%B9%E9%92%9F
直接上代码:
绘制折线view
package weather.hanwei.com; import android.content.Context; import android.content.res.TypedArray; 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; public class WeatherChartView extends View { /** * x轴集合 */ private float mXAxis[] = new float[6]; /** * 白天y轴集合 */ private float mYAxisDay[] = new float[6]; /** * 夜间y轴集合 */ private float mYAxisNight[] = new float[6]; /** * x,y轴集合数 */ private static final int LENGTH = 6; /** * 白天温度集合 */ private int mTempDay[] = new int[6]; /** * 夜间温度集合 */ private int mTempNight[] = new int[6]; /** * 控件高 */ private int mHeight; /** * 字体大小 */ private float mTextSize; /** * 圓半径 */ private float mRadius; /** * 圓半径今天 */ private float mRadiusToday; /** * 文字移动位置距离 */ private float mTextSpace; /** * 线的大小 */ private float mStokeWidth; /** * 白天折线颜色 */ private int mColorDay; /** * 夜间折线颜色 */ private int mColorNight; /** * 字体颜色 */ private int mTextColor; /** * 屏幕密度 */ private float mDensity; /** * 控件边的空白空间 */ private float mSpace; @SuppressWarnings("deprecation") public WeatherChartView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.WeatherChartView); float densityText = getResources().getDisplayMetrics().scaledDensity; mTextSize = a.getDimensionPixelSize(R.styleable.WeatherChartView_textSize, (int) (14 * densityText)); mColorDay = a.getColor(R.styleable.WeatherChartView_dayColor, getResources().getColor(R.color.colorAccent)); mColorNight = a.getColor(R.styleable.WeatherChartView_nightColor, getResources().getColor(R.color.colorPrimary)); mTextColor = a.getColor(R.styleable.WeatherChartView_textColor, Color.WHITE); a.recycle(); mDensity = getResources().getDisplayMetrics().density; mRadius = 3 * mDensity; mRadiusToday = 5 * mDensity; mSpace = 3 * mDensity; mTextSpace = 10 * mDensity; mStokeWidth = 2 * mDensity; } public WeatherChartView(Context context) { super(context); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mHeight == 0) { // 设置控件高度,x轴集合 setHeightAndXAxis(); } // 计算y轴集合数值 computeYAxisValues(); // 画白天折线图 drawChart(canvas, mColorDay, mTempDay, mYAxisDay, 0); // 画夜间折线图 drawChart(canvas, mColorNight, mTempNight, mYAxisNight, 1); } /** * 计算y轴集合数值 */ private void computeYAxisValues() { // 存放白天最低温度 int minTempDay = mTempDay[0]; // 存放白天最高温度 int maxTempDay = mTempDay[0]; for (int item : mTempDay) { if (item < minTempDay) { minTempDay = item; } if (item > maxTempDay) { maxTempDay = item; } } // 存放夜间最低温度 int minTempNight = mTempNight[0]; // 存放夜间最高温度 int maxTempNight = mTempNight[0]; for (int item : mTempNight) { if (item < minTempNight) { minTempNight = item; } if (item > maxTempNight) { maxTempNight = item; } } // 白天,夜间中的最低温度 int minTemp = minTempNight < minTempDay ? minTempNight : minTempDay; // 白天,夜间中的最高温度 int maxTemp = maxTempDay > maxTempNight ? maxTempDay : maxTempNight; // 份数(白天,夜间综合温差) float parts = maxTemp - minTemp; // y轴一端到控件一端的距离 float length = mSpace + mTextSize + mTextSpace + mRadius; // y轴高度 float yAxisHeight = mHeight - length * 2; // 当温度都相同时(被除数不能为0) if (parts == 0) { for (int i = 0; i < LENGTH; i++) { mYAxisDay[i] = yAxisHeight / 2 + length; mYAxisNight[i] = yAxisHeight / 2 + length; } } else { float partValue = yAxisHeight / parts; for (int i = 0; i < LENGTH; i++) { mYAxisDay[i] = mHeight - partValue * (mTempDay[i] - minTemp) - length; mYAxisNight[i] = mHeight - partValue * (mTempNight[i] - minTemp) - length; } } } /** * 画折线图 * * @param canvas 画布 * @param color 画图颜色 * @param temp 温度集合 * @param yAxis y轴集合 * @param type 折线种类:0,白天;1,夜间 */ private void drawChart(Canvas canvas, int color, int temp[], float[] yAxis, int type) { // 线画笔 Paint linePaint = new Paint(); // 抗锯齿 linePaint.setAntiAlias(true); // 线宽 linePaint.setStrokeWidth(mStokeWidth); linePaint.setColor(color); // 空心 linePaint.setStyle(Paint.Style.STROKE); // 点画笔 Paint pointPaint = new Paint(); pointPaint.setAntiAlias(true); pointPaint.setColor(color); // 字体画笔 Paint textPaint = new Paint(); textPaint.setAntiAlias(true); textPaint.setColor(mTextColor); textPaint.setTextSize(mTextSize); // 文字居中 textPaint.setTextAlign(Paint.Align.CENTER); int alpha1 = 102; int alpha2 = 255; for (int i = 0; i < LENGTH; i++) { // 画线 if (i < LENGTH - 1) { // 昨天 if (i == 0) { linePaint.setAlpha(alpha1); // 设置虚线效果 linePaint.setPathEffect(new DashPathEffect(new float[]{2 * mDensity, 2 * mDensity}, 0)); // 路径 Path path = new Path(); // 路径起点 path.moveTo(mXAxis[i], yAxis[i]); // 路径连接到 path.lineTo(mXAxis[i + 1], yAxis[i + 1]); canvas.drawPath(path, linePaint); } else { linePaint.setAlpha(alpha2); linePaint.setPathEffect(null); canvas.drawLine(mXAxis[i], yAxis[i], mXAxis[i + 1], yAxis[i + 1], linePaint); } } // 画点 if (i != 1) { // 昨天 if (i == 0) { pointPaint.setAlpha(alpha1); canvas.drawCircle(mXAxis[i], yAxis[i], mRadius, pointPaint); } else { pointPaint.setAlpha(alpha2); canvas.drawCircle(mXAxis[i], yAxis[i], mRadius, pointPaint); } // 今天 } else { pointPaint.setAlpha(alpha2); canvas.drawCircle(mXAxis[i], yAxis[i], mRadiusToday, pointPaint); } // 画字 // 昨天 if (i == 0) { textPaint.setAlpha(alpha1); drawText(canvas, textPaint, i, temp, yAxis, type); } else { textPaint.setAlpha(alpha2); drawText(canvas, textPaint, i, temp, yAxis, type); } } } /** * 绘制文字 * * @param canvas 画布 * @param textPaint 画笔 * @param i 索引 * @param temp 温度集合 * @param yAxis y轴集合 * @param type 折线种类:0,白天;1,夜间 */ private void drawText(Canvas canvas, Paint textPaint, int i, int[] temp, float[] yAxis, int type) { switch (type) { case 0: // 显示白天气温 canvas.drawText(temp[i] + "°C", mXAxis[i], yAxis[i] - mRadius - mTextSpace, textPaint); break; case 1: // 显示夜间气温 canvas.drawText(temp[i] + "°C", mXAxis[i], yAxis[i] + mTextSpace + mTextSize, textPaint); break; } } /** * 设置高度,x轴集合 */ private void setHeightAndXAxis() { mHeight = getHeight(); // 控件宽 int width = getWidth(); // 每一份宽 float w = width / 12; mXAxis[0] = w; mXAxis[1] = w * 3; mXAxis[2] = w * 5; mXAxis[3] = w * 7; mXAxis[4] = w * 9; mXAxis[5] = w * 11; } /** * 设置白天温度 * * @param tempDay 温度数组集合 */ public void setTempDay(int[] tempDay) { mTempDay = tempDay; } /** * 设置夜间温度 * * @param tempNight 温度数组集合 */ public void setTempNight(int[] tempNight) { mTempNight = tempNight; } }
样式:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="WeatherChartView"> <attr name="textColor" format="color"/> <attr name="dayColor" format="color"/> <attr name="nightColor" format="color"/> <attr name="textSize" format="dimension"/> </declare-styleable> </resources>
xml布局:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:wcv="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/black"> <weather.hanwei.com.WeatherChartView android:id="@+id/line_char" android:layout_width="match_parent" android:layout_height="150dp" android:layout_centerInParent="true" wcv:dayColor="@color/colorAccent" wcv:nightColor="@color/colorPrimary" wcv:textColor="@android:color/white" wcv:textSize="14sp"/> </RelativeLayout>
在Main中调用:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); WeatherChartView chartView = (WeatherChartView) findViewById(R.id.line_char); // 设置白天温度曲线 chartView .setTempDay(new int[]{5,6,4,6,7,6,10}); // 设置夜间温度曲线 chartView .setTempNight(new int[]{0,-1,-2,0,2,0,4}); chartView .invalidate(); } }
样式图:
以上就是整理的所有代码,可直接运行!
點擊查看更多內容
為 TA 點贊
評論
評論
共同學習,寫下你的評論
評論加載中...
作者其他優質文章
正在加載中
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦