I have a layout that contains several sub-views all which set height like:
<View android:layout_width="fill_parent"
android:layout_height="18dip"
android:background="#ff000000" />
How can I retrieve the value stored in layout_height in code?
Ultimately, what I would like to do is being able to adjust the size defined in the layout so I can dynamically change the value defined by layout_height depending on the resolution of the screen resolution and the pixel density.
Is the only way to do so during the onLayout callback?
It would be much easier to redefined the XML on onCreate.
Comments, advices would be much appreciated.
Thanks
JY
Acces the View's Layout and then access the 'height' field: View.getLayoutParams().height
Should have searched a tad further prior to post a question.
This does the trick it seems...
DisplayMetrics dm = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(dm);
factor_y = (dm.ydpi * dm.heightPixels) / (160 * 480);
factor_x = (dm.xdpi * dm.widthPixels) / (160 * 320);
LinearLayout layout = (LinearLayout) findViewById(R.id.mainlayout);
for (int i = 0; i < layout.getChildCount(); i++)
{
View v = layout.getChildAt(i);
int height = v.getLayoutParams().height;
if (height > 0)
{
v.getLayoutParams().height = (int) ((float) height * factor_y);
}
int width = v.getLayoutParams().width;
if (width > 0)
{
v.getLayoutParams().width = (int) ((float) width * factor_x);
}
}
Related
I'm trying to create a number of edit texts programmatically without using XML, but I faced some problems while trying this out. Here is a piece of code:
private void createEditText(int l, int topMargin){
ViewGroup.MarginLayoutParams vlp = (ViewGroup.MarginLayoutParams) editText.getLayoutParams();
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(vlp.width, vlp.height);
layoutParams.setMargins((vlp.leftMargin + l) - vlp.width - vlp.height - 25, topMargin, vlp.rightMargin, vlp.bottomMargin);
final EditText newEditText = new EditText(this);
newEditText.setBackgroundResource(R.drawable.rounded_edittext);
newEditText.setLayoutParams(layoutParams);
linearLayout.addView(newEditText);
}
private void numberOfEditTexts(){
String[] words = Answers.answers[getCurrentLevel()].split(" ");
int l = 0, topMargin = 450;
for(int i = 0; i < words.length - 1; i++){
createEditText(l, topMargin);
l += editText.getLayoutParams().width + 5;
if(i == 0) topMargin -= 560;
}
}
The first function creates an edit text and I send 2 parameteres to it, of which the topMargin is the variable that defines the altitude coordinates of the edit text. So the problem is that this edit text will appear differently on different devices because of their screen sizes.
How can I fix it? How can I avoid setting the position manually?
Thanks in advance.
I think you need to get the screen width and length. Use the percentage of screen size as your margin size.
to get the screen size by pixels,
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Your margin can be some percentage of the height: like 5% or 10% of the screen height. Then it is adjustable.
This question already has answers here:
How can I dynamically set the position of view in Android?
(13 answers)
Closed 6 years ago.
I want myImageView to locate itself somewhere on a random position inside the screen, without pushing textviews away. I found this code in another thread, but I can't get it to work.
myImageView = (ImageView) findViewById(R.id.myImageView);
LinearLayout game = (LinearLayout)findViewById(R.id.game);
int width = game.getWidth();
int height = game.getHeight();
random = new Random();
int x = width;
int y = height;
int imageX = random.nextInt(x-50)+50;
int imageY = random.nextInt(y-100)+100;
myImageView.setX(imageX);
myImageView.setY(imageY);
You can give margin programmatically between certain range, may be you can use device width or height for range. Check this links for setting margin dynamically on run time and get screen dimension.
I Think first get programmatically device size then set image view width & height
WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth(); // deprecated
int height = display.getHeight(); // deprecated
hear you get width & height now set image view size
android.view.ViewGroup.LayoutParams layoutParams =myImageView.getLayoutParams();
layoutParams.width = 30;
layoutParams.height = 30;
myImageView.setLayoutParams(layoutParams);
and if you still have a problem to change it's size try to put it inside of a LinearLayout and manipulate the imageView size using the layout params:
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(30, 30);
myImageView.setLayoutParams(layoutParams);
This question already has answers here:
onMeasure custom view explanation
(3 answers)
Closed 7 years ago.
I have a layout with several views and one of these views have to be scaled based on screen size. As of now I have it set to 250dp as it looks good on a 5.1 inch device, but when used on smaller devices it isnt as good any more. I can't use wrap content as it will make the looks of it very bad and the size of buttons too small, so it has to be 1/3rd of the width of the screen. Is it possible to do that in the layout code, or does it have to be doen in java code?
Is it possible to do that in the layout code
Yes it is. It is pretty simple by using android:layout_weight and android:weightSum attributes of LinearLayout :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="3"
android:orientation="horizontal">
<View
android:id="#+id/thirdView"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1" />
</LinearLayout>
You need to override onMeasure(...) then do your view resizing login inside this function. Here is the perfect explanation and solution.
Some reference code from this link goes below...
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int desiredWidth = 100;
int desiredHeight = 100;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
//Measure Width
if (widthMode == MeasureSpec.EXACTLY) {
//Must be this size
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
width = Math.min(desiredWidth, widthSize);
} else {
//Be whatever you want
width = desiredWidth;
}
//Measure Height
if (heightMode == MeasureSpec.EXACTLY) {
//Must be this size
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
height = Math.min(desiredHeight, heightSize);
} else {
//Be whatever you want
height = desiredHeight;
}
//MUST CALL THIS
setMeasuredDimension(width, height);
}
You could have a look at the PercentRelativeLayout from the Percent Support Library. This is a RelativeLayout in which you can specify it's Views sizes in percentages, e.g. set its width to 33%.
<android.support.percent.PercentRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
app:layout_widthPercent="33%"
app:layout_heightPercent="33%"
app:layout_marginTopPercent="25%"
app:layout_marginLeftPercent="25%" />
</android.support.percent.PercentRelativeLayout>
Currently I am using the following to set height and width:
//landsapeWebView is a WebView, and deviceHeight and deviceHeight are ints
landsapeWebView.setLayoutParams(new RelativeLayout.LayoutParams(deviceHeight, deviceWidth));
This seems to work fine on some devices but not others. The only conclusion I've come to is that this is setting the height and width like this:
<WebView android:layout_width="(deviceWidth)dp"
android:layout_height="(deviceHeight)dp" />
when what I want is this:
<WebView android:layout_width="(deviceWidth)px"
android:layout_height="(deviceHeight)px" />
How can I specify the unit of measure?
Extra disclosure for #collusionbdbh
display = getWindowManager().getDefaultDisplay();
if(getResources().getConfiguration().orientation == 1){
deviceWidth = display.getWidth();
deviceHeight = display.getHeight();
}else{
deviceWidth = display.getHeight();
deviceHeight = display.getWidth();
}
Try this:
DisplayMetrics metrics = this.getResources().getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;
Are you sure it is not an orientation issue?
Regardless of the orientation of the device the width is the horizontal and the height is the vertical.
I would try this:
display = getWindowManager().getDefaultDisplay();
deviceWidth = display.getWidth();
deviceHeight = display.getHeight();
I am pretty sure width should be before height:
landsapeWebView.setLayoutParams(new RelativeLayout.LayoutParams(deviceHeight, deviceWidth));
should be:
landsapeWebView.setLayoutParams(new RelativeLayout.LayoutParams(deviceWidth, deviceHeight));
I am trying to change my ImageView size, but I can't seem to change both - width and height. If I just change one of them, then all works correctly, but when I try to change both, only width is changed.
I have the size in dp: width 22 and height 38, and I convert them to px. Is there another way to do so? I have tried many other ways, but they don't seem to work either.
Could someone tell me, what I should do differently?
Here is my code:
public GridLayout gridLayout;
public GridLayout.Spec row = GridLayout.spec(0);
public GridLayout.Spec col = GridLayout.spec(3);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridLayout = (GridLayout) findViewById(R.id.gameGrid);
createBlock();
}
public void createBlock() {
ImageView block = new ImageView(this);
block.setImageResource(R.drawable.red);
if (gridLayout != null) {
gridLayout.addView(block, new GridLayout.LayoutParams(row, col));
int width_in_dp = 22, height_in_dp = 38;
final float scale = getResources().getDisplayMetrics().density;
int width_in_px = (int) (width_in_dp * scale + 0.5f);
int height_in_px = (int) (height_in_dp * scale + 0.5f);
ViewGroup.LayoutParams layoutParams = block.getLayoutParams();
layoutParams.width = width_in_px;
layoutParams.height = height_in_px;
block.setLayoutParams(layoutParams);
}
}
Have you tried playing with the block's scaleType? The default is fitCenter but I usually choose centerCrop or fitXY. Here's a good webpage that describes the differences.
You can set the scaleType through ImageView's setScaleType method.