Xem của getWidth () và getHeight () trả về 0


513

Tôi đang tạo ra tất cả các yếu tố trong dự án Android của tôi một cách linh hoạt. Tôi đang cố gắng để có được chiều rộng và chiều cao của một nút để tôi có thể xoay nút đó xung quanh. Tôi chỉ đang cố gắng học cách làm việc với ngôn ngữ Android. Tuy nhiên, nó trả về 0.

Tôi đã thực hiện một số nghiên cứu và tôi thấy rằng nó cần phải được thực hiện ở một nơi khác ngoài onCreate() phương pháp. Nếu ai đó có thể cho tôi một ví dụ về cách làm điều đó, điều đó sẽ rất tuyệt.

Đây là mã hiện tại của tôi:

package com.animation;

import android.app.Activity;
import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.Button;
import android.widget.LinearLayout;

public class AnimateScreen extends Activity {


//Called when the activity is first created.
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    LinearLayout ll = new LinearLayout(this);

    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    layoutParams.setMargins(30, 20, 30, 0);

    Button bt = new Button(this);
    bt.setText(String.valueOf(bt.getWidth()));

    RotateAnimation ra = new RotateAnimation(0,360,bt.getWidth() / 2,bt.getHeight() / 2);
    ra.setDuration(3000L);
    ra.setRepeatMode(Animation.RESTART);
    ra.setRepeatCount(Animation.INFINITE);
    ra.setInterpolator(new LinearInterpolator());

    bt.startAnimation(ra);

    ll.addView(bt,layoutParams);

    setContentView(ll);
}

Bất kỳ trợ giúp được đánh giá cao.

Câu trả lời:


197

Bạn đang gọi getWidth()quá sớm. Giao diện người dùng chưa được kích thước và đặt trên màn hình.

Tôi nghi ngờ bạn muốn làm những gì bạn đang làm, dù sao đi nữa - các widget đang hoạt hình không thay đổi các khu vực có thể nhấp của chúng và do đó, nút vẫn sẽ phản hồi các nhấp chuột theo hướng ban đầu bất kể nó đã xoay như thế nào.

Điều đó đang được nói, bạn có thể sử dụng tài nguyên kích thước để xác định kích thước nút, sau đó tham chiếu tài nguyên kích thước đó từ tệp bố cục và mã nguồn của bạn, để tránh vấn đề này.


82
ngreenwood6, giải pháp khác của bạn là gì?
Andrew

12
@Andrew - nếu bạn muốn negreenwood6 được thông báo về việc theo dõi của bạn, bạn phải bắt đầu tin nhắn của mình như tôi đã làm với bạn (tôi nghĩ ba chữ cái đầu tiên là đủ) - CommonsWare được thông báo tự động, vì anh ta đã viết phản hồi này, nhưng ngreen không trừ khi bạn giải quyết chúng.
Peter Ajtai

11
@Override void công khai trênWindowF FocusChanged (boolean hasF Focus) {// TODO Phương thức tự động tạo stub super.onWindowF FocusChanged (hasF Focus); // Ở đây bạn có thể có được kích thước! }
Sana

5
@ ngreenwood6 Vậy giải pháp của bạn là gì?
Nima Vaziri

5
Sử dụng trình nghe này để lấy kích thước, khi nào màn hình của bạn sẵn sàng. view.getViewTreeObserver (). addOnGlobalLayoutListener (new ViewTreeObserver.OnGlobalLayoutListener () {}
Sinan Dizdarević

815

Vấn đề cơ bản là, bạn phải chờ pha vẽ cho các phép đo thực tế (đặc biệt là với các giá trị động như wrap_contenthoặc match_parent), nhưng thường thì giai đoạn này chưa được hoàn thành onResume(). Vì vậy, bạn cần một cách giải quyết để chờ đợi giai đoạn này. Có nhiều giải pháp khả thi khác nhau cho vấn đề này:


1. Nghe các sự kiện Vẽ / Bố cục: ViewTreeObserver

Một ViewTreeObserver bị sa thải cho các sự kiện vẽ khác nhau. Thông thường, đó OnGlobalLayoutListenerlà những gì bạn muốn để có được phép đo, vì vậy mã trong trình nghe sẽ được gọi sau giai đoạn bố trí, vì vậy các phép đo đã sẵn sàng:

view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                view.getHeight(); //height is ready
            }
        });

