溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

自定義控件入門及案例

發(fā)布時(shí)間:2020-05-29 19:03:46 來源:網(wǎng)絡(luò) 閱讀:518 作者:屠夫章哥 欄目:移動(dòng)開發(fā)
  • Android View (1) View的樹形結(jié)構(gòu)和坐標(biāo)計(jì)算 - 簡書

  • (5條消息)Android-findViewById()方法分析 - Abe的學(xué)習(xí)之路 - CSDN博客



自定義View必看:?

????? 坐標(biāo)系繪制流程相關(guān):

??????????https://www.jianshu.com/p/a99d1574bc8e

??????????https://www.jianshu.com/p/47786eb9c093

??????????https://blog.csdn.net/suyimin2010/article/details/84418775

? ? ? ? ? ? ? ? ?



    • Android canvas.save()與canvas.restore()的使用總結(jié) - Nothing - CSDN博客

    • 【android】對(duì)canvas的translate(),save(),restore()方法的理解 - 簡書

    • 關(guān)于Canvas的save和restore的那些事 - 朱玉強(qiáng)的博客 - CSDN博客




???? 測(cè)量相關(guān):

??????????https://blog.csdn.net/fan7983377/article/details/88355085

????????? ? ?????

??????????

????? 滑動(dòng)相關(guān):

???????????https://www.cnblogs.com/krislight1105/p/3748281.html

? ?????????https://www.jianshu.com/p/f27b0f2c41b5? (滑動(dòng)沖突)

? ? ? ? ? ?https://blog.csdn.net/gu_solo/article/details/51094413?(scrollTo方法是改變View的內(nèi)容的位置,并非View本身的位置。)

????????? ?android 布局之滑動(dòng)探究 scrollTo 和 scrollBy 方法使用說明 - Leo的銀彈 - 博客園

????????????(8條消息)ScrollTo,ScrollBy是如何改變子View位置的 - gu_solo的博客 - CSDN博客


? ? ? 繪制圖形:

????????? ?在onDraw方法里寫繪制邏輯,通過invalidate可以重新執(zhí)行onDraw方法,不過之前所畫圖形會(huì)先擦除。當(dāng)然可以通過canvas.restore和canvas.save保存之前所畫的圖像

?????

? ? ? ? ??


    • 自定義控件之繪圖篇(一):概述及基本幾何圖形繪制 - 啟艦 - CSDN博客

    • Android canvas.drawArc() 畫圓弧 - 檸萌味的博客 - CSDN博客

    • Android 的Canvas的drawArc方法參數(shù)介紹 - Big_Sweet - CSDN博客

    • Android一種View動(dòng)態(tài)折線繪制的實(shí)現(xiàn)實(shí)戰(zhàn)


???????????https://blog.csdn.net/yanbober/article/details/21000579

? ? ? ??


    • Android自定義View三(坐標(biāo)系與View的繪制流程) - 簡書

    • (8條消息)利用重寫onTouchEvent方法實(shí)現(xiàn)view隨手指移動(dòng)效果 - h65l55的專欄 - CSDN博客

    • (8條消息)【Android】超簡單!打造一個(gè)任意View縮放平移工具 - Jarvis的博客 - CSDN博客


????????

?????????


自定義控件一般分為2種:

????1.組合控件

????????第1種形式:自定義一個(gè)類繼承任意一個(gè)布局(XXLayout),然后復(fù)寫它的構(gòu)造方法,填充view,得到XML屬性并設(shè)置屬性。這

???????????????????? 種形式我在上一篇文章已經(jīng)詳細(xì)講到 ?http://4259297.blog.51cto.com/4249297/1683192

???????? ? 第2種形式:由Android原生的控件組合起來,配合動(dòng)畫實(shí)現(xiàn)的效果。


????2.自定義控件:

????????控件之所以能由代碼轉(zhuǎn)換成視圖展現(xiàn)在屏幕上,在底層主要會(huì)做3件事:測(cè)量(measure)、布局(layout)、繪制(draw),對(duì)應(yīng)的

