2012-01-13 14 views
0

これは数時間前に私を狂ってしまいました。
私はFrameLayoutを持っています、それに1つのボタンがあります。 ボタンをクリックすると、新しい単語を描画し、その周囲に矩形を描くことができるように測定値を取得します。TextViewの測定値は、左上が更新されていません

これは、あなたが「次へ」ボタンをクリックしたときに実行されるコードです:

private OnClickListener m_onClickNext = new OnClickListener() 
{ 
    public void onClick(View v) 
    { 
     TextView tv = new TextView(context);     
     tv.setTextColor(0xFF000000); 
     tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 100);     
     tv.setText("TEXTSTRING"); 

     m_frameLayout.addView(tv, new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.CENTER)); 

     //tv.measure(0, 0); 
     int left = tv.getLeft(); 
     int top = tv.getTop(); 
     int right = left + tv.getMeasuredWidth(); 
     int bottom = top + tv.getMeasuredHeight(); 
    } 
}; 

左とトップは0(ゼロ)です。
tv.measure(0, 0)を追加すると、幅と高さが少なくとも更新されます。

私は、invalidaterequestLayouttvm_frameLayoutに呼び出しましたが、成功しませんでした。

私はレイアウトが描画されていないことを理解しています..しかし、WHY ????

答えて

0

私はレイアウトが描画を終了していないと理解していますが、WHY ????

レイアウトが描画されていない理由は、UI描画が使用するのと同じスレッドを使用しているためです。あなたが行うことは、AsyncTaskや別のスレッドで別途指定しない限り、単一のスレッド(UIスレッド)を使用することです。 Invalidate()は、即時再描画を強制する関数ではありません。 Invalidate()は、UIスレッドが空いているときに無効化されたものをすべて描画するようにフラグを設定します。あなたがUIスレッド命令を与え続けるなら、再描画は起こる機会がありません。

つまり、描画が実行されるまで、Invalidateは数値を変更しません。また、数値を求める前に実行するチャンスが与えられていないため、正しい数値が得られません。これを必要に応じて行うには、次の2つのことを実行する必要があります。

  1. レイアウトを許可する必要があります。これは3つの方法で行うことができます:a)別のスレッドでクリックを実行することはできますが、これはいつ実行されるかを保証するものではありません。 b)invalidate()をオーバーライドして、コールバックを実行して長方形を追加することができます。 c)TextViewのサイズが変更されたときにコードが実行されるように、リスナーを実装することができます。

  2. レイアウトが再描画された後、特殊な四角形を適用できます。上記の方法c)を使うことで、基本的にすぐにこれを行うことができます。しかし、あなたはinvalidate()を再度実行しなければならないので、処理のループが発生する可能性があります。だから、あなたがすでに矩形を描いていて、3度目には無効化しないように指示するための標識を持っていることを確認してください。

これが役に立てば幸い、

FuzzicalLogic

+0

おかげで、私はOnLayoutChangeListener' '実装 – Itsik

関連する問題