Lưu ý: Người nghe sẽ bị xóa ngay lập tức vì nếu không nó sẽ kích hoạt mọi sự kiện bố trí. Nếu bạn phải hỗ trợ ứng dụng SDK Lvl <16, hãy sử dụng ứng dụng này để hủy đăng ký người nghe:

public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)


2. Thêm một runnable vào hàng đợi bố trí: View.post ()

Không nổi tiếng lắm và giải pháp yêu thích của tôi. Về cơ bản chỉ cần sử dụng phương pháp bài của View với runnable của riêng bạn. Điều này về cơ bản xếp hàng mã của bạn sau khi đo, bố cục, v.v. như được nêu bởi Romain Guy :

Hàng đợi sự kiện UI sẽ xử lý các sự kiện theo thứ tự. Sau khi setContentView () được gọi, hàng đợi sự kiện sẽ chứa một thông báo yêu cầu chuyển tiếp, do đó, bất cứ điều gì bạn đăng lên hàng đợi sẽ xảy ra sau khi vượt qua bố cục

Thí dụ:

final View view=//smth;
...
view.post(new Runnable() {
            @Override
            public void run() {
                view.getHeight(); //height is ready
            }
        });

Ưu điểm hơn ViewTreeObserver:

  • mã của bạn chỉ được thực thi một lần và bạn không phải vô hiệu hóa Trình quan sát sau khi thực thi có thể gây rắc rối
  • cú pháp ít dài dòng

Người giới thiệu:


3. Ghi đè Phương thức onLayout của Lượt xem

Điều này chỉ thực tế trong một số trường hợp nhất định khi logic có thể được gói gọn trong chính khung nhìn, nếu không đây là một cú pháp khá dài dòng và rườm rà.

view = new View(this) {
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        view.getHeight(); //height is ready
    }
};

Cũng lưu ý rằng onLayout sẽ được gọi nhiều lần, vì vậy hãy cân nhắc những gì bạn làm trong phương thức hoặc vô hiệu hóa mã của bạn sau lần đầu tiên


4. Kiểm tra xem đã qua giai đoạn bố trí chưa

Nếu bạn có mã đang thực thi nhiều lần trong khi tạo ui, bạn có thể sử dụng phương thức lib v4 hỗ trợ sau:

View viewYouNeedHeightFrom = ...
...
if(ViewCompat.isLaidOut(viewYouNeedHeightFrom)) {
   viewYouNeedHeightFrom.getHeight();
}

Trả về true nếu chế độ xem đã qua ít nhất một bố cục kể từ lần cuối được gắn vào hoặc tách ra khỏi cửa sổ.


Bổ sung: Lấy số đo xác định tĩnh

Nếu chỉ cần lấy chiều cao / chiều rộng được xác định tĩnh, bạn có thể thực hiện việc này với:

Nhưng lưu ý bạn, rằng điều này có thể khác với chiều rộng / chiều cao thực tế sau khi vẽ. Javadoc mô tả sự khác biệt một cách hoàn hảo:

Kích thước của một khung nhìn được thể hiện bằng chiều rộng và chiều cao. Một khung nhìn thực sự sở hữu hai cặp giá trị chiều rộng và chiều cao.

Cặp đầu tiên được gọi là chiều rộng đo và chiều cao đo. Các kích thước này xác định mức độ lớn mà một khung nhìn muốn nằm trong cha mẹ của nó (xem Bố cục để biết thêm chi tiết.) Các kích thước đo có thể thu được bằng cách gọi getMeasuredWidth () và getMeasuredHeight ().

