Activityで取得したviewの高さと幅が0の理由と解決策
4332 ワード
ActivityでViewを呼び出すことができます.getWidth、View.getHeight()、View.getMeasuredWidth() 、View.getgetMeasuredHeight()は、ビューの幅または高さを取得しますが、onCreate()、onStrart()、onResume()メソッドでは0が返されます.WindowPhoneに追加されていないDecorViewまたは取得すべきviewがDecorViewに追加されていないか、またはそのViewのvisibility属性がgoneまたはそのviewのwidthまたはheightが本当に0であるため、上記の条件が成立しない場合にのみ0以外のwidthおよびheightが得られる
だから得られるwidthとheightを真実に有効にするには、以下の方法があります.
1.このビューのイベントコールバックで使用すると、イベントをクリックしてイベントフォーカスイベントをタッチするなど、DecorViewに表示されて追加される
[java] view plain copy
View view=findViewById(R.id.tv);
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int width = v.getWidth();
}
});
2.activityが表示されたときにDecorViewに追加されたときのonWindowFocusChanged()のような幅と高さのコールバックメソッドの取得
[java] view plain copy
@Override
public void onWindowFocusChanged(boolean hasFocus) {
View iv1 = findViewById(R.id.iv1);
View iv2=findViewById(R.id.iv2);
String msg1="iv1' width:"+iv1.getWidth()+" height:"+iv1.getHeight()+" measuredWidth:"+iv1.getMeasuredWidth()+"measuredHeight:"+iv1.getMeasuredHeight();
String msg2="iv2' width:"+iv2.getWidth()+" height:"+iv2.getHeight()+" measuredWidth:"+iv2.getMeasuredWidth()+"measuredHeight:"+iv2.getMeasuredHeight();
i("onWindowFocusChanged() "+msg1);
i("onWindowFocusChanged() "+msg2);
super.onWindowFocusChanged(hasFocus);
}
3.またはonResumeメソッドの最後にスレッドを300ミリ秒程度開いた後に幅と高さを取得します.onResume実行後300ミリ秒後にインタフェースが表示されるからです.
もちろん2つの方法と3つの方法は、幅の広いviewがsetContentViewのときに設定されたViewまたはそのサブViewであることを保証する.
[java] view plain copy
view.postDelayed(new Runnable() {
@Override
public void run() {
View iv1 = findViewById(R.id.iv1);
View iv2=findViewById(R.id.iv2);
String msg1="iv1' width:"+iv1.getWidth()+" height:"+iv1.getHeight()+" measuredWidth:"+iv1.getMeasuredWidth()+"measuredHeight:"+iv1.getMeasuredHeight();
String msg2="iv2' width:"+iv2.getWidth()+" height:"+iv2.getHeight()+" measuredWidth:"+iv2.getMeasuredWidth()+"measuredHeight:"+iv2.getMeasuredHeight();
i("onWindowFocusChanged() "+msg1);
i("onWindowFocusChanged() "+msg2);
}
}, 300);
4.onCreate()やonResume()などの方法で幅を広くする必要がある場合はgetViewTreeObserver()を用いる.addOnGlobalLayoutListener()は、viewにコールバックを追加し、コールバックで幅または高さを取得した後、viewにコールバックを削除させる
[java] view plain copy
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
view.postDelayed(new Runnable() {
@Override
public void run() {
View iv1 = findViewById(R.id.iv1);
View iv2=findViewById(R.id.iv2);
String msg1="iv1' width:"+iv1.getWidth()+" height:"+iv1.getHeight()+" measuredWidth:"+iv1.getMeasuredWidth()+"measuredHeight:"+iv1.getMeasuredHeight();
String msg2="iv2' width:"+iv2.getWidth()+" height:"+iv2.getHeight()+" measuredWidth:"+iv2.getMeasuredWidth()+"measuredHeight:"+iv2.getMeasuredHeight();
i("onWindowFocusChanged() "+msg1);
i("onWindowFocusChanged() "+msg2);
}
}, 300);
}
});
GlobalLayoutListenerを削除
コピーしてGoogle翻訳
翻訳結果
だから得られるwidthとheightを真実に有効にするには、以下の方法があります.
1.このビューのイベントコールバックで使用すると、イベントをクリックしてイベントフォーカスイベントをタッチするなど、DecorViewに表示されて追加される
[java] view plain copy
View view=findViewById(R.id.tv);
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int width = v.getWidth();
}
});
2.activityが表示されたときにDecorViewに追加されたときのonWindowFocusChanged()のような幅と高さのコールバックメソッドの取得
[java] view plain copy
@Override
public void onWindowFocusChanged(boolean hasFocus) {
View iv1 = findViewById(R.id.iv1);
View iv2=findViewById(R.id.iv2);
String msg1="iv1' width:"+iv1.getWidth()+" height:"+iv1.getHeight()+" measuredWidth:"+iv1.getMeasuredWidth()+"measuredHeight:"+iv1.getMeasuredHeight();
String msg2="iv2' width:"+iv2.getWidth()+" height:"+iv2.getHeight()+" measuredWidth:"+iv2.getMeasuredWidth()+"measuredHeight:"+iv2.getMeasuredHeight();
i("onWindowFocusChanged() "+msg1);
i("onWindowFocusChanged() "+msg2);
super.onWindowFocusChanged(hasFocus);
}
3.またはonResumeメソッドの最後にスレッドを300ミリ秒程度開いた後に幅と高さを取得します.onResume実行後300ミリ秒後にインタフェースが表示されるからです.
もちろん2つの方法と3つの方法は、幅の広いviewがsetContentViewのときに設定されたViewまたはそのサブViewであることを保証する.
[java] view plain copy
view.postDelayed(new Runnable() {
@Override
public void run() {
View iv1 = findViewById(R.id.iv1);
View iv2=findViewById(R.id.iv2);
String msg1="iv1' width:"+iv1.getWidth()+" height:"+iv1.getHeight()+" measuredWidth:"+iv1.getMeasuredWidth()+"measuredHeight:"+iv1.getMeasuredHeight();
String msg2="iv2' width:"+iv2.getWidth()+" height:"+iv2.getHeight()+" measuredWidth:"+iv2.getMeasuredWidth()+"measuredHeight:"+iv2.getMeasuredHeight();
i("onWindowFocusChanged() "+msg1);
i("onWindowFocusChanged() "+msg2);
}
}, 300);
4.onCreate()やonResume()などの方法で幅を広くする必要がある場合はgetViewTreeObserver()を用いる.addOnGlobalLayoutListener()は、viewにコールバックを追加し、コールバックで幅または高さを取得した後、viewにコールバックを削除させる
[java] view plain copy
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
view.postDelayed(new Runnable() {
@Override
public void run() {
View iv1 = findViewById(R.id.iv1);
View iv2=findViewById(R.id.iv2);
String msg1="iv1' width:"+iv1.getWidth()+" height:"+iv1.getHeight()+" measuredWidth:"+iv1.getMeasuredWidth()+"measuredHeight:"+iv1.getMeasuredHeight();
String msg2="iv2' width:"+iv2.getWidth()+" height:"+iv2.getHeight()+" measuredWidth:"+iv2.getMeasuredWidth()+"measuredHeight:"+iv2.getMeasuredHeight();
i("onWindowFocusChanged() "+msg1);
i("onWindowFocusChanged() "+msg2);
}
}, 300);
}
});
GlobalLayoutListenerを削除
if(Build.VERSION.SDK_INT>=16){
tv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}else{
tv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
コピーしてGoogle翻訳
翻訳結果