电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Android自定義控件實現時間軸

瀏覽:2日期:2022-09-19 09:00:10

本文實例為大家分享了Android自定義控件實現時間軸的具體代碼,供大家參考,具體內容如下

由于項目中有需求,就簡單的封裝一個,先記錄一下,有時間上傳到github。

1、先增加自定義屬性:

<?xml version='1.0' encoding='utf-8'?><resources> <declare-styleable name='global_TimelineLayout'><!--時間軸左偏移值--><attr name='global_line_margin_left' format='dimension' /><!--時間軸上偏移值--><attr name='global_line_margin_top' format='dimension' /><!--線寬--><attr name='global_line_stroke_width' format='dimension' /><!--線的顏色--><attr name='global_line_color' format='color' /><!--點的大小--><attr name='global_point_inner_size' format='dimension' /><attr name='global_point_out_size' format='dimension' /><!--點的上偏移值--><attr name='global_point_margin_top' format='dimension' /><!--點的顏色--><attr name='global_point_inner_color' format='color' /><attr name='global_point_out_color' format='color' /><!--圖標--><attr name='global_icon_src' format='reference' /><!--虛線--><attr name='global_dash_gap' format='dimension' /><attr name='global_dash_width' format='dimension' /> </declare-styleable></resources>

2、自定義時間軸類:

