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

您的位置:首頁技術(shù)文章
文章詳情頁

Android自定義控件實(shí)現(xiàn)時(shí)間軸

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

本文實(shí)例為大家分享了Android自定義控件實(shí)現(xiàn)時(shí)間軸的具體代碼,供大家參考,具體內(nèi)容如下

由于項(xiàng)目中有需求,就簡(jiǎn)單的封裝一個(gè),先記錄一下,有時(shí)間上傳到github。

1、先增加自定義屬性:

<?xml version='1.0' encoding='utf-8'?><resources> <declare-styleable name='global_TimelineLayout'><!--時(shí)間軸左偏移值--><attr name='global_line_margin_left' format='dimension' /><!--時(shí)間軸上偏移值--><attr name='global_line_margin_top' format='dimension' /><!--線寬--><attr name='global_line_stroke_width' format='dimension' /><!--線的顏色--><attr name='global_line_color' format='color' /><!--點(diǎn)的大小--><attr name='global_point_inner_size' format='dimension' /><attr name='global_point_out_size' format='dimension' /><!--點(diǎn)的上偏移值--><attr name='global_point_margin_top' format='dimension' /><!--點(diǎn)的顏色--><attr name='global_point_inner_color' format='color' /><attr name='global_point_out_color' format='color' /><!--圖標(biāo)--><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、自定義時(shí)間軸類:

