日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

关于ViewTreeObserver的理解

發(fā)布時(shí)間:2024/4/17 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于ViewTreeObserver的理解 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
作用:通過(guò)名字就可以知道它是View樹(shù)的觀察者,當(dāng)View樹(shù)的發(fā)生變化的時(shí)候會(huì)發(fā)出通知。ViewTreeObserver是不能被應(yīng)用程序?qū)嵗?#xff0c;因?yàn)樗怯梢晥D提供的,通過(guò)view.getViewTreeObserver()獲取。


熟悉觀察者模式的人應(yīng)該很容易想到,為了能夠相應(yīng)的通知,我們肯定需要注冊(cè)監(jiān)聽(tīng)。下面來(lái)看看我們可以注冊(cè)哪些監(jiān)聽(tīng)。


1、當(dāng)在一個(gè)視圖樹(shù)中的焦點(diǎn)狀態(tài)或者可見(jiàn)性發(fā)生改變時(shí)調(diào)用OnGlobalFocusChangeListener的onGlobalFocusChanged()函數(shù)。


public void addOnGlobalFocusChangeListener (ViewTreeObserver.OnGlobalFocusChangeListener listener)
1
1
2、當(dāng)在一個(gè)視圖樹(shù)中的焦點(diǎn)狀態(tài)或者可見(jiàn)性發(fā)生改變時(shí)調(diào)用OnGlobalFocusChangeListener的onGlobalFocusChanged()函數(shù)。


public void addOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener listener)
1
1
3、當(dāng)一個(gè)視圖樹(shù)將要繪制時(shí)調(diào)用OnPreDrawListener的onPreDraw()函數(shù)


public void addOnPreDrawListener (ViewTreeObserver.OnPreDrawListener listener)
1
1
4、當(dāng)一個(gè)視圖發(fā)生滾動(dòng)時(shí)調(diào)用OnScrollChangedListener的onScrollChanged()函數(shù)


public void addOnScrollChangedListener (ViewTreeObserver.OnScrollChangedListener listener) ?
1
1
5、當(dāng)一個(gè)觸摸模式發(fā)生改變時(shí)調(diào)用OnTouchModeChangeListener的onTouchModeChanged()函數(shù)


public void addOnTouchModeChangeListener (ViewTreeObserver.OnTouchModeChangeListener listener)
1
1
6、當(dāng)一個(gè)視圖樹(shù)繪制時(shí)調(diào)用OnDrawListener的onDraw()函數(shù)


addOnDrawListener(ViewTreeObserver.OnDrawListener listener)?
1
1
7、當(dāng)View樹(shù)綁定到window上的時(shí)候回調(diào)OnWindowAttachListener的onWindowAttached() 函數(shù),當(dāng)它從window上解綁時(shí)調(diào)用OnWindowAttachListener的onWindowDetached()


addOnWindowAttachListener(ViewTreeObserver.OnWindowAttachListener listener)?
1
1
8、當(dāng)window的焦點(diǎn)狀態(tài)發(fā)生改變時(shí),調(diào)用OnWindowFocusChangeListener的onWindowFocusChanged函數(shù)


addOnWindowFocusChangeListener(ViewTreeObserver.OnWindowFocusChangeListener listener)?
1
1
對(duì)應(yīng)這些注冊(cè)的監(jiān)聽(tīng),還有相應(yīng)的刪除監(jiān)聽(tīng)


public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)


public void removeOnGlobalFocusChangeListener (ViewTreeObserver.OnGlobalFocusChangeListener victim)


public void removeOnPreDrawListener (ViewTreeObserver.OnPreDrawListener victim)


public void removeOnScrollChangedListener (ViewTreeObserver.OnScrollChangedListener victim)


public void removeOnTouchModeChangeListener (ViewTreeObserver.OnTouchModeChangeListener victim)


public void removeOnDrawListener(ViewTreeObserver.OnDrawListener victim)?


public void removeOnWindowAttachListener(ViewTreeObserver.OnWindowAttachListener victim)?


public void removeOnWindowFocusChangeListener(ViewTreeObserver.OnWindowFocusChangeListener victim)?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
上面注冊(cè)的監(jiān)聽(tīng)都是View樹(shù)發(fā)生變化的時(shí)候,會(huì)被自動(dòng)觸發(fā)回調(diào),如果我們希望手動(dòng)觸發(fā)回調(diào),可以調(diào)用下面函數(shù)


public final void dispatchOnGlobalLayout ()


手動(dòng)觸發(fā)OnGlobalLayoutListener的onGlobalLayout()函數(shù)回調(diào)


public final boolean dispatchOnPreDraw ()


