自定義View之簽到足跡控制元件
大家好我叫王大錘,今天 UI 妹紙又給了個圖叫我做,我一看是這樣的:
輸入圖片說明
儘管嘴上說著不願意,但是身體還是很誠實,開始擼程式碼了。
我們首先把這個控制元件劃分成 1個 部分:
1.底下部分的直線 :
2.左右兩邊的半圓弧度 :
3.線上面的小圖示 :
4.最後的文字說明 :
我不管,我就要說一個
首先我們把線畫出來,大概這個樣子
輸入圖片說明
@Override protected void onDraw(Canvas canvas) { paint.setColor(backColor); paint.setStrokeWidth(strokeWidth); int rowCount = (monthDays % 7 == 0 ? monthDays / 7 : monthDays / 7 + 1); int rowHeigh = height / (rowCount); int startX = 0 + rowHeigh / 2; int endX = width - rowHeigh / 2; int days = 0; for (int a = 0; a我們這裡根據一個月得總天數,和一條線上需要畫七個圖,計算出總共需要畫出的線條數,以及畫出左邊和右邊的弧度,根據當前線是單數還是雙數,來計算出是否是左半邊的弧度,還是右半邊的弧度,以及是否是最後的一條線,因為最後一條線不需要畫弧度。
然後再線上上畫出禮物數量
// 這裡是來判斷,本次這根線上畫出的禮物的點,以及順序是順畫,還是倒畫出。 bitmapList.clear(); for (int b = 0; b這裡有一個需要注意的地方,就是,線上為雙數的時候,這時候禮物的排列是需要反過來排列的,我這裡使用了一個LinkedList來儲存禮物的排列順序,然後我們透過計算平均數,計算出每個禮物的位置。
/** * 畫出的按路線上的圖片,勾選,禮物 * @param bitmapList * @param startX * @param endX * @param y * @param canvas */ private void drawImgs(ListbitmapList, float startX, float endX, float y, Canvas canvas) { startX = startX - bitmapList.get(0).getWidth() / 2; int count = bitmapList.size(); float bitmap_width = (endX - startX) / (count - 1); for (int a = 0; a 這裡也有一個需要注意的地方,就是,當最後一條線是短的時候,這個時候,你的禮物的排列需要按照那條線的開始位置和結束位置來平均計算每個禮物的位置。
最後,我們在最後一條線最後的位置,畫出文字
/** * 畫出文字 * @param canvas * @param y * @param x */ private void drawText(Canvas canvas, float y, float x) { int oldColor = paint.getColor(); Paint.Style old_style = paint.getStyle(); paint.setStyle(Paint.Style.FILL); paint.setColor(textColor); String drawText = "已累計簽到"+signInCount+"天"; paint.setTextSize(DensityUtil.sp2px(getContext(), 15)); int textHeigh = getStringHeight(drawText); int textWidth = getStringWidth(drawText); canvas.drawText(drawText, x + textWidth/2, y + textHeigh / 2, paint); paint.setColor(oldColor); paint.setStyle(old_style); }輸入圖片說明
好了,這就是所有的思路。下面貼一下最新完整程式碼(更新時間 2018年2月5日):
import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.RectF;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.view.View;import com.yongxing.QianJR.R;import com.yongxing.QianJR.utils.DensityUtil;import java.util.LinkedList;import java.util.List;/** * Created by xiaolei on 2017/11/6. */public class SignInView extends View{ private int width, height; private int monthDays = 31;//本月有31天 private Paint paint; private RectF oval = new RectF(); private float strokeWidth = 10; private Bitmap checkBitmap, uncheckBitmap, closeGiftBitmap, openGiftBitmap; private int backColor = Color.parseColor("#C3DEEA"), rashColor = Color.parseColor("#B2CADB"), textColor = Color.parseColor("#60ADE5"); private ListbitmapList = new LinkedList(); private int signInCount = 9; public SignInView(Context context) { this(context, null); } public SignInView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public SignInView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs); } private void init(Context context, AttributeSet attrs) { paint = new Paint(); paint.setAntiAlias(true); strokeWidth = DensityUtil.dip2px(context, 6); checkBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_sign_in_check_img); uncheckBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_sign_in_uncheck_img); closeGiftBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_close_gift_img); openGiftBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_open_gift_img); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { height = MeasureSpec.getSize(heightMeasureSpec); width = MeasureSpec.getSize(widthMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } /** * 設定本月天數 * * @param monthDays */ public void setMonthDays(int monthDays) { this.monthDays = monthDays; if (monthDays == 0) { this.monthDays = 31; } postInvalidate(); } /** * 設定一共簽到了幾天 * * @param days */ public void setProgress(int days) { this.signInCount = days; postInvalidate(); } @Override protected void onDraw(Canvas canvas) { paint.setColor(backColor); paint.setStrokeWidth(strokeWidth); int rowCount = (monthDays % 7 == 0 ? monthDays / 7 : monthDays / 7 + 1); int rowHeigh = height / (rowCount); int startX = 0 + rowHeigh / 2; int endX = width - rowHeigh / 2; int days = 0; for (int a = 0; a bitmapList, float startX, float endX, float y, Canvas canvas) { if (!bitmapList.isEmpty()) { startX = startX - bitmapList.get(0).getWidth() / 2; int count = bitmapList.size(); float bitmap_width = (endX - startX) / (count - 1); for (int a = 0; a
THE END
作者:xiaolei123
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3349/viewspace-2809974/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 自定義View之SwitchViewView
- Android 自定義 View 之 LeavesLoadingAndroidView
- Android自定義View--翻書控制元件(一)AndroidView控制元件
- 自定義View 之 RecyclerView.ItemDecorationView
- Android自定義View之捲尺AndroidView
- 自定義View之kotlin繪製手勢設定溫度控制元件ViewKotlin控制元件
- 自定義VIEWView
- Flutter 之 自定義控制元件Flutter控制元件
- Android 自定義 View 實戰之 PuzzleViewAndroidView
- Android 自定義 View 之入門篇AndroidView
- Android自定義view之emoji鍵盤AndroidView
- Android自定義View之Canvas的使用AndroidViewCanvas
- Android自定義View:View(二)AndroidView
- 自定義View事件之進階篇(四)-自定義Behavior實戰View事件
- Android自定義View之定點寫文字AndroidView
- 【朝花夕拾】Android自定義View篇之(四)自定義View的三種實現方式及自定義屬性詳解AndroidView
- 【朝花夕拾】Android自定義View篇之(十一)View的滑動,彈性滑動與自定義PagerViewAndroidView
- Android自定義View整合AndroidView
- Android自定義view-自繪ViewAndroidView
- Android自定義View之區塊選擇器AndroidView
- Android自定義View之requestLayout方法和invalidate方法AndroidView
- Android自定義View之invalidate方法和postInvalidate方法AndroidView
- 【Android自定義View】繪圖之文字篇(三)AndroidView繪圖
- 【Android自定義View】繪圖之Path篇(二)AndroidView繪圖
- Flutter 115: 圖解自定義 View 之 Canvas (四Flutter圖解ViewCanvas
- Android自定義View之Window、ViewRootImpl和View的三大流程AndroidView
- android自定義view(自定義數字鍵盤)AndroidView
- Android自定義view之實現帶checkbox的SnackbarAndroidView
- Android自定義View之Paint繪製文字和線AndroidViewAI
- flutter自定義View(CustomPainter) 之 canvas的方法總結FlutterViewAICanvas
- 自定義view————Banner輪播View
- Flutter 自定義繪製 ViewFlutterView
- Flutter自定義View(二)—— MultiChildRenderObejctWidgetFlutterView
- 重拾Android自定義ViewAndroidView
- Android自定義View:ViewGroup(三)AndroidView
- Android 自定義View:深入理解自定義屬性(七)AndroidView
- 自定義控制元件ViewPager控制元件Viewpager
- 自定義Switch控制元件控制元件