???????? ?控件類的3個(gè)方法onMeasure、onLayout、onDraw


????????? 自定義控件也有3種形式

???????? ?第1種:View控件繼承View,需要復(fù)寫測(cè)量(onMeasure)、繪制(onDraw)方法。因?yàn)閂iew的擺放位置,是由它的父控件

?????????????????ViewGroup來決定。測(cè)量是指測(cè)量自身的大小。

???????? ?第2種:ViewGroup控件組,繼承ViewGroup,需要復(fù)寫測(cè)量(onMeasure)、布局(onLayout)兩個(gè)方法。測(cè)量是指測(cè)量控件組里的

? ? ? ? ? ? ? ? ?**控件的大小,布局是指怎么擺它里面的控件。繪制就不需要復(fù)寫了,因?yàn)檫@是由控件組里的控件來完成的。

? ? ? ? ? ? ? ? ?**一般addView之前要先測(cè)量View的大小,然后addView,最后通過View的layout方法擺放View的位置。

?????????????????**如果調(diào)用了子View的layout方法,會(huì)引起當(dāng)前類onDraw方法的執(zhí)行。

?????????

????????????????

????????? 第3種:升級(jí)控件,繼承已有的Android控件,在它的基礎(chǔ)之上再作一些修改。 ?



?????????


下面就總結(jié)一下老師上課所講的案例,作為對(duì)自定義控件拋磚引玉作用吧...

組合控件案例

????案例1:優(yōu)酷菜單

????????自定義控件入門及案例

????????

????????上面的這個(gè)動(dòng)畫錄制得比較的粗糙,真實(shí)速度是沒有這么快的。

????????????1)素材和布局

? ? ? ? ? ? ? ? ? ?自定義控件入門及案例 ??

????????????? ?優(yōu)酷菜單分為三級(jí),每一級(jí)采用的都是相對(duì)布局(因?yàn)椴藛卫锏目丶茄刂⌒螖[放的),而且三個(gè)布局的三個(gè)上下的中

????????????心在一條直線且在activity里水平居中。三個(gè)相對(duì)布局是相互疊加在一起的,所以最頂層的布局只能是相對(duì)布局或幀布局。

????????????給3個(gè)布局由里到外取名為level1、level2、level3。

????????????? ?想要實(shí)現(xiàn)這樣的效果,圖片的尺寸是需要計(jì)算和設(shè)計(jì)的,且要為透明。 ?

????????????2)動(dòng)畫類的制作

???????????? 分析可知,顯示或隱藏動(dòng)畫是通過旋轉(zhuǎn)動(dòng)畫來完成的,動(dòng)畫有重載形式(有延時(shí)與無延時(shí)),且動(dòng)畫之間是有關(guān)系的(動(dòng)

????????????畫的個(gè)數(shù)統(tǒng)計(jì),動(dòng)畫監(jiān)聽機(jī)制),所以動(dòng)畫應(yīng)該寫在一個(gè)類當(dāng)中。

????????????? ?