Cặp thứ hai được gọi đơn giản là chiều rộng và chiều cao, hoặc đôi khi vẽ chiều rộng và chiều cao bản vẽ. Các kích thước này xác định kích thước thực của chế độ xem trên màn hình, tại thời gian vẽ và sau khi bố trí. Các giá trị này có thể, nhưng không phải khác với chiều rộng và chiều cao đo được. Chiều rộng và chiều cao có thể đạt được bằng cách gọi getWidth () và getHeight ().


1
Tôi đang sử dụng view.post trong một đoạn. Tôi cần đo chế độ xem có chiều cao của cha mẹ là 0dp và có trọng số được đặt. Mọi thứ tôi thử đều trả về độ cao bằng 0 (Tôi cũng đã thử trình nghe bố cục toàn cầu). Khi tôi đặt mã view.post trong onViewCreated với độ trễ là 125, nó hoạt động, nhưng không phải là không có độ trễ. Ý tưởng?
Psest328

6
quá tệ, bạn chỉ có thể đưa ra một câu trả lời một lần, giải thích thực sự tốt. Tôi gặp vấn đề với xoay vòng lượt xem nếu tôi thoát khỏi ứng dụng của mình và khởi động lại nó từ các ứng dụng gần đây. Nếu tôi vuốt nó từ đó và khởi động lại thì mọi thứ đều ổn. Các view.post () đã lưu ngày của tôi!
Matthias

1
Cảm ơn. Tôi thường sử dụng View.post () (phương thức thứ 2), nhưng nếu nó được gọi từ một luồng nền thì đôi khi nó không hoạt động. Vì vậy, đừng quên viết runOnUiThread(new Runnable() {...}. Hiện tại tôi sử dụng một biến thể của phương pháp 1 : addOnLayoutChangeListener. Đừng quên xóa nó sau đó bên trong: removeOnLayoutChangeListener. Nó hoạt động từ chủ đề nền là tốt.
CoolMind

2
Thật không may cho tôi 'View.post ()' không hoạt động mọi lúc. Tôi có 2 dự án rất giống nhau. Trong một dự án, nó hoạt động, mặt khác không hoạt động. :(. Trong cả hai tình huống, tôi gọi phương thức từ phương thức 'onCreate ()' từ một Hoạt động. Có gợi ý nào tại sao không?
Adrian Buciuman

1
Tôi tìm thấy vấn đề. Trong một dự án, khung nhìn có android:visibility="gone", và trên dự án khác, thuộc tính hiển thị là invisible. Nếu tầm nhìn là gonechiều rộng sẽ luôn là 0.
Adrian Buciuman

262

Chúng ta có thể sử dụng

@Override
 public void onWindowFocusChanged(boolean hasFocus) {
  super.onWindowFocusChanged(hasFocus);
  //Here you can get the size!
 }

10
Vậy làm thế nào chúng ta có thể làm việc trong Fragment? cái này chỉ hoạt động trong Activity?
Olkunmustafa

8
Điều này nên làm điều đó nhưng nó không phải là câu trả lời. Một người dùng muốn có được kích thước trong bất kỳ thời điểm nào thay vì được vẽ trên cửa sổ. Ngoài ra phương pháp này được gọi nhiều lần hoặc mỗi lần khi có thay đổi (Xem ẩn, biến mất, thêm chế độ xem mới, v.v.) trong cửa sổ. Vì vậy, hãy sử dụng nó một cách cẩn thận :)
Tiến sĩ aNdRO

1
Đây là một hack và có vẻ như sử dụng ViewTreeObserver sẽ tốt hơn.
i_am_jorf

Không có nghĩa là nghe thô lỗ, nhưng để lại một nhận xét được tạo tự động (đặc biệt là trong 2 dòng mã) không mang lại nhiều niềm tin rằng bạn thực sự biết những gì bạn đang làm.
Natix 6/2/2016

Thật không may, nó không làm việc cho tôi. Đang thử viewTreeObserver làm việc cho tôi.
Narendra Singh

109

Tôi đã sử dụng giải pháp này, mà tôi nghĩ là tốt hơn so với onWindowF FocusChanged (). Nếu bạn mở DialogFragment, sau đó xoay điện thoại, onWindowF FocusChanged sẽ chỉ được gọi khi người dùng đóng hộp thoại):

    yourView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            // Ensure you call it only once :
            yourView.getViewTreeObserver().removeGlobalOnLayoutListener(this);

            // Here you can get the size :)
        }
    });