/** * 時間軸控件 * <p>The following snippet shows how to include a linear layout in your layout XML file:</p> * * <com.taoche.mars.commonres.widget.TimelineLayout android: android:layout_width='40dp' android:layout_height='match_parent' app:global_line_margin_left='10dp' app:global_line_margin_top='0dp' app:global_point_margin_top='10dp' app:global_point_inner_color='#377CFF' app:global_point_out_color='#FFE8F0FF' app:global_point_out_size='8dp' app:global_point_inner_size='4dp' app:global_dash_width='8dp' app:global_dash_gap='2dp' app:global_line_color='#C9DCFF'> </com.taoche.mars.commonres.widget.TimelineLayout> * * <p>The following snippet shows how to java file:</p> * timelineLayout.setPointMarginTop(10) timelineLayout.setLineMarginTop(10) timelineLayout.setPointMarginTop(40) timelineLayout.setInterrupt(true) */class TimeLinearLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : LinearLayout(context, attrs, defStyleAttr) { private var mContext: Context? = null private var mLineMarginLeft: Int = 10 private var mLineMarginTop: Int = 0 private var mPointMarginTop: Int = 0 private var mLineStrokeWidth: Int = 2 private var mLineColor: Int = 0 //內圓半徑 private var mPointInnerSize: Int = 8 //外圓半徑 private var mPointOutSize: Int = 18 //內圓顏色 private var mPointInnerColor: Int = 0 //外圓顏色 private var mPointOutColor: Int = 0 //虛線寬 private var mDashWidth: Int = 0 //虛線空白寬 private var mDashGap: Int = 0 //是否中斷 private var mInterrupt: Boolean = false private var mIcon: Bitmap? = null //線的畫筆 private var mLinePaint: Paint? = null //點的畫筆 private var mPointPaint: Paint? = null //第一個點的位置 private var mFirstX = 0 private var mFirstY = 0 //最后一個圖標的位置 private var mLastX = 0 private var mLastY = 0 init {setLayerType(View.LAYER_TYPE_SOFTWARE, null) //開啟硬件加速val ta = context.obtainStyledAttributes(attrs, R.styleable.global_TimelineLayout)mLineMarginLeft = ta.getDimensionPixelOffset(R.styleable.global_TimelineLayout_global_line_margin_left, 10)mLineMarginTop = ta.getDimensionPixelOffset(R.styleable.global_TimelineLayout_global_line_margin_top, 0)mPointMarginTop = ta.getDimensionPixelOffset(R.styleable.global_TimelineLayout_global_point_margin_top, 0)mLineStrokeWidth = ta.getDimensionPixelOffset(R.styleable.global_TimelineLayout_global_line_stroke_width, 2)mLineColor = ta.getColor(R.styleable.global_TimelineLayout_global_line_color, -0xc22e5b)mPointInnerSize = ta.getDimensionPixelSize(R.styleable.global_TimelineLayout_global_point_inner_size, 8)mPointOutSize = ta.getDimensionPixelSize(R.styleable.global_TimelineLayout_global_point_out_size, 18)mPointInnerColor = ta.getColor(R.styleable.global_TimelineLayout_global_point_inner_color, -0xc22e5b)mPointOutColor = ta.getColor(R.styleable.global_TimelineLayout_global_point_out_color, -0x170f01)mDashGap = ta.getDimensionPixelOffset(R.styleable.global_TimelineLayout_global_dash_gap, 0)mDashWidth = ta.getDimensionPixelOffset(R.styleable.global_TimelineLayout_global_dash_width, 0)val iconRes = ta.getResourceId(R.styleable.global_TimelineLayout_global_icon_src, View.NO_ID)if (iconRes > View.NO_ID) { val drawable = ContextCompat.getDrawable(context,iconRes) as? BitmapDrawable if (drawable != null) {mIcon = drawable.bitmap }}ta.recycle()setWillNotDraw(false)initView(context) } fun setLineMarginTop(lineMarginTop:Int){this.mLineMarginTop = lineMarginTop } fun setPointMarginTop(pointMarginTop:Int){this.mPointMarginTop = pointMarginTop } fun setInterrupt(interrupt:Boolean){this.mInterrupt = interrupt } private fun initView(context: Context) {mContext = contextmLinePaint = Paint()mLinePaint?.apply { isAntiAlias = true isDither = true color = mLineColor strokeWidth = mLineStrokeWidth.toFloat() style = Paint.Style.FILL_AND_STROKE //虛線設置 if (mDashGap > 0 && mDashWidth > 0) {//mLinePaint.setPathEffect(new DashPathEffect(new float[]{20,5}, 20));pathEffect = DashPathEffect(floatArrayOf(mDashWidth.toFloat(), mDashGap.toFloat()), mDashWidth.toFloat()) }} mPointPaint = Paint()mPointPaint?.apply { isAntiAlias = true isDither = true color = mPointInnerColor style = Paint.Style.FILL} } override fun onDraw(canvas: Canvas) {super.onDraw(canvas)drawTimeline(canvas) } private fun drawTimeline(canvas: Canvas) {drawBetweenLine(canvas)drawFirstPoint(canvas)drawLastIcon(canvas) } private fun drawFirstPoint(canvas: Canvas) {val top = topmFirstX = paddingLeft + mLineMarginLeft + max(mPointOutSize, mPointInnerSize)mFirstY = top + paddingTop + mPointMarginTop + max(mPointOutSize, mPointInnerSize) //畫圓外環mPointPaint?.color = mPointOutColorcanvas.drawCircle(mFirstX.toFloat(), mFirstY.toFloat(), mPointOutSize.toFloat(), mPointPaint)//畫圓內環mPointPaint?.color = mPointInnerColorcanvas.drawCircle(mFirstX.toFloat(), mFirstY.toFloat(), mPointInnerSize.toFloat(), mPointPaint) } private fun drawLastIcon(canvas: Canvas) {/*if (child != null) { int top = child.getTop(); mLastX = mLineMarginLeft; mLastY = top + child.getPaddingTop() + mLineMarginTop; //畫圖 canvas.drawBitmap(mIcon, mLastX - (mIcon.getWidth() >> 1), mLastY, null);}*/val top = topmLastX = mLineMarginLeft + paddingLeftmLastY = top + paddingTop + mLineMarginTop //畫圖if (mIcon != null) { canvas.drawBitmap(mIcon, mLastX - (mIcon!!.width shr 1).toFloat(), height - mIcon!!.height.toFloat(), null)} } private fun drawBetweenLine(canvas: Canvas) {val top = topmFirstX = paddingLeft + mLineMarginLeft + max(mPointOutSize, mPointInnerSize)mFirstY = top + paddingTop + mLineMarginTopmLastX = paddingLeft + mLineMarginLeft + max(mPointOutSize, mPointInnerSize)mLastY = if(!mInterrupt) {top + paddingTop + mLineMarginTop + height} else mPointMarginTop //從開始的點到最后的圖標之間,畫一條線canvas.drawLine(mFirstX.toFloat(), mFirstY.toFloat(), mLastX.toFloat(), mLastY.toFloat(), mLinePaint)//畫圓//val y = top + paddingTop + mLineMarginTop + mPointInnerSize//canvas.drawCircle(mFirstX, y, mPointSize, mPointPaint); } override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {super.onMeasure(widthMeasureSpec, heightMeasureSpec)val mode = MeasureSpec.getMode(widthMeasureSpec)var measuredWidth = MeasureSpec.getSize(widthMeasureSpec)val measuredHeight = MeasureSpec.getSize(heightMeasureSpec)if (mode == MeasureSpec.AT_MOST) { measuredWidth = paddingLeft + mLineMarginLeft + max(mPointOutSize, mPointInnerSize) * 2}setMeasuredDimension(measuredWidth, measuredHeight) }}

布局中可以直接引用,如下:

<com.example.demo1224.TimelineLayoutandroid:layout_width='wrap_content'android:layout_height='match_parent'app:line_margin_left='25dp'app:line_margin_top='0dp'app:point_margin_top='10dp'app:point_inner_color='#377CFF'app:point_out_color='#FFE8F0FF'app:point_out_size='8dp'app:point_inner_size='4dp'app:dash_width='8dp'app:dash_gap='2dp'app:line_color='#C9DCFF'android:orientation='vertical'android:background='@android:color/white'> </com.example.demo1224.TimelineLayout>

也可以在代碼里面動態設置相關屬性(相關屬性注釋,在自定義屬性時有說明):

timelineLayout.setPointMarginTop(10) timelineLayout.setLineMarginTop(10) timelineLayout.setPointMarginTop(40) timelineLayout.setInterrupt(true)

僅供大家參考!

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Android
相關文章:
主站蜘蛛池模板: STRO|DTRO-STRO反渗透膜(科普)_碟滤 | 盘扣式脚手架-附着式升降脚手架-移动脚手架,专ye承包服务商 - 苏州安踏脚手架工程有限公司 | ★济南领跃标识制作公司★济南标识制作,标牌制作,山东标识制作,济南标牌厂 | IIS7站长之家-站长工具-爱网站请使用IIS7站长综合查询工具,中国站长【WWW.IIS7.COM】 | 济南宣传册设计-画册设计_济南莫都品牌设计公司 | 一体化预制泵站-一体化提升泵站-一体化泵站厂家-山东康威环保 | 全自动包装秤_全自动上袋机_全自动套袋机_高位码垛机_全自动包装码垛系统生产线-三维汉界机器(山东)股份有限公司 | 仿真茅草_人造茅草瓦价格_仿真茅草厂家_仿真茅草供应-深圳市科佰工贸有限公司 | 控显科技 - 工控一体机、工业显示器、工业平板电脑源头厂家 | 数控走心机-走心机价格-双主轴走心机-宝宇百科 | 厂房出租_厂房出售_产业园区招商_工业地产&nbsp;-&nbsp;中工招商网 | 团建-拓展-拓展培训-拓展训练-户外拓展训练基地[无锡劲途] | 河南橡胶接头厂家,河南波纹补偿器厂家,河南可曲挠橡胶软连接,河南套筒补偿器厂家-河南正大阀门 | 齿轮减速机电机一体机_齿轮减速箱加电机一体化-德国BOSERL蜗轮蜗杆减速机电机生产厂家 | PC构件-PC预制构件-构件设计-建筑预制构件-PC构件厂-锦萧新材料科技(浙江)股份有限公司 | HDPE储罐_厂家-山东九州阿丽贝防腐设备| 微水泥_硅藻泥_艺术涂料_艺术漆_艺术漆加盟-青岛泥之韵环保壁材 武汉EPS线条_EPS装饰线条_EPS构件_湖北博欧EPS线条厂家 | 周口市风机厂,周鼓风机,河南省周口市风机厂 | 北京网站建设-企业网站建设-建站公司-做网站-北京良言多米网络公司 | 污水/卧式/潜水/钻井/矿用/大型/小型/泥浆泵,价格,参数,型号,厂家 - 安平县鼎千泵业制造厂 | uv固化机-丝印uv机-工业烤箱-五金蚀刻机-分拣输送机 - 保定市丰辉机械设备制造有限公司 | 陕西安闸机-伸缩门-车牌识别-广告道闸——捷申达门业科技 | 合肥升降机-合肥升降货梯-安徽升降平台「厂家直销」-安徽鼎升自动化科技有限公司 | 工业CT-无锡璟能智能仪器有限公司| 全钢实验台,实验室工作台厂家-无锡市辰之航装饰材料有限公司 | 无锡装修装潢公司,口碑好的装饰装修公司-无锡索美装饰设计工程有限公司 | 耐酸碱胶管_耐腐蚀软管总成_化学品输送软管_漯河利通液压科技耐油耐磨喷砂软管|耐腐蚀化学软管 | PC阳光板-PC耐力板-阳光板雨棚-耐力板雨棚,厂家定制[优尼科板材] | 废旧物资回收公司_广州废旧设备回收_报废设备物资回收-益美工厂设备回收公司 | 合肥制氮机_合肥空压机厂家_安徽真空泵-凯圣精机 | 餐饮加盟网_特色餐饮连锁加盟店-餐饮加盟官网 | 拉卡拉POS机官网 - 官方直营POS机办理|在线免费领取 | 自动焊锡机_点胶机_螺丝机-锐驰机器人 | 不锈钢监控杆_监控立杆厂家-廊坊耀星光电科技有限公司 | 盘扣式脚手架-附着式升降脚手架-移动脚手架,专ye承包服务商 - 苏州安踏脚手架工程有限公司 | 北京印刷厂_北京印刷_北京印刷公司_北京印刷厂家_北京东爵盛世印刷有限公司 | 留学生辅导网-在线课程论文辅导-留学生挂科申诉机构 | 滤芯,过滤器,滤油机,贺德克滤芯,精密滤芯_新乡市宇清流体净化技术有限公司 | Eiafans.com_环评爱好者 环评网|环评论坛|环评报告公示网|竣工环保验收公示网|环保验收报告公示网|环保自主验收公示|环评公示网|环保公示网|注册环评工程师|环境影响评价|环评师|规划环评|环评报告|环评考试网|环评论坛 - Powered by Discuz! | 食药成分检测_调料配方还原_洗涤剂化学成分分析_饲料_百检信息科技有限公司 | 展厅设计-展馆设计-专业企业展厅展馆设计公司-昆明华文创意 |