在Runnable外时,LinearLayout.getwidth为零

时间:2019-01-26 21:19:10

标签: java android

我试图获取LinearLayout的宽度。

这是MainActivity.java的代码:

public class MainActivity extends AppCompatActivity {
        BoardClass board;
        private int widthareagame;
       @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       final LinearLayout  gamearea;
        ImageView im1 ;
        Button abutton;
        abutton = (Button) findViewById(R.id.buttonnew);
        gamearea = ( LinearLayout)  findViewById(R.id.boardarea);
        gamearea.post(new Runnable(){
            public void run(){
                widthareagame = gamearea.getWidth();
            }
        });

        board = new BoardClass(this,widthareagame);
        gamearea.addView(board);
    }

widthareagamenew BoardClass(this,widthareagame);的值仍然为零。

谢谢

3 个答案:

答案 0 :(得分:0)

这是因为post方法调用将widthareagame的设置排队在视图呈现时所在的位置。您不能保证执行的顺序。

您必须确保先执行run方法中的语句,然后再调用new Board(..。为此,您可以执行以下操作

final AtomicBoolean done = new AtomicBoolean(false);
run(){
//inside run method
done.set(true);
notify();
}

然后做类似的事情

synchronized(task) {
            while(!done.get()) {
                task.wait();
            }
   new Board(..

        }
where task is your runnable task defined something like this
final Runnable task = new Runnable() {
            @Override
            public void run() {

答案 1 :(得分:0)

这是documentation关于View#post()的内容:

  

导致将Runnable添加到消息队列中。可运行   将在用户界面线程上运行。

您修改widthareagame变量的值的任务已被推送到视图的消息队列中。它不能保证它会在同一实例上执行。然后,控件继续进行到下一行,您仍将获得未修改的值。

您可以尝试执行以下操作,以确保您可以使用修改后的值:

gamearea.post(new Runnable(){
            public void run(){
                widthareagame = gamearea.getWidth();
                board = new BoardClass(this,widthareagame);
                gamearea.addView(board);
            }
        });

答案 2 :(得分:0)

之所以为零,是因为尚未在onCreate内测量LinearLayout。 之所以只能在Runnable中运行,是因为自从发布该代码以来,它将在下一个执行周期(即onCreate和Activity生命周期的其余方法(onStart,onResume等)之后)运行,并且甚至onAttachedToWindow都已被调用,此时将已经测量并给出正确的大小。

说了这么多,确定布局指标的一种更安全的方法是在布局状态更改时进行监听。

gamearea.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        // Remove the listener here unless you want to get this callback for
        // "every" layout pass, which can get you into an infinite loop if you
        // modify the layout from within this method
        gamearea.getViewTreeObserver().removeGlobalOnLayoutListener(this);

        // A this point you can get the width and height
        widthareagame = gamearea.getWidth();
    }
});