手動(dòng)觸發(fā)OnPreDrawListener的onPreDraw()函數(shù)的回調(diào)
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
另外還是一個(gè)指示當(dāng)前的ViewTreeObserver是否可用的函數(shù)。


public boolean isAlive ()


當(dāng)observer不可用時(shí),任何方法的調(diào)用(除了這個(gè)方法)都將拋出一個(gè)異常。
1
2
3
1
2
3
應(yīng)用場(chǎng)景1:獲取View的寬高


@Override
protected void onCreate(Bundle savedInstanceState) {
? ? super.onCreate(savedInstanceState);
? ? setContentView(R.layout.activity_main);
? ? final MyImageView myImageView = (MyImageView) findViewById(R.id.imageview);
? ? int height = 0;
? ? int width = ?0 ;
? ? ViewTreeObserver vto = myImageView.getViewTreeObserver();
? ? vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
? ? ? ? public boolean onPreDraw() {
? ? ? ? ? ? int height = myImageView.getMeasuredHeight();
? ? ? ? ? ? int width = myImageView.getMeasuredWidth();
? ? ? ? ? ? return true;
? ? ? ? }
? ? });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
因?yàn)榛卣{(diào)OnPreDrawListener的onPreDraw,表示這個(gè)View準(zhǔn)備進(jìn)行繪制,在繪制之前,這個(gè)View的寬高肯定是已經(jīng)測(cè)量好了,所以這個(gè)時(shí)機(jī)是可以得到view的寬高的。


@Override
protected void onCreate(Bundle savedInstanceState) {
? ? super.onCreate(savedInstanceState);
? ? setContentView(R.layout.activity_main);
? ? final MyImageView myImageView = (MyImageView) findViewById(R.id.imageview);
? ? int height = 0;
? ? int width = ?0 ;


? ? ViewTreeObserver vto = myImageView.getViewTreeObserver();
? ? vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
? ? ? ? @Override
? ? ? ? public void onGlobalLayout() {
? ? ? ? ? ? myImageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
? ? ? ? ? ? int height = myImageView.getHeight();
? ? ? ? ? ? int width = myImageView.getWidth();
? ? ? ? }
? ? });?
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
當(dāng)view的可見(jiàn)狀態(tài)發(fā)生變化的時(shí)候回調(diào)OnGlobalLayoutListener的onGlobalLayout()函數(shù),這個(gè)時(shí)候View的寬高肯定也是已經(jīng)測(cè)量好了,所以這個(gè)時(shí)機(jī)是可以得到view的寬高的。


應(yīng)用場(chǎng)景2:Activity跳轉(zhuǎn)動(dòng)畫


ViewTreeObserver還可以用來(lái)監(jiān)聽(tīng)根布局,用來(lái)實(shí)現(xiàn)Activity跳轉(zhuǎn)動(dòng)畫,核心代碼如下:


@Override
public void onCreate(Bundle savedInstanceState) {
? ? super.onCreate(savedInstanceState);
? ? setContentView(R.layout.activity_second);
? ? rootView = findViewById(R.id.root);
? ? if (savedInstanceState == null) {
? ? ? ? rootView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public boolean onPreDraw() {
? ? ? ? ? ? ? ? rootView.getViewTreeObserver().removeOnPreDrawListener(this);
? ? ? ? ? ? ? ? startRootAnimation();
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? });
? ? }
}

因?yàn)樵诶L制之前會(huì)觸發(fā)OnPreDrawListener的onPreDraw()函數(shù),這個(gè)時(shí)候可以執(zhí)行跳轉(zhuǎn)動(dòng)畫。


應(yīng)用場(chǎng)景3:測(cè)量軟鍵盤狀態(tài)和高度


ViewTreeObserver.OnGlobalLayoutListener mListener = new ViewTreeObserver
? ? ? ? ? ? .OnGlobalLayoutListener() {
? ? ? ? public void onGlobalLayout() {
? ? ? ? ? ? Rect r1 = new Rect();
? ? ? ? ? ? root.getWindowVisibleDisplayFrame(r1);
? ? ? ? ? ? Log.e("TAG",r1.bottom+"") ;?
? ? ? ? }
? ? };
root.getViewTreeObserver().addOnGlobalLayoutListener(mListener);


在根布局加入GlobalLayoutListener監(jiān)聽(tīng),通過(guò)getWindowVisibleDisplayFrame方法可以觀察可見(jiàn)區(qū)域的變化,鍵盤打開(kāi)后 會(huì)影響可見(jiàn)區(qū)域的大小,導(dǎo)致Rect的底部r1.bottom變小。

總結(jié)

以上是生活随笔為你收集整理的关于ViewTreeObserver的理解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。