Chỉnh sửa: vì removeGlobalOnLayoutListener không được dùng nữa, bây giờ bạn nên làm:

@SuppressLint("NewApi")
@SuppressWarnings("deprecation")
@Override
public void onGlobalLayout() {

    // Ensure you call it only once :
    if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
        yourView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
    }
    else {
        yourView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
    }

    // Here you can get the size :)
}

4
đây là giải pháp tốt nhất bởi vì nó cũng hoạt động trên các giải pháp động mà chiều rộng và chiều cao không được biết và tính toán. tức là trong một bố cục tương đối dựa trên vị trí / kích thước của các yếu tố khác. Làm tốt!
George Pligoropoulos

2
Điều này yêu cầu API 16 trở lên (Jelly bean)
tomsv

7
Nó KHÔNG YÊU CẦU API 16! Vấn đề duy nhất là phương thức removeGlobalOnLayoutListener không được dùng từ API 16, nhưng có một giải pháp đơn giản tương thích với tất cả các cấp độ api - stackoverflow.com/questions/16189525/iêu
gingo

Nếu bạn cần loại bỏ trình nghe để không tự gọi nhiều lần và bạn gặp vấn đề với các API khác nhau, tôi khuyên bạn nên đặt một boolean sai ở đầu lớp và sau đó sau khi bắt các giá trị được đặt thành đúng để nó không nắm bắt được các giá trị một lần nữa.
Mansour Fahad

Nếu bạn loại bỏ người nghe sau lần chạy đầu tiên, bạn có thể nhận được kích thước sai: 02-14 10: 18: 53.786 15063-15063 / PuzzleFragment: height: 1647 width: 996 02-14 10: 18: 53.985 15063-15063 / PuzzleFragment: height : 1500 chiều rộng: 996
Leos Literak 14/2/2016

76

Như Ian tuyên bố trong chủ đề Nhà phát triển Android này :

Dù sao đi nữa, thỏa thuận là việc bố trí nội dung của một cửa sổ xảy ra sau khi tất cả các yếu tố được xây dựng và thêm vào các khung nhìn chính của chúng. Nó phải theo cách này, bởi vì cho đến khi bạn biết Chế độ xem chứa thành phần nào và chúng chứa những gì, v.v., không có cách nào hợp lý để bạn có thể đặt nó ra.

Dòng dưới cùng, nếu bạn gọi getWidth (), v.v. trong một hàm tạo, nó sẽ trả về 0. Quy trình là tạo tất cả các thành phần khung nhìn của bạn trong hàm tạo, sau đó đợi phương thức onSizeChanged () của View được gọi - đó là khi bạn lần đầu tiên tìm ra kích thước thực của mình, vì vậy đó là khi bạn thiết lập kích thước của các thành phần GUI.

Cũng lưu ý rằng đôi khi onSizeChanged () được gọi với tham số bằng 0 - kiểm tra trường hợp này và trả về ngay lập tức (để bạn không bị chia cho 0 khi tính toán bố cục, v.v.). Một thời gian sau nó sẽ được gọi với các giá trị thực.


8
onSizeChanged làm việc cho tôi. onWindowF FocusedChanged không được gọi trong chế độ xem tùy chỉnh của tôi.
aaronmarino

Đây có vẻ là một giải pháp tốt, nhưng tôi nên luôn tạo chế độ xem tùy chỉnh của mình để ghi đè phương thức onSizeChanged?
M.ElSaka

Bottom line, if you call getWidth() etc. in a constructor, it will return zero.đó là một trò chơi lô tô. Căn nguyên của vấn đề của tôi.
MikeNereson