/** * 時(shí)間軸控件 * <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 //內(nèi)圓半徑 private var mPointInnerSize: Int = 8 //外圓半徑 private var mPointOutSize: Int = 18 //內(nèi)圓顏色 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 //點(diǎn)的畫筆 private var mPointPaint: Paint? = null //第一個(gè)點(diǎn)的位置 private var mFirstX = 0 private var mFirstY = 0 //最后一個(gè)圖標(biāo)的位置 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 //虛線設(shè)置 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) //畫圓外環(huán)mPointPaint?.color = mPointOutColorcanvas.drawCircle(mFirstX.toFloat(), mFirstY.toFloat(), mPointOutSize.toFloat(), mPointPaint)//畫圓內(nèi)環(huán)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 //從開始的點(diǎn)到最后的圖標(biāo)之間,畫一條線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>

也可以在代碼里面動(dòng)態(tài)設(shè)置相關(guān)屬性(相關(guān)屬性注釋,在自定義屬性時(shí)有說明):

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

僅供大家參考!

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Android
相關(guān)文章:
主站蜘蛛池模板: 卫生纸复卷机|抽纸机|卫生纸加工设备|做卫生纸机器|小型卫生纸加工需要什么设备|卫生纸机器设备多少钱一台|许昌恒源纸品机械有限公司 | 南京泽朗生物科技有限公司 | 低噪声电流前置放大器-SR570电流前置放大器-深圳市嘉士达精密仪器有限公司 | 粉丝机械,粉丝烘干机,粉丝生产线-招远市远东粉丝机械有限公司 | 打造全球沸石生态圈 - 国投盛世| 激光内雕_led玻璃_发光玻璃_内雕玻璃_导光玻璃-石家庄明晨三维科技有限公司 激光内雕-内雕玻璃-发光玻璃 | 东风体检车厂家_公共卫生体检车_医院体检车_移动体检车-锦沅科贸 | 中国品牌排名投票_十大品牌榜单_中国著名品牌【中国品牌榜】 | 二氧化碳/活性炭投加系统,次氯酸钠发生器,紫外线消毒设备|广州新奥 | HDPE土工膜,复合土工膜,防渗膜价格,土工膜厂家-山东新路通工程材料有限公司 | 环讯传媒,永康网络公司,永康网站建设,永康小程序开发制作,永康网站制作,武义网页设计,金华地区网站SEO优化推广 - 永康市环讯电子商务有限公司 | 泡沫消防车_水罐消防车_湖北江南专用特种汽车有限公司 | 欧美日韩国产一区二区三区不_久久久久国产精品无码不卡_亚洲欧洲美洲无码精品AV_精品一区美女视频_日韩黄色性爱一级视频_日本五十路人妻斩_国产99视频免费精品是看4_亚洲中文字幕无码一二三四区_国产小萍萍挤奶喷奶水_亚洲另类精品无码在线一区 | 东莞压铸厂_精密压铸_锌合金压铸_铝合金压铸_压铸件加工_东莞祥宇金属制品 | 西子馋火锅鸡加盟-太原市龙城酉鼎餐饮管理有限公司 | 郑州外墙清洗_郑州玻璃幕墙清洗_郑州开荒保洁-河南三恒清洗服务有限公司 | 袋式过滤器,自清洗过滤器,保安过滤器,篮式过滤器,气体过滤器,全自动过滤器,反冲洗过滤器,管道过滤器,无锡驰业环保科技有限公司 | 二手注塑机回收_旧注塑机回收_二手注塑机买卖 - 大鑫二手注塑机 二手光谱仪维修-德国OBLF光谱仪|进口斯派克光谱仪-热电ARL光谱仪-意大利GNR光谱仪-永晖检测 | 高低温试验房-深圳高低温湿热箱-小型高低温冲击试验箱-爱佩试验设备 | 播音主持培训-中影人教育播音主持学苑「官网」-中国艺考界的贵族学校 | 干粉砂浆设备-干粉砂浆生产线-干混-石膏-保温砂浆设备生产线-腻子粉设备厂家-国恒机械 | SDG吸附剂,SDG酸气吸附剂,干式酸性气体吸收剂生产厂家,超过20年生产使用经验。 - 富莱尔环保设备公司(原名天津市武清县环保设备厂) | SDI车窗夹力测试仪-KEMKRAFT方向盘测试仪-上海爱泽工业设备有限公司 | 中国产业发展研究网 - 提供行业研究报告 可行性研究报告 投资咨询 市场调研服务 | 全自动烧卖机厂家_饺子机_烧麦机价格_小笼汤包机_宁波江北阜欣食品机械有限公司 | 飞象网 - 通信人每天必上的网站| 皮带机_移动皮带机_大倾角皮带机_皮带机厂家 - 新乡市国盛机械设备有限公司 | 螺旋绞龙叶片,螺旋输送机厂家,山东螺旋输送机-淄博长江机械制造有限公司 | 网架支座@球铰支座@钢结构支座@成品支座厂家@万向滑动支座_桥兴工程橡胶有限公司 | 上海律师咨询_上海法律在线咨询免费_找对口律师上策法网-策法网 广东高华家具-公寓床|学生宿舍双层铁床厂家【质保十年】 | 玻璃钢型材_拉挤模具_玻璃钢拉挤设备——滑县康百思 | 动物麻醉机-数显脑立体定位仪-北京易则佳科技有限公司 | 垃圾压缩设备_垃圾处理设备_智能移动式垃圾压缩设备--山东明莱环保设备有限公司 | SMN-1/SMN-A ABB抽屉开关柜触头夹紧力检测仪-SMN-B/SMN-C-上海徐吉 | 耐破强度测试仪-纸箱破裂强度试验机-济南三泉中石单品站 | 全自动翻转振荡器-浸出式水平振荡器厂家-土壤干燥箱价格-常州普天仪器 | 有机废气处理-rto焚烧炉-催化燃烧设备-VOC冷凝回收装置-三梯环境 | 全自动不干胶贴标机_套标机-上海今昂贴标机生产厂家 | 微波萃取合成仪-电热消解器价格-北京安合美诚科学仪器有限公司 | 船用泵,船用离心泵,船用喷射泵,泰州隆华船舶设备有限公司 | 温湿度记录纸_圆盘_横河记录纸|霍尼韦尔记录仪-广州汤米斯机电设备有限公司 |