adding constraints to a spinner in my code - android

I have a code in my app which when you click the FAB, a spinner appears. when I test this on my phone which is quite small in screen size, the spinner shows up right. but when I try it on a bigger phone screen size, the spinner seems to shrink and is hidden partially.
Is it possible to add constraints to my code here so that the size of the spinner will change depending on the size of the screen and it won't be partially cut off/hidden?
code:
SearchableSpinner spinner = (SearchableSpinner) makeSpinner();
mLinearLayout.addView(spinner); //Add another spinner
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)spinner.getLayoutParams();
layoutParams.setMargins( 5, 130, 10, 0);
layoutParams.height = 80;//pixels
layoutParams.width = 240;//pixels
spinner.setLayoutParams(layoutParams);

To make your spinner have a consistent size/looks on different screen sizes you have to use DP(density independent pixels) instead of simple pixels.
What I would recommend you to do is to set your layout.height/width to specific DP by converting DP to pixels using this:
public static float convertDpToPixel(float dp, Context context){
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float px = dp * ((float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT);
return px;
}
Good luck :)

Related

Get screen size in px on Android N with changed display zoom

I have a problem with the calculation of the display size on Android N with a changed display zoom.
With Android N you can change the display zoom (check here)
but the display size (...getSize()) doesn't change if the user sets a zoom from android settings...
Any idea to solve it? Have I to use the size in px multiplied by scaledDensity to have a real display size?
My app dinamically creates windows and components calculating screen dimensions in px, the components are designed on a server.
Briefly I do a math proportion by the width set on the server and the width of the smartphone screen :
DisplayMetrics dm = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
display.getRealSize(sizePoint);
}else{
display.getSize(sizePoint);
}
int smartphoneDisplayWidth = sizePoint.x;
int smartphoneDisplayHeight = sizePoint.y;
int serverDisplayWidth = 720px; //this come from the server
int serverComponentWidth = 720px; //this come from the server
int smartphoneComponentWidth = (smartphoneDisplayWidth/serverDisplayWidth)*serverComponentWidth;
//ex: smartphoneComponentWidth = (1080/720)*720 = 1080; the component widht on the smartphone will be 1080px.
If i set a smaller zoom I have this problem:
default:
small:
the windows components are to small:
The width in px doesn't change, it changes only the density:
small
DisplayMetrics{density=2.2250001, width=1080, height=1813, scaledDensity=2.2250001, xdpi=422.03, ydpi=424.069}
default
DisplayMetrics{density=2.625, width=1080, height=1794, scaledDensity=2.625, xdpi=422.03, ydpi=424.069}
large
DisplayMetrics{density=2.875, width=1080, height=1782, scaledDensity=2.875, xdpi=422.03, ydpi=424.069}
larger
DisplayMetrics{density=3.125, width=1080, height=1770, scaledDensity=3.125, xdpi=422.03, ydpi=424.069}
largest
DisplayMetrics{density=3.375, width=1080, height=1758, scaledDensity=3.375, xdpi=422.03, ydpi=424.069}
You should create views using dp value instead of px. When density changes (like in nugat settings) you see the result in second screen.
Probably you create layout like this:
int screenWidth = <value>;
LayoutParams lp = new LayoutParams(screenWidth, 200);
view.setlayoutparams(lp);
You should use density:
float sampleDensity = 2f; // get from DisplayMetrics
int screenWidth = <value>;
LayoutParams lp = new LayoutParams((int) (screenWidth * sampleDensity), 200);
view.setlayoutparams(lp);
Other reason is maybe you not update layouts after configuration change. Better solution is use MATCH_PARENT and WRAP_CONTENT in LayoutParams. Its more convenient and fast solution.

Resize EditText to fit Text Size

I am looking to resize an EditText height, based on the height of the text size.
The reason I want to do this is because some users will set their text size to "Large" inside the Android Accessibility Options, and than some of the text will be cut off within my applications EditText views.
What can I do to dynamically adjust the height to match the Text Size? I do not need auto resizing or anything fancy.
Here is some code inside my custom EditText Class
mCurrentTextSize = getTextSize();
LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,
DisplayUtils.pixel2dp(getContext(), mCurrentTextSize));
setLayoutParams(layoutParams);
Inside a Utility Class
public static int pixel2dp(Context context, float pixel) {
DisplayMetrics metrics = new DisplayMetrics();
float logicalDensity = metrics.density;
return (int) Math.ceil(pixel / logicalDensity);
}
Why not use layout_height=wrap_content? It will automatically re-adjust the EditText so as to contain the text.

