Getting the size of an inner layout in pixels - android

With the following Java and XML code, I was wondering how to retrieve the dimensions in pixels of an inner/child layout (LinearLayout, whereas the parent is RelativeLayout with paddings of 20dp) properly:
Java code:
public class TestActivity extends Activity {
private LinearLayout linLay;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
linLay = (LinearLayout)findViewById(R.id.linLay);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
linLay.setLayoutParams(lp);
getDimensions();
}
private void getDimensions() {
System.out.println(linLay.getHeight());
System.out.println(linLay.getWidth());
}
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp" >
<LinearLayout
android:id="#+id/linLay"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true">
</LinearLayout>
</RelativeLayout>
... Since I get outputs of 0 for the dimensions, I am aware that the LinearLayout needs to be set first on the screen before I could retrieve the dimensions... But what am I doing wrong here?

It didn't get its dimensions at the time you try to output them.You can just add a delay or just use method below.
private void getDimensions() {
ViewTreeObserver vto = linLay.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener(){
#Override
public voidonGlobalLayout() {
linLay.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int height =linLay.getMeasuredHeight();
int width =linLay.getMeasuredWidth();
System.out.println(height);
System.out.println(width);
}
});
}

Related

Calculate the empty area of a linear layout

I want to construct a generic function which receives a LinearLayout (or another view) and calculate the empty space left in it, so i know how many space i've to fit something into it
The main purpose of it is to set ads, example:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/mainView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".activity.MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="#dimen/profilePhotoRadius"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/smallMargin"
android:layout_marginTop="#dimen/smallMargin"
/>
<!-- bunch of other stuff here -->
<com.google.android.gms.ads.AdView
android:id="#+id/adView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_alignParentBottom="true"/>
</LinearLayout>
then after in my code
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.adView = (AdView) findViewById(R.id.adView);
if (this.adView != null) {
int width = this.adView.getMeasuredWidth();
int height = this.adView.getHeight();
}
but running this code width and height are always zero... i tried to use getWidth() and result is always zero
how can i get the real value?
In OnCreate() you are are just inflating the layout. The UI has not been sized and laid out on the screen yet.You are calling getWidth() and getHeight() too early.
You can try this:
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.adView = (AdView) findViewById(R.id.adView);
this.adView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
touchView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
else {
touchView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
float Width = this.adView.getWidth();
float Height =this.adView.getHeight();
...
}
});
Try it in onWindowFocusChanged (boolean hasFocus) method. From the documentation:
This is the best indicator of whether this activity is visible to the
user

ImageView android abort program

I am programming a android app with ImageView and when I try to change the width and height dynamically, the app stops (abort). I am using the following commands:
RelativeLayout.LayoutParams icon_horizontal = new RelativeLayout.LayoutParams(50, 50);
mec21h_icon2.setLayoutParams(icon_horizontal);
The layout is Relative, so what is wrong?
It would be nice to have a Stack trace in order to understand what the error is.
Without this, I can just guess:
you're trying to use the wrong parent layout params
the ImageView ref is null
...
I guess you are trying to change the image dimensions after it is visible (already displayed), if so you should first call for method requestLayout();
i.e.
mImageView.requestLayout();
Re-size image on Click of a button.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/rel"
tools:context="com.testingpp.scannerbarcode.MainActivity">
<ImageView
android:id="#+id/imageview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="button_one"
android:src="#drawable/btn_back"
/>
</FrameLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
FrameLayout layout;
ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.imageview);
layout = (FrameLayout) findViewById(R.id.rel);
}
public void button_one(View view)
{
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(50,50);
layout.setLayoutParams(params);
}
}
if you are using Framents, then don't use onClick of xml. use onClickListener in java.

Android: stretch layout above another

I create layout (ContentLayout) with wrap_content.
And I want to show loading layout (LoadingLayout) same size as ContentLayout above it.
Something like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout.
android:id="#+id/ContentLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
...
</LinearLayout>
<RelativeLayout
android:id="#+id/LoadingLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
...
</RelativeLayout>
</RelativeLayout>
But when I want set LoadingLayout size in onMeasure, it will be set to right size only in second chance.
Works only something like this:
Activity
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) loadingLayout.getLayoutParams();
params.height = getMeasuredHeight();
loadingLayout.setLayoutParams(params);
super.onMeasure(widthMeasureSpec, heightMeasureSpec); // android realignment hack
}
I think this is a hack. Do you have a better solution?
If I understood correctly, you need LoadingLayout to keep width of ContentLayout
<RelativeLayout
android:id="#+id/LoadingLayout"
android:layout_alignLeft="#id/ContentLayout"
android:layout_alignRight="#id/ContentLayout"
....>
....
</RelativeLayout>
Edit: Below is one way for the height
You can add a one time listener when global refresh happens. Then all sizes will be available.
// in your activity
#Override
protected void onCreate(Bundle state) {
final View loading = findViewById(R.id.LoadingLayout);
final View content = findViewById(R.id.ContentLayout);
content.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
content.getViewTreeObserver().removeOnGlobalLayoutListener(this);
loading.getLayoutParams().height = content.getHeight();
loading.onRequestLayout();
loading.invalidate();
}
}
}

Why linearlayout's size -1?

I'm trying to get linearlayout's size.
I tested as following code.
But I just get value -1 (linearlayout's width).
How to get correct size?
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainLayout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, MyActivity"
/>
</LinearLayout>
package com.example.LayoutSize;
import android.app.Activity;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.LinearLayout;
public class MyActivity extends Activity {
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.mainLayout);
ViewGroup.LayoutParams layoutParams = linearLayout.getLayoutParams();
System.out.printf("linearLayout width : %d", layoutParams.width);
}
}
The reason you get -1 is because the width parameter is set to MatchParent which has a value -1.
To get the size of a layout, your should be using getWidth() or getMeasuredWidth() methods. However, these methods won't give you a meaningful answer until the view has been measured. Read about how android draws views here.
You can get the correct size, by overriding the onWindowFocusChanged() as mentioned in this thread.
Alternatively, (hacky solution), you could do this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final LinearLayout linearLayout = (LinearLayout) findViewById(R.id.mainLayout);
linearLayout.post(new Runnable() {
#Override
public void run() {
System.out.printf("linearLayout width : %d", linearLayout.getMeasuredWidth());
}
});
}
public static final int MATCH_PARENT = -1;

How to set a FrameLayout fill_parent in width and always have a fixed ratio in height?

I see some questions about "ImageView"s, but I need a FrameLayout.
I have a FrameLayout, which I need its width:height = 2:1, and the width is fill_parent. There are many image views inside the frame layout, I can just set them width=fill_parent and height=fill_parent.
I don't find a way to do this, please help .
My xml code is:
<FrameLayout
android:id="#+id/cardView"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:layout_centerInParent="true">
<ImageView
android:id="#+id/frameView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitXY"
android:src="#drawable/card_style1"
/>
</FrameLayout>
See if this is what you want:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
final FrameLayout target = (FrameLayout) findViewById(R.id.frame_id);
target.post(new Runnable() {
#Override
public void run() {
int width = target.getWidth();
int height = width / 2;
LayoutParams lp = target.getLayoutParams();
lp.height = height;
target.setLayoutParams(lp);
}
});
}

Categories

Resources