Tôi đề nghị giải pháp này cho các đoạn, bởi vì một số giải pháp khác trả về 0 trong trường hợp của tôi.
WindRider

66

Nếu bạn cần lấy chiều rộng của một số tiện ích trước khi nó được hiển thị trên màn hình, bạn có thể sử dụng getMeasuredWidth () hoặc getMeasuredHeight ().

myImage.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
int width = myImage.getMeasuredWidth();
int height = myImage.getMeasuredHeight();

5
Vì một số lý do, đây là câu trả lời duy nhất có hiệu quả với tôi - cảm ơn!
Farbod Salamat-Zadeh

Tương tự với tôi, giải pháp đơn giản nhất, có hiệu quả với tôi
Tima

Làm việc như một cơ duyên!
Morales Batovski

1
@CommonsWare giải pháp này cho chiều cao và chiều rộng như thế nào trước khi người quan sát cây xem trên cuộc gọi lại bố cục toàn cầu, một lời giải thích sẽ hữu ích.
Mightian

22

Tôi thà sử dụng OnPreDrawListener()thay vì addOnGlobalLayoutListener(), vì nó được gọi sớm hơn một chút so với những người nghe khác.

    view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
    {
        @Override
        public boolean onPreDraw()
        {
            if (view.getViewTreeObserver().isAlive())
                view.getViewTreeObserver().removeOnPreDrawListener(this);

            // put your code here
            return true;
        }
    });

3
Lưu ý rằng return falsecó nghĩa là để hủy bỏ bản vẽ hiện tại . Để tiến hành, return truethay vào đó.
Pang

9

Tiện ích mở rộng Kotlin để quan sát bố cục toàn cầu và thực hiện một tác vụ nhất định khi chiều cao sẵn sàng linh hoạt.

Sử dụng:

view.height { Log.i("Info", "Here is your height:" + it) }

Thực hiện:

fun <T : View> T.height(function: (Int) -> Unit) {
    if (height == 0)
        viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                viewTreeObserver.removeOnGlobalLayoutListener(this)
                function(height)
            }
        })
    else function(height)
}

7

AndroidX có nhiều chức năng mở rộng giúp bạn thực hiện loại công việc này, bên trong androidx.core.view

Bạn cần sử dụng Kotlin cho việc này.

Một trong những phù hợp nhất ở đây là doOnLayout:

Thực hiện hành động đã cho khi quan điểm này được đặt ra. Nếu chế độ xem được đặt ra và nó không yêu cầu bố cục, hành động sẽ được thực hiện ngay nếu không, hành động sẽ được thực hiện sau khi chế độ xem được đặt tiếp theo.

Hành động sẽ chỉ được gọi một lần trên bố cục tiếp theo và sau đó loại bỏ.

Trong ví dụ của bạn:

bt.doOnLayout {
    val ra = RotateAnimation(0,360,it.width / 2,it.height / 2)
    // more code
}

Phụ thuộc: androidx.core:core-ktx:1.0.0


Đây là câu trả lời đúng duy nhất. android.googlesource.com/pl
platform / frameworks / support / + / Từ

1
các tiện ích mở rộng này thực sự quan trọng và hữu ích
Ahmed na

5

Một lớp lót nếu bạn đang sử dụng RxJava & RxBindings . Cách tiếp cận tương tự mà không cần nồi hơi. Điều này cũng giải quyết vụ hack để ngăn chặn các cảnh báo như trong câu trả lời của Tim Autin .

RxView.layoutChanges(yourView).take(1)
      .subscribe(aVoid -> {
           // width and height have been calculated here
      });

Đây là nó. Không cần phải hủy đăng ký, ngay cả khi không bao giờ được gọi.


4

Nó xảy ra bởi vì khung nhìn cần nhiều thời gian hơn để được thổi phồng. Vì vậy, thay vì gọi view.widthview.heighttrên chuỗi chính, bạn nên sử dụng view.post { ... }để đảm bảo rằng bạn viewđã bị thổi phồng. Trong Kotlin:

