Trying to arrange my UI and I can't seem to remove the spacing around my slider. It's a basic Material Slider (pictured below). I've tried changing minHeight & minWidth with no luck & I'd prefer not to pad negatively. I assume there must be a way to make the slider's bounds just be around the actual slider image.
See Slider Example
The height of the slider is controlled by the dimension R.dimen.mtrl_slider_widget_height. You can change the height by specifying in dimens.xml
<dimen name="mtrl_slider_widget_height">30dp</dimen>
Or whatever height you would like. There are some other resources loaded in the BaseSlider.java that may be helpful.
private void loadResources(#NonNull Resources resources) {
widgetHeight = resources.getDimensionPixelSize(R.dimen.mtrl_slider_widget_height);
minTrackSidePadding = resources.getDimensionPixelOffset(R.dimen.mtrl_slider_track_side_padding);
trackSidePadding = minTrackSidePadding;
defaultThumbRadius = resources.getDimensionPixelSize(R.dimen.mtrl_slider_thumb_radius);
trackTop = resources.getDimensionPixelOffset(R.dimen.mtrl_slider_track_top);
labelPadding = resources.getDimensionPixelSize(R.dimen.mtrl_slider_label_padding);
}
Related
Android - How can I create layout as per image attached for different screens?
You must make different designs and use the visibility attribute to change the designs:
RelativeLayout oneLayout = findViewById (R.id.one_view);
RelativeLayout otherLayout = findViewById (R.id.other_view);
oneLayout.setVisibility (View.GONE);
otherLayout.setVisibility (View.VISIBLE);
To know what design to use:
DisplayMetrics metrics = context.getResources().GetDisplayMetrics ();
int height = metrics.heightPixels;
int width = metrics.widthPixels;
int density = metrics.densityDpi;
This way you will know the width and height of the screen.
For the design you have chosen, you should read about RelativeLayout and ConstraintLayout.
So there is one option, which is way too sophisticated and going to be fun to implement but could take forever, you draw this on a Canvas with all sort of paths and whatnot.
Another option is not very clever, but I think will do the trick!
Step 1
Split your background into squares, so that your background is a grid. Split it horizontally and vertically, like the images below.
Place those into containers, namely ViewGroups that split the screen correctly .. maybe using weights or ConstraintLayout
Step 2
You can align your items to the edges of those backgrounds you constructed.
Just an idea :)
I have a logo in the top of a login screen:
ScaleImageLabel logo = new ScaleImageLabel(theme.getImage("myLogo.svg"))
logo.setName("MyLogo");
logo.setUIID("MyLogo");
backgroundContainer.add(BorderLayout.NORTH, FlowLayout.encloseCenterMiddle(logo));
My main problem is the sizing, because on some devices is too big, on other devices is too small.
For example, suppose that I want that the logo resizes automatically at the maximum the 80% of the horizontal screen space and at the maximum the 20% of the vertical space (according to what is the largest value of them). How can I achieve this if the logo is in the North of a Border Layout?
You are using flow layout to wrap the component. Flow layout gives the component its preferred size so your scaling component no longer matters if the preferred size is too small.
I would suggest using a multi-image that looks decent in all devices based on DPI and avoiding scaling for an element like a logo. Multi-image was designed exactly for this purpose. Alternatively you can size the image in millimeters using code like:
Image img = logo.scaledHeight(Display.getInstance().convert(sizeInMM));
Shai's answer is correct in general, but in this particular case I need more precision and control on image size, that should change automatically according to the screen available size (in other words, the logo size should change on device orientation and when the virtual keyboard is used). Note that I'm using a vectorial image to avoid problems of loss of image quality on resizing (I tested that this SVG file is rendered correctly on Android 4, so I suppose that is rendered correctly on any modern device).
I share my solution:
public class MyMainClass {
[...]
private static Label logo;
public void init(Object context) {
[...]
}
public void start() {
[...]
// Insert vectorial logo in the north
// Constraints:
// logoMaxWidth is the maximum horizontal screen space in percentage
// logoMaxHeight is the maximum vertical screen space in percentage
double logoMaxWidth = 0.75;
double logoMaxHeight = 0.15;
logo = new Label((theme.getImage("Logo.svg")).scaledSmallerRatio(Double.valueOf(Display.getInstance().getDisplayWidth() * logoMaxWidth).intValue(), Double.valueOf(Display.getInstance().getDisplayHeight() * logoMaxHeight).intValue()));
backgroundContainer.add(BorderLayout.NORTH, FlowLayout.encloseCenterMiddle(logo));
[...]
// Recalculate the size of the logo when device size changes
Form logoForm = logo.getComponentForm();
if (logoForm != null) {
logoForm.addSizeChangedListener(l -> {
logo.remove();
logo = new Label((theme.getImage("Logo.svg")).scaledSmallerRatio(Double.valueOf(Display.getInstance().getDisplayWidth() * logoMaxWidth).intValue(), Double.valueOf(Display.getInstance().getDisplayHeight() * logoMaxHeight).intValue()));
backgroundContainer.add(BorderLayout.NORTH, FlowLayout.encloseCenterMiddle(logo));
logoForm.revalidate();
});
}
I'm using a TabLayout, and no matter what layout options I choose, it looks bad somewhere. Here's what I've tried, and the results:
Gravity center, mode scrollable: if there is too much space
horizontally on the screen, the tab bar doesn't fill the width
Gravity center, mode fixed: if there is not enough space, the text
wraps (which would be OK except it's the last letter of a single word.
Looks ridiculous.
Gravity fill, mode fixed: if not enough space, text wraps
Documentation says fill/scrollable is invalid, which is unfortunate because it seems like that's exactly what I need - fill all available space, and scroll if there is not enough. I tried it anyway, and it doesn't fill.
I have tried setting tabMaxWidth to 0dp with all these combinations, and it doesn't seem to have any effect. I have tried various solutions I've found around here with doing things in styles.xml or in code, with no success. Is there just no way to get this thing to behave on all screens? Do I need to calculate the screen width and adjust the layout at runtime (barf)?
UPDATE: I decided to try measuring and adujsting. Here's the code:
tabLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
tabLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
final int tabWidth = tabLayout.getWidth();
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int screenWidth = displaymetrics.widthPixels;
if(screenWidth > tabWidth){
// The tabs won't fill the horizontal space. Switch to fixed mode instead of scrollable.
tabLayout.setTabMode(TabLayout.MODE_FIXED);
}
}
});
What happens is the screen width and tab layout width are the same. So this technique cannot help me distinguish whether there's not enough or too much space. I tried it with the TabLayout width set to wrap_content instead of match_parent and that didn't work either. Still looking for a solution.
EDIT: Here are screenshots of the behavior.
If I can get the white behind the tab layout to be gray that would probably be good enough, but I think that's the activity / application background color, and I don't want to change that to gray.
Here's the background setting in the XML: app:tabBackground="#drawable/tab_selector"
That leads to:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/tab_background" android:state_selected="true"/>
<item android:drawable="#color/tab_background"/>
</selector>
tab_background is #a2a2a3
I want to set dimensions for my custom alert dialog, based on screen orientation. My intention is to swap height and width values to keep the box look like being the same size, yet handled various screen sizes of various devices, thanks to Android fragmentation it seems difficult to achieve the same effect on all devices. Android's auto-resizing seems weird to me.
Portrait:
alertDialog.width=screen.width*0.8
alertDialog.height=screen.height=0.5
Landscape:
alertDialog.width=screen.width*0.5;
alertDialog.height=screen.height*0.8
Please note that the Custom Alert Dialog must use the same code and support Android versions from JellyBean (at least 4.2) to Nougat (7).
i am using android.support.v7.AlertDialog (the latest available thing)
i assume android.app.Dialog should be avoided now (being old)
Also, i need a black border and white background for the same. i am unable to achieve same effect on all devices, (i need transparency for rounded corners)
i have used android:windowMinWidthMajor and android:windowMinWidthMinor but they affect both layouts (portrait and landscape) and seem to be ignored if content does not fit within the specified constraints.
I wish there was android:windowMaxWidthMinor & android:windowMaxWidthMajor
This is something that I've used for resizing specific views on a page:
myView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
item.height = myView.getHeight();
});
Applying it to what you want to do:
myView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
LayoutParams params = (get the layout params according to the layout);
params.width = myView.getWidth() * 0.5;
params.height = myView.getHeight() * 0.8;
myView.setLayoutParams(params);
});
You have to use the listener because the object will be added to the view tree, will be measured and prepared for display, but won't yet be displayed, so you can change its dimensions before it is visible.
Update:
I could achieve it by setting android:layout_centerInParent="true" for my Layout. and layout values for each component in the style to
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_gravity="center"
to achieve the center alignment.
XML Code available at https://github.com/computingfreak/CFTest/blob/master/app/src/main/res/layout/alert_popup.xml
Java Code available at
https://github.com/computingfreak/CFTest/blob/master/app/src/main/java/net/cf/sms/cftest/MainActivity.java
I wonder this line of code is redundant
view.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
and thus left it to Android System to decide dimensions and resizing based on content. It works for my case, but will fail in case of long text, maybe some kind of Scroll Layout will help. Cheers!
I am having problem with custom seek bar I am not getting same as i expect, I am using 2nd image as progress drawable and first as thumb, but when i use wrap content it is small and when i use fill parent it is repeating and the seek bar different from the 2nd image in the UI?
You should use Nine-path graphics. With this android will automatically resize your image based on borders you provide in graphics.
set maxHeight and minHeight of seekbar properties.
example:
maxHeight = 40dp
minHeight = 40dp