[英]How to get programmatically width and height of Relative - Linear layout in android?
[英]Get height and width of a layout programmatically
我設計了一個布局,其中LinearLayout
有 2 個孩子LinearLayout
和FrameLayout
並且在每個孩子中我放置了不同的視圖。
我只是想測量FrameLayout
高度和寬度,以便達到我的目的。
在我使用的程序中
int height,width;
FrameLayout fr=(FrameLayout)findviewbyid(R.id.fr);
height=fr.getHeight();
width=fr.getWidth();
兩者都返回0
值
即使我嘗試使用以下代碼 int height,width;
FrameLayout fr=(FrameLayout)findviewbyid(R.id.fr);
height=fr.getMeasuredHeight();
width=fr.getMeasuredWidth();
返回相同的值0
最后我嘗試了以下代碼,int height,width;
FrameLayout fr=(FrameLayout)findviewbyid(R.id.fr);
height=fr.getgetLayoutParams().height();
width=fr.getLayoutParams().width;
返回我-2
和-1
我希望解決方案以編程方式獲取任何布局的高度和寬度?
視圖本身有自己的生命周期,基本如下:
隨附的
實測
布局
畫
因此,根據您何時嘗試獲取寬度/高度,您可能看不到您期望看到的內容,例如,如果您在 onCreate 期間執行此操作,那么到那時甚至可能還沒有測量視圖,另一方面如果您在按鈕的 onClick 方法期間這樣做,很可能到目前為止該視圖已被附加、測量、布局和繪制,因此,您將看到預期值,您應該實現一個 ViewTreeObserver 以確保您獲得在適當的時候值。
LinearLayout layout = (LinearLayout)findViewById(R.id.YOUR VIEW ID);
ViewTreeObserver vto = layout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
this.layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
this.layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
int width = layout.getMeasuredWidth();
int height = layout.getMeasuredHeight();
}
});
正如 CapDroid 所說,您正在嘗試在繪制視圖之前獲取大小,另一種可能的解決方案可能是在視圖上使用可運行對象執行 Post:
mView.post(new Runnable() {
@Override
public void run() {
int width = mView.getWidth();
int height = mView.getHeight();
}
}
我認為您在 OnCreate() 方法中獲得 Height 和 Width 這就是為什么您始終獲得 0 值的原因,因為當時您的視圖仍未創建。
嘗試在單擊某些按鈕時獲取高度和寬度,否則..
只是想在這里添加一個答案,因為 Koltin 有一些方便的方法來做到這一點,這比添加和刪除onGlobalLayoutListener
少得多:
view.doOnLayout {
it.measuredWidth
it.measuredHeight
}
您可以在此處查看更多便利方法。
只需給出您的高度,如果需要,您將獲得高度甚至寬度。
/** * 獲取視圖渲染前的視圖高度 * @param view 要測量的視圖 * @return 視圖的高度 */
public static int getViewHeight(View view) {
WindowManager wm =
(WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int deviceWidth;
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2){
Point size = new Point();
display.getSize(size);
deviceWidth = size.x;
} else {
deviceWidth = display.getWidth();
}
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(deviceWidth, View.MeasureSpec.AT_MOST);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
view.measure(widthMeasureSpec, heightMeasureSpec);
return view.getMeasuredHeight(); // view.getMeasuredWidth();
}
在 Kotlin 中,您可以簡單地執行以下操作:
fr.post {
height=fr.height
width=fr.width
}
如果你得到 -1 或 -2,它也可能是 LayoutParams.WRAP_CONTENT (-2) 或 LayoutParams.MATCH_PARENT (-1) 的數值。
我有同樣的問題,但不想在測量之前在屏幕上繪制,所以我在嘗試獲取高度和寬度之前使用了這種測量視圖的方法。
使用示例:
layoutView(view);
int height = view.getHeight();
//...
void layoutView(View view) {
view.setDrawingCacheEnabled(true);
int wrapContentSpec =
MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
view.measure(wrapContentSpec, wrapContentSpec);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
}
最簡單的方法是使用 ViewTreeObserver,如果你直接使用 .height 或 .width 你得到的值為 0,因為視圖在我們的屏幕上繪制之前沒有大小。 下面的例子將展示如何使用 ViewTreeObserver
ViewTreeObserver viewTreeObserver = YOUR_VIEW_TO_MEASURE.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
YOUR_VIEW_TO_MEASURE.getViewTreeObserver().removeOnGlobalLayoutListener(this);
int viewHeight = YOUR_VIEW_TO_MEASURE.getHeight();
int viewWeight = YOUR_VIEW_TO_MEASURE.getWidth();
}
});
}
如果你需要在方法上使用這個,像這樣使用並保存你可以使用全局變量的值。
試試這個方法:
int width = mView.getMeasuredWidth();
int height = mView.getMeasuredHeight();
或者
int width = mTextView.getMeasuredWidth();
int height = mTextView.getMeasuredHeight();
從這個鏈接嘗試類似這樣的代碼
ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
viewWidth = view.getWidth();
viewHeight = view.getHeight();
}
});
}
希望這可以幫助。
當我剛遇到這個問題時,我以為我會為 kotlin 編寫它,
my_view.viewTreeObserver.addOnGlobalLayoutListener {
// here your view is measured
// get height using my_view.height
// get width using my_view.width
}
或者
my_view.post {
// here your view is measured
// get height using my_view.height
// get width using my_view.width
}
第一個片段是正確的,但您需要在onMeasure()
執行后調用它。 否則,視圖的大小尚未測量。
對於框架:
height=fr.getHeight();
width=fr.getWidth();
對於屏幕:
width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();
我使用 DisplayMetrics 來獲取屏幕尺寸,然后我可以將寬度/高度分配給 %age 中的元素
會是這樣
DisplayMetrics dmetrics = new DisplayMetrics();
int widthPixels=dmetrics.widthPixels;
int heightPixels=dmetrics.heightPixels;
//setting the height of the button
button_nextPuzzle.setMinHeight((int) ((heightPixels/3)*.30));
為我工作得很好!!!
檢查行為非常簡單的解決方案
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d(LOG, "MainActivity - onCreate() called")
fragments_frame.post {
Log.d(LOG, " fragments_frame.height:${fragments_frame.width}")
Log.d(LOG, " fragments_frame.height:${fragments_frame.measuredWidth}")
}
}
如果您在 Kotlin 中編寫代碼,請使用這個不錯的擴展函數:
inline fun View.getDimensions(crossinline onDimensionsReady: (Int, Int) -> Unit) {
lateinit var layoutListener: ViewTreeObserver.OnGlobalLayoutListener
layoutListener = ViewTreeObserver.OnGlobalLayoutListener {
viewTreeObserver.removeOnGlobalLayoutListener(layoutListener)
onDimensionsReady(width, height)
}
viewTreeObserver.addOnGlobalLayoutListener(layoutListener)
}
用法 :
view.getDimensions { width, height ->
println("width = $width")
println("height = $height")
}
getDefaultDisplay().getHeight 已棄用。 所以更好地使用
getResources().getDisplayMetrics().heightPixels;
你也可以使用協程,就像這樣:
CoroutineScope(Dispatchers.Main).launch {
delay(10)
val width = view.width()
val height= view.height()
// do your job ....
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.