android dynamically change text size

My button layout is as follows
<Button
android:id="#+id/Button01"
android:layout_width="420px"
android:layout_height="120px"
android:background="#drawable/butt1"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:onClick="clk_fault"
android:text="Enter Fault"
android:textColor="#FFFF00"
android:layout_marginTop="100px"
android:textSize="50px" />
When the activity starts i run code that gets the display width and then adjusts the button size according to the resolution of the device
this all works fine but the text size always stays the same
is there a way of increasing the textsize depending on the size of the button containg the text?
50px is great when button width is 420px but if button width is only 200px i need to be able to reduce the text size so it looks the same whatever the size
any help appreciated
Mark
EDIT
Activity code as requested
public void onCreate(Bundle savedInstanceState) {
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
getWindow().setFormat(PixelFormat.RGBA_8888);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DITHER);
setContentView(R.layout.activity_activity1);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int h = metrics.heightPixels;
int w = metrics.widthPixels;
int w1 = (w/2);
Button txt1 = (Button) findViewById(R.id.Button01);
txt1.setLayoutParams(new LinearLayout.LayoutParams(w1, 100));
setMargins(txt1, 0, 100, 0, 0);
}
public static void setMargins (View v, int left, int top, int right, int bottom) {
if (v.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
p.setMargins(left, top, right, bottom);
v.requestLayout();
}
}
Please, don't use px. Use dp for widget sizes and sp for font sizes.
This way you will be granted a perfect scalability.
sp ~ dp (almost equals).
At mdpi resolution, 1px = 1dp.
At ldpi resolution, the scale multiplier is 0.75
At mdpi resolution, the scale multiplier is 1.0
At hdpi resolution, the scale multiplier is 1.5
At xhdpi resolution, the scale multiplier is 2.0
At xxhdpi resolution, the scale multiplier is 3.0
At xxxhdpi resolution, the scale multiplier is 4.0
mdpi is to be considered the reference resolution
While working in Java code, you are using pixels.
This means you have to:
1 - find the scaling factor to "transform them to dp".
2 - multiply your values by this factor.
To find the multiplier, I use this code:
final DisplayMetrics metrics =
Resources.getSystem().getDisplayMetrics();
final float scale = metrics.density;
Now, you can multiply your values by scale and have your pixels scaled accordingly
Firstly text sizes should be in sp and widget & component sizes in dp.
Secondly dynamics size change based on viewport size change like on different devices needs you to create different layout files for them not do dynamics expansion or contraction based on view sizes.

scene2d button scaling with libgdx

