English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
The production method of Taobao logistics information TimeLine:
Reference timeline effect diagram:
Code implementation:
package com.zms.timelineview; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.view.View; public class TimeLineView extends View { private Paint mPaint; /** * The outer radius of the first node */ private float timelineHeadRadius; /** * The center color of the first node */ private int timelineHeadColor; /** * The edge color of the first node */ private int timelineHeadColorEdge; /** * The color value of other nodes */ private int timelineOtherColor; /** * The number of timeline nodes */ private int timelineCount; /** * The position of the timeline */ private int viewWidth; /** * The distance from the timeline to the top */ private int marginTop; /** * The radius of the timeline nodes */ private int timelineRadius; /** * The distance between timeline nodes */ private int timelineRadiusDistance; /** * The width of the timeline */ private int timelineWidth; /** * The height of the timeline */ private float timeLineViewHeight; public TimeLineView(Context context) { this(context, null); } public TimeLineView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public TimeLineView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs, defStyle); } /** * Initialization * * @param context * @param attrs * @param defStyle */ private void init(Context context, AttributeSet attrs, int defStyle) { final TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.TimeLineView, defStyle, 0); timelineRadiusDistance = (int) a.getDimension( R.styleable.TimeLineView_timelineRadiusDistance, convertDIP2PX(context, 20)); timelineHeadRadius = a.getDimension( R.styleable.TimeLineView_timelineHeadRadius, convertDIP2PX(context, 6)); timelineRadius = (int) a.getDimension( R.styleable.TimeLineView_timelineRadius, convertDIP2PX(context, 5)); timelineHeadColor = a.getColor( R.styleable.TimeLineView_timelineHeadColor, Color.parseColor("#25ae5f")); // Center dark color timelineHeadColorEdge = a.getColor( R.styleable.TimeLineView_timelineHeadColorEdge, Color.parseColor("#b9e5cc")); // Edge light color timelineOtherColor = a.getColor( R.styleable.TimeLineView_timelineOtherColor, Color.parseColor("#cccccc")); timelineCount = a.getInteger(R.styleable.TimeLineView_timelineCount, 0); timelineWidth = (int) a.getDimension( R.styleable.TimeLineView_timelineWidth, convertDIP2PX(context, 1)); marginTop = (int) a.getDimension( R.styleable.TimeLineView_timelineMarginTop, convertDIP2PX(context, 50)); a.recycle(); mPaint = new Paint(); mPaint.setAntiAlias(true); } @Override protected void onDraw(Canvas canvas) { // Default setting of the time axis position is in the middle of the view viewWidth = getMeasuredWidth() / 2; // Set the color of the first node mPaint.setColor(timelineHeadColor); /** * Draw the corresponding nodes and axes according to the number of time axis nodes */ for (int j = 1; j <= timelineCount; j++) { /** * when j==1It's a bit special when drawing the first node, we need to draw another ring outside the node */ if (j == 1) { // Set the pen to hollow canvas.drawCircle(viewWidth, timelineHeadRadius + marginTop, timelineRadius, mPaint); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(5.0f); // Draw the outer ring of the first node mPaint.setColor(timelineHeadColorEdge); canvas.drawCircle(viewWidth, timelineHeadRadius + marginTop, timelineHeadRadius, mPaint); // Set the pen color, the color of other time nodes mPaint.setColor(timelineOtherColor); // Set the pen to solid mPaint.setStyle(Paint.Style.FILL); /** * Draw the axis below the first node */ canvas.drawRect(new Rect(viewWidth - timelineWidth / 2, (int) (2 * timelineHeadRadius + marginTop) + 5, viewWidth + timelineWidth / 2, (int) (2 * timelineHeadRadius + timelineRadiusDistance + marginTop + 5)), mPaint); continue; } /** * Draw the timeline nodes, that is, draw circles; the x of the center of the circle is the same, the middle of the view * The calculation of the y of the center of the circle is based on the position of the node, for example: the y of the first node is based on the distance from the first node to the top plus the radius of the first node * :timelineHeadRadius + marginTop * The remaining nodes are on the y basis of a node, plus twice the radius and the length of the axis between nodes * the number of nodes: (2 * timelineRadius + * timelineRadiusDistance) * (j - 1) + timelineHeadRadius - * timelineRadius + marginTop * */ canvas.drawCircle(viewWidth, (2 * timelineRadius + timelineRadiusDistance) * (j - 1) + 2 * timelineHeadRadius - timelineRadius + marginTop, timelineRadius, mPaint); /** * Draw the remaining axes, left: each axis is the same distance from the left; the center position of the timeline-1/2the width of the timeline viewWidth - * timelineWidth / 2 top: (int) (j * (2 * timelineRadius + * timelineRadiusDistance) - timelineRadiusDistance + 2 * * (timelineHeadRadius-timelineRadius)+ marginTop) * right: each axis is the same distance from the right; the center position of the timeline+1/2the width of the timeline viewWidth + * timelineWidth / 2 bottom: (int) (j * (2 * timelineRadius + * timelineRadiusDistance) + 2 * * (timelineHeadRadius-timelineRadius)+ marginTop) */ canvas.drawRect( new Rect( viewWidth - timelineWidth / 2, (int) (j * (2 * timelineRadius + timelineRadiusDistance) - timelineRadiusDistance + 2 * (timelineHeadRadius - timelineRadius) + marginTop), viewWidth + timelineWidth / 2, (int) (j * (2 * timelineRadius + timelineRadiusDistance) + 2 * (timelineHeadRadius - timelineRadius) + marginTop)), mPaint); } } public float getTimelineHeadRadius() { return timelineHeadRadius; } public void setTimelineHeadRadius(float timelineHeadRadius) { this.timelineHeadRadius = timelineHeadRadius; invalidate(); } public int getTimelineHeadColor() { return timelineHeadColor; } public void setTimelineHeadColor(int timelineHeadColor) { this.timelineHeadColor = timelineHeadColor; invalidate(); } public int getTimelineOtherColor() { return timelineOtherColor; } public void setTimelineOtherColor(int timelineOtherColor) { this.timelineOtherColor = timelineOtherColor; invalidate(); } public int getTimelineCount() { return timelineCount; } public void setTimelineCount(int timelineCount) { this.timelineCount = timelineCount; invalidate(); } public int getMarginTop() { return marginTop; } public void setMarginTop(int marginTop) { this.marginTop = marginTop; invalidate(); } public int getTimelineRadius() { return timelineRadius; } public void setTimelineRadius(int timelineRadius) { this.timelineRadius = timelineRadius; invalidate(); } public int getTimelineRadiusDistance() { return timelineRadiusDistance; } public void setTimelineRadiusDistance(int timelineRadiusDistance) { this.timelineRadiusDistance = timelineRadiusDistance; invalidate(); } public int getTimelineWidth() { return timelineWidth; } public void setTimelineWidth(int timelineWidth) { this.timelineWidth = timelineWidth; } public float getTimeLineViewHeight() { this.timeLineViewHeight = getMarginTop(); + getTimelineCount()} * (2 * getTimelineRadius() + getTimelineRadiusDistance()); return timeLineViewHeight; } public void setTimeLineViewHeight(float timeLineViewHeight) { this.timeLineViewHeight = timeLineViewHeight; invalidate(); } public int getViewWidth() { return viewWidth; } public void setViewWidth(int viewWidth) { this.viewWidth = viewWidth; invalidate(); } /** * Convert dip to px */ public static int convertDIP2PX(Context context, int dip) { float scale = context.getResources().getDisplayMetrics().density; return (int) (dip * scale + 0.5f * (dip >= 0 &63; 1 : -1)); } }
That's all for this article. I hope it will be helpful to everyone's learning and that everyone will support the Yelling Tutorial more.
Statement: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been manually edited, and does not assume any relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (Please replace # with @ when sending an email to report violations, and provide relevant evidence. Once verified, this site will immediately delete the content suspected of infringement.)