view.post{width}
view.post{height}

Trong Java bạn cũng có thể gọi getWidth()getHeight()phương pháp trong một Runnablevà vượt qua Runnableđể view.post()phương pháp.

view.post(new Runnable() {
        @Override
        public void run() {
            view.getWidth(); 
            view.getHeight();
        }
    });

Đây không phải là câu trả lời đúng vì chế độ xem có thể không được đo lường và đặt ra khi mã được đăng thực thi. Nó sẽ là một trường hợp cạnh, nhưng .postkhông đảm bảo quan điểm được đặt ra.
d.aemon

1
Câu trả lời này là tuyệt vời và làm việc cho tôi. Cảm ơn bạn rất nhiều Ehsan
MMG

3

Chiều cao và chiều rộng bằng không vì chế độ xem chưa được tạo vào thời điểm bạn yêu cầu chiều cao và chiều rộng. Một giải pháp đơn giản nhất là

view.post(new Runnable() {
        @Override
        public void run() {
            view.getHeight(); //height is ready
            view.getWidth(); //width is ready
        }
    });

Phương pháp này là tốt so với các phương pháp khác vì nó ngắn và sắc nét.


3

Có lẽ điều này giúp ai đó:

Tạo một hàm mở rộng cho lớp View

tên tệp: ViewExt.kt

fun View.afterLayout(what: () -> Unit) {
    if(isLaidOut) {
        what.invoke()
    } else {
        viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                viewTreeObserver.removeOnGlobalLayoutListener(this)
                what.invoke()
            }
        })
    }
}

Điều này sau đó có thể được sử dụng trên bất kỳ chế độ xem nào với:

view.afterLayout {
    do something with view.height
}

2

Trả lời với postlà không chính xác, vì kích thước có thể không được tính toán lại.
Một điều quan trọng khác là quan điểm và tất cả những gì tổ tiên phải được nhìn thấy . Cho rằng tôi sử dụng một tài sản View.isShown.

Đây là chức năng kotlin của tôi, có thể được đặt ở đâu đó trong utils:

fun View.onInitialized(onInit: () -> Unit) {
    viewTreeObserver.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
        override fun onGlobalLayout() {
            if (isShown) {
                viewTreeObserver.removeOnGlobalLayoutListener(this)
                onInit()
            }
        }
    })
}

Và cách sử dụng là:

myView.onInitialized {
    Log.d(TAG, "width is: " + myView.width)
}

1

Nếu bạn đang sử dụng Kotlin

  leftPanel.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {

            override fun onGlobalLayout() {

                if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
                    leftPanel.viewTreeObserver.removeOnGlobalLayoutListener(this)
                }
                else {
                    leftPanel.viewTreeObserver.removeGlobalOnLayoutListener(this)
                }

                // Here you can get the size :)
                leftThreshold = leftPanel.width
            }
        })

0

Lượt xem đã trả về 0 là chiều cao nếu ứng dụng ở chế độ nền. Mã này của tôi (1oo% hoạt động)

fun View.postWithTreeObserver(postJob: (View, Int, Int) -> Unit) {
    viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
        override fun onGlobalLayout() {
            val widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
            val heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
            measure(widthSpec, heightSpec)
            postJob(this@postWithTreeObserver, measuredWidth, measuredHeight)
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                @Suppress("DEPRECATION")
                viewTreeObserver.removeGlobalOnLayoutListener(this)
            } else {
                viewTreeObserver.removeOnGlobalLayoutListener(this)
            }
        }
    })
}

0

Chúng ta cần chờ xem sẽ được rút ra. Đối với mục đích này, sử dụng OnPreDrawListener. Ví dụ về Kotlin:

val preDrawListener = object : ViewTreeObserver.OnPreDrawListener {

                override fun onPreDraw(): Boolean {
                    view.viewTreeObserver.removeOnPreDrawListener(this)

                    // code which requires view size parameters

                    return true
                }
            }

            view.viewTreeObserver.addOnPreDrawListener(preDrawListener)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.