I don't know if it is just me, but drawables confuse me. Are they intended to keep the size they are given, or is there a way to scale the image within them? I understand they can use ninepatch to fill certain areas by stretching an image, but I want to scale the image that it stretches. I am using a TextButton
for my menu buttons, but they are way too big, and I would love to know how to scale them. I am retrieving the skin from an atlas, which has ninepatch images in it.
Here is the settings screen:
Here are the images in the pack I am using:
Here is the initialization of the TextureAtlas, and Skin:
buttonAtlas = new TextureAtlas(Gdx.files.internal("buttons/buttons.pack"));
buttonSkin = new Skin(buttonAtlas);
Here is the initialization of that menu button.
TextButtonStyle textButtonStyle = new TextButtonStyle();
textButtonStyle.up = Assets.buttonSkin.getDrawable("bluebutton");
textButtonStyle.down = Assets.buttonSkin.getDrawable("redbutton");
textButtonStyle.font = font;
buttonMenu = new TextButton("Menu", textButtonStyle);
buttonMenu.pad(20.0f);
buttonMenu.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
game.fade.startFadeOut();
super.clicked(event, x, y);
}
});
And perhaps I could change how I put it in the table, or how I put the table in the stage?
table.add(buttonMenu).width(Gdx.graphics.getWidth()/4);
stage.addActor(table);
As a last resort I suppose I could attempt creating my own text button actor that I could scale, thank you for your time.
First of all if you know that your images are too big: The best would be to scale the images themselves to a smaller size and then use the TexturePacker too generate a new TextureAtlas that contain the smaller images.
Anyhow you can scale the image button with the TableLayout if you really want to, see example:
table.add(buttonMenu).width(100).height(100);
The above answer didnt work for me, but i have a solution.
You can make a secondary camera and attach it to your stage.
To scale the table just scale the viewport size of the secondary camera
An example would be:
//Heres where you set the scale of your buttons and your table
Camera secondaryCamera = new Camera(Gdx.graphics.getWidth() * scale,
Gdx.graphics.getHeight() * scale);
Stage stage = new Stage();
Table table = new Table();
ImageButton button = new ImageButton(drawableUp, drawableDown, drawableChecked);
table.setFillParent(true);
stage.getViewport().setCamera(secondaryCamera);
table.add(ImageButton);
stage.addActor(table);
This works great when your using it for touch controls. You can use a table for the entire UI and scale it to your liking independent of your other game items;
table.add(buttonMenu).width(100).height(100); should work, and you just need to adjust the width and height parameters to your liking, or you can use the setBounds method. Here is an example:
TextButton myButton = new TextButton("Press Me", style);
myButton.setBounds(xCoordinate, yCoordinate, width, height);
You can set size of Drawable in ButtonStyle to resize your Button:
float scale = 0.5f;
float currentHeight = textButtonStyle.up.getMinHeight();
textButtonStyle.up.setMinHeight(currentHeight * scale);
For more information, see official document for layout:
UI widgets do not set their own size and position. Instead, the parent widget sets the size and position of each child. Widgets provide a minimum, preferred, and maximum size that the parent can use as hints. Some parent widgets, such as Table and Container, can be given constraints on how to size and position the children. To give a widget a specific size in a layout, the widget's minimum, preferred, and maximum size are left alone and size constraints are set in the parent.
And you can find the implementation of Button.getPrefHeight() in the source code:
public float getPrefHeight () {
float height = super.getPrefHeight();
if (style.up != null) height = Math.max(height, style.up.getMinHeight());
if (style.down != null) height = Math.max(height, style.down.getMinHeight());
if (style.checked != null) height = Math.max(height, style.checked.getMinHeight());
return height;
}

How to use the taken width and height in xml file in andorid?

I have identified the width and height of the screen programatically. Now I want to use that width and height in my xml file. Kindly give me a way to achive this.
Here is my Activity class.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DisplayMetrics display = this.getResources().getDisplayMetrics();
float width = display.widthPixels;
float height = display.heightPixels;
Toast.makeText(TestProjectActivity.this, "width and height is: "+width + ": "+height, Toast.LENGTH_LONG).show();
float w = convertPixelsToDp(width, this);
float h = convertPixelsToDp(height, this);
Toast.makeText(TestProjectActivity.this, "DP" +w+": "+h, Toast.LENGTH_LONG).show();
}
public static float convertPixelsToDp(float px,Context context){
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float dp = px / (metrics.densityDpi / 160f);
return dp;
}
Now I want to send the w and b to the xml for the further work.
Any help would be appricieted?
Thanks.
You cannot pass information back to XML. At most, you can get your widget using findViewById and then programmatically set the widget size.
I am developing the application which runs on any screen device. So the issue with the screen size. If I am setting the width of textview to 200dp, then its ok in my device but on other device,its not getting appear. So I just want a way where I can use this above detected width and height in my XML
You should then use a LinearLayout to give your image a size relative to the available width (like a percentage of the width of the screen
Here is how your XML would look (pseudo code)
LinearLayout (layout_width: match_parent, layout_height: wrap_content)
ImageView (layout_width: 0dip, layout_height: wrap_content, layout_weight: 50)
ImageView (layout_width: 0dip, layout_height: wrap_content, layout_weight: 50)
In the above example, each image view will take 50% of the screen width, no matter the number of pixels.
I think you need to Google a good tutorial about layouts in Android.

Categories

Resources