viewgroup自定義元件 側滑元件

2021-07-05 19:31:59 字數 3251 閱讀 2021

繼承viewgroup製作的自定義元件常常是一些布局或者組合元件:

和view的自定義元件類似,需要重寫onmeause和onlayout測量元件的寬高和布局,因為viewgruop裡面包含了子元件,所有在測量和定位的時候都是以子元件為中心進行測量和定位;不需要重寫ondraw方法,因為viewgroup是乙個容器類,我們只需要呼叫它的子元件的draw方法即可

還要注意事件分發時,要重寫onintecepttouchevent,判斷事件來臨時需不需要向子元件傳遞下去;

下面以一下側滑元件為例:

我們建立的元件由兩個子元件組合而成,該元件可以左右側滑,而裡面的子元件「選單欄」可以上下滑動;

1. 建立乙個類,繼承viewgroup,重寫onmeasure和onlayout和構造器

measure

選單欄( 寬度等於自己的真實寬度 高度和父類的控制項相同)

主介面 (寬高都和父控制項相同)

layout:

選單欄 (右邊為 0 ,0 左邊為 -自己寬度長 0 )

主介面 (和父類的相同)

2. 監控事件分發:

當我們在螢幕上滑動時,如何區分是左右滑動還是數值滑動,傳遞給viewgroup還是它的子類scrollview;

需要乙個判斷使用者滑動的長度,大於此長度就認為是滑動;此長度 == viewconfiguration.get(context).getscaletouchslop

用上面的長度,在onintecepttouchevent的move動作中,如果x軸上變化距離大於此變數並且y小於此長度就是水平滑動,返回true,阻斷事件分發;反之fasle

3. 左右的滑動效果

滑動效果的主要在ontouchevent方法裡面完成:

switch(down move up)三個動作,down裡面記錄初始的x座標,move裡面用當前座標減去初始座標就是x軸的位移;

在move中,

view.getscrollx()獲取開始接觸螢幕時的座標,此座標+移動的x軸座標差就是移動後的座標,判斷此座標如果大於0直接scrollto(0,0);如果小於-選單欄的,則移動到左邊的選單欄

view.scrollto(int x,int y)滑動到具體的xy座標

view.scrollby(int dx,int dy); 滑動了多少距離 當前座標加dx和dy

慢慢滑動的效果:

在我們抬起手指,檢視當前的x軸座標,如果小於選單欄/2,往左慢慢滑動選單欄,大於選單欄/2,慢慢滑動右邊

借助scroller輔助類幫助滑動:

startscroll(int startx, int starty, int dx, int dy, int duration) 在規定的時間內完成滑動,模擬滑動,但此方法不會使view滑動

computescrolloffset() 如果模擬沒完成,返回true,完成則false

//重寫view的方法,drawchild -- >> child.draw() -->> computescroll

computescroll()

在此方法中,我們通過判斷computescrolloffset看模擬是否完成,如果沒完成就滑動元件scrollto(scroller.getcurrx,0)然後呼叫 invalidate重畫draw即可實現再次呼叫此方法,直到模擬完成

public

class

sildview

extends

viewgroup

/*測量布局*/

@override

protected

void

onmeasure(int widthmeasurespec, int heightmeasurespec)

/*布局下去*/

@override

protected

void

onlayout(boolean arg0, int l, int t, int r, int b)

@override

public

boolean

ontouchevent(motionevent event) else

if(scrollx > 0)else

lastx = currentx;

break;

case motionevent.action_up:

int midx = -this.getchildat(0).getwidth()/2;

int x = getscrollx();

if(x < midx)else

switchui(viewflag);

break;

}return

true;

}/**

* 選單介面和功能介面的切換

* true為功能介面

* false為選單介面

* 注:滑動是從當前介面滑動到目標位置,而不是直接跳轉到目標position

*/public

void

switchui(boolean flagui)else

//模擬滑動過程

scroller.startscroll(currentx, 0, dx, 0,math.abs(dx)*5);

invalidate(); //此函式會經過viewgroup下面的drawchild()-->child.draw()-->computescroll()最終完成滑動並顯示出來

}@override

public

void

computescroll()

}@override

public

boolean

onintercepttouchevent(motionevent ev)

break;

case motionevent.action_up:

log.i(tag, "action_up: ");

break;

}return

super.onintercepttouchevent(ev);

}//功能介面是否開啟

public

boolean

isshown()

//開啟功能介面

public

void

showview()

//掩藏功能介面

public

void

hideview()

}

自定義ViewGroup之側滑選單

最近pm2.5對側滑選單比較感興趣,很多頁面上都用到了側滑選單,之前也在網上看到了很多關於側滑,有自定義recyclerview,也有自定義item的,但是當自己真正去用的時候,發現有很多問題,所以打算自己參考網上的思路自己寫乙個,果然,看花容易繡花難,寫的很艱辛,不過最後還是實現了,下面看看效果圖...

自定義ViewGroup(一)

1 概述 viewgroup是乙個view的容器,他可以給出childview的測量模式和測量其寬高,他的作用非常重要。childview測量模式 exactly 表示設定了精確的值,一般當childview設定其寬 高為精確值 match parent時,viewgroup會將其設定為exactl...

ViewGroup 自定義控制項

自定義viewgroup這篇文章是針對自定義layoutmanager來寫的,提取出相關自定義的相同點。所有的自定義都可以歸結為在父控制項裡面放置子控制項。一 繼承類 viewgroup 繼承之後需要實現構造,由於一般是在xml中引入所有需要實現以下構造 viewgroup context cont...