????/**
?????*?自定義動(dòng)畫工具類
?????*?工具類不一定非要是靜態(tài)的方法,靜態(tài)雖然不用new,但是會(huì)有太多的限制。
?????*?@author?LENOVO
?????*?
?????*/
????
????
????public?class?MyAnimUtils?{
	??public?int?runningAnimations?=?0;
	??MyAnimationListener?listener?=?new?MyAnimationListener();
	??
	//暴露方法-有沒有動(dòng)畫正在運(yùn)行
	??public?boolean?isRunningAnimation()
	??{
		??return?runningAnimations?!=?0;
	??}
	??
	??
	??
	//?隱藏菜單動(dòng)畫
	public??boolean?startHideAnimation(Context?context,?View?view)?{
		return?startHideAnimation(context,?view,?0);
	}

	//?隱藏菜單動(dòng)畫-延時(shí)
	public??boolean?startHideAnimation(Context?context,?View?view,
			int?startOffset)?{
		
		//因?yàn)檠a(bǔ)間動(dòng)畫不會(huì)改變控件原有的坐標(biāo)位置,雖然不可見了,但是還是可以點(diǎn)擊。
		//?找到View里所有的控件,使它們不可用。
		RelativeLayout?rl?=?(RelativeLayout)?view;
		int?childCount?=?rl.getChildCount();
		for?(int?i?=?0;?i?<?childCount;?i++)?{
			rl.getChildAt(i).setEnabled(false);
		}

		Animation?hideAnimation?=?AnimationUtils.loadAnimation(context,
				R.anim.zero_to_fu180);
		hideAnimation.setStartOffset(startOffset);
		view.startAnimation(hideAnimation);
		//?動(dòng)畫監(jiān)聽
		hideAnimation.setAnimationListener(listener);
		return?false;?//?表示隱藏菜單
	}

	//?顯示菜單動(dòng)畫
	public??boolean?startShowAnimation(Context?context,?View?view)?{
		return?startShowAnimation(context,?view,?0);
	}

	//?顯示菜單動(dòng)畫-延時(shí)
	public??boolean?startShowAnimation(Context?context,?View?view,
			int?startOffset)?{

		//?找到View里所有的控件,使它們可用。
		RelativeLayout?rl?=?(RelativeLayout)?view;
		int?childCount?=?rl.getChildCount();
		for?(int?i?=?0;?i?<?childCount;?i++)?{
			rl.getChildAt(i).setEnabled(true);
		}

		Animation?showAnimation?=?AnimationUtils.loadAnimation(context,
				R.anim.fu180_to_zero);
		showAnimation.setStartOffset(startOffset);
		view.startAnimation(showAnimation);
		//?動(dòng)畫監(jiān)聽
		showAnimation.setAnimationListener(listener);
		return?true;?//?表示顯示菜單
	}

	
	//自定義動(dòng)畫監(jiān)聽類(自己監(jiān)聽自己)
	private?class?MyAnimationListener?implements?AnimationListener
	{
		@Override
		public?void?onAnimationStart(Animation?animation)?{
			runningAnimations++;
		}

		@Override
		public?void?onAnimationRepeat(Animation?animation)?{

		}

		@Override
		public?void?onAnimationEnd(Animation?animation)?{
			runningAnimations--;
		}
	}
	
????}

? ? ? ? ? ??3)顯示或隱藏動(dòng)畫的布局和邏輯

????????????第1步:初始化操作

????????????????實(shí)例動(dòng)畫類,findview,注冊(cè)點(diǎn)擊事件。

????????????第2步:點(diǎn)擊事件

??????????????■menu(菜單)鍵的點(diǎn)擊事件邏輯

?????????????????如果第三級(jí)菜單level3隱藏/關(guān)閉,關(guān)閉/隱藏第三級(jí)菜單level3,且在關(guān)閉/隱藏動(dòng)畫未執(zhí)行完之前,不會(huì)執(zhí)行隱藏

????????????????/關(guān)閉動(dòng)畫。

????????????????



升級(jí)控件,繼承已有的Android控件?

? 實(shí)際場景1:




拓展:

1。關(guān)于onDraw()方法不被執(zhí)行的解決方法(setWillNotDraw),經(jīng)常見到別人自定義控件的時(shí)候使用。

??http://blog.csdn.net/look85/article/details/8442675


2.最簡單也最難——如何獲取到Android控件的高度

?http://www.2cto.com/kf/201410/341592.html??


3.Android 獲得view的寬和高

????http://blog.csdn.net/yangdeli888/article/details/25405263

4.Android?getWidth和getMeasuredWidth?區(qū)別

? ??http://blog.sina.com.cn/s/blog_4b93170a0102e2ns.html


豎直的seekBar

https://github.com/lexluthors/VerticalSeekbar



?

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI