I was creating a banner layout for our App and it turns out that there are essentially two options I have:
Have a static image for the banner
Create a banner layout that actually lays out individual elements of the banner image. This option enables changing the banner content at runtime.
Initially, I thought that creating a dynamic banner(option 2) should always be the way to go(unless you have time crunch) but it turns out if the layout is to be changed in width and height, the margins, dimensioning and position of the views might change. As an example, if there is a TextView that is supposed to take up only single line might spill over to second line if the width is shrunk. This is the case with the dynamic layout.
With static layout, overall image would scale down therefore, although the font size would go down a bit, the text would remain in one line only.
Now, this seems to be the obvious disadvantage with dynamic layouts, is there any way I can fix it...like maybe scaling up/down a view like an image instead dynamically adjusting the positioning and whatnot for the views involved?
Or, having a static banner design is preferred?
Related
There is a dialogue, in one place of which I need to show either one element or another, depending on the situation. Example:
I would like to do this so that the elements below do not move. I want to keep the area occupied by alternating elements of a constant size.
What is the easiest way to do this?
I can, of course, manually change the visibility. Вut when switching, if there is a different height, then the underlying elements will jump. I can manually set their height equal, but this is inconvenient. It will be necessary to correct the heights of all alternating elements every time after I change one of them.
For example, Qt has Stack Layout that allows you to alternate elements and takes the size of the largest of them. Does Android have something like this?
You might be able to use the ViewSwitcher to hold the two layouts.
It holds 2 different child views and measures its height to the biggest child by default.
Here's the documentation for it: https://developer.android.com/reference/android/widget/ViewSwitcher
Just an idea if you can't find something like Stack Layout. I haven't tried it.
You can put all the elements in an horizontal LinearLayout with MATCH_PARENT width for the visible one and 0 for the invisible ones, but keeping all of them VISIBLE. It should always have the largest height and only the MATCH_PARENT width element should actually be visible.
I have a list item that contains an image (red) and another layout (blue)
Normally, the layout would be the first one, but the black layout's width depends on user configurations, so it may not fit the whole content.
I thought about making it a Linear Layout and changing the orientation depending on its width, but i read somewhere its possible to do such things with layout only (maybe constraint layouts).
Is it possible to achieve this result using only "layout responsiveness", or do i have to input some code also?
I am creating an android app and I am having some trouble with the XML file. What I want is four ImageButtons displayed in the center of four quadrants of the layout (so one in each quadrant). I also want thees ImageButtons to be sized by a percent of the screen (so the button would be bigger on a bigger screen and smaller on a smaller screen) but to a maximum of a specific size.
description of what I have in the layout that works:
The layout that contains thees buttons takes up 70% of the screen height and maximum width (there is another layout in the top 30%) and the screen is locked in vertical orientation. so I'm only looking to complete this quadrant ImageButton style of view.
my attempts to accomplish this was:
1) grid layout: this wrapped my buttons up and they did not take up the whole screen or one quadrant filled up the whole screen and the other three quadrants were not visible.
2) layout dimension percent: several linear layouts positioned in vertical and horizontal orientation and using the layout_hight=0dp (or width), layout_weight="0.50" "trick" to position the quadrants out. This worked nicely but there is a warning i get that the layouts are inefficient when you use a percentage to size a layout within a layout that was position with a percentage, and the ImageButtons did not want to stop at a maximum size completely ignored maxHight & maxWidth (i did have adjustViewBounds="true").
3) I can make all this work easily by calculating sizes and positioning everything by code but I would really like to do this in the xml file and leave that as a last resort.
I would appreciate any help, even a push in the right direction would be grate. I have been stuck on this for a while thank you.
Just do it programatically. It's much simpler as xml is very static and java is dynamic and in complex situations easier to use. Save yourself the trouble.
I've got a situation where I bring up a color picker. If it's done in portrait mode everything is fine. But if I do it in landscape mode (the dialog doesn't fit on the screen) it seems to be blowing up when trying to inflate the layout.
Is there some special way to do this in landscape mode where the view doesn't fit entirely on the screen?
Any differences I need to take into account other than screen real estate?
CraigA,
After reading your comments, it seems there is a misunderstanding about the way that different widths and heights are generated in XML. This is a common misconception at first. So, the thing to understand here is that the width of the various objects, while dynamic, impose different behaviors upon your objects.
layout_width/layout_height generally
The width and height parameters do not affect the actual width and height of the object. They affect the display width and height. This means that you can set the width and height to smaller than the contents, and the contents will still be accessible when scrolling, if they are bigger than the container.
Since many child Views take their cues from the parent Views, this can result in behavior like you are seeing above. The trick here is first to understand what is going on, and then compensate for the behavior of the system.
match_parent/fill_parent
Ordinarily, this means that the current View will get its size from the parent. If the View is a top-level View, the behavior changes slightly. If this happens to be the top level View of a Dialog, then it will be the size of the screen or the size of the contents (whichever is smaller). If the View is the top-level View of an Activity, then the results are the same, but they look different. That is, it will have the full Activity opacity and background, but the View's size is only that of the contents or size of the screen (whichever is smaller). The children's sizes are unaffected unless their width/height is based upon that of this View.
wrap_content
In this case, the display height is based upon the display heights of all of the immediate children. This behavior cascades down to the "youngest" descendants until the hierarchy uses something other than wrap_content.
Your issue (as it appears right now)
Your top level view uses wrap_content, so the display size will be based upon all of the children's display sizes. In this case, it might be better to use match_parent' orfill_parent` (depends on your API) for your top level View only. This will at least get the Dialog to be the appropriate size, if not the contents. For those controls whose size is based on the top level View, they will come into line. Those that aren't will have to be adjusted manually.
Now, the decision you have to make here is implementation. Do you need to adjust the sizes for every display, or just the landscape. If your changes have no effect upon the portrait display, then one file should be good. If not, you will want a layout file for portrait (the current one), and then an adjusted one for landscape mode.
If you are using two files, you will have a folder named layout_port for the current one to be stored. You will add a folder named layout_land for the adjusted one. They will be of the same name, just housed in the separate folders.
Hope this helps,
FuzzicalLogic
I would like to create an Android custom component for a game. The basic idea is that the custom component would be square in shape and contain other square ImageView components inside it. The ImageView components inside may be scaled and/or cropped as needed, but must remain square. The number of rows == columns, always. The difficulty level determines the exact value of rows and columns at runtime. As the game gets more difficult, the number of rows and columns will increase equally, but the scaled size of each ImageView will shrink accordingly. I would like the components to have some fixed small spacing between them, mostly so it looks nice. The display won't be scrollable, all items must fit on the display at the same time.
After a bunch of failed attempts, I'm getting frustrated and I'm not sure what is the best approach is to make this custom component.
My latest idea would be to do roughly the following:
I create my custom component class by "extends FrameLayout". In my constructor, I create an arbitrary small square ImageView object in code. I'd like others to reuse my custom component someday, so I do it in code rather than XML so that the custom component doesn't rely on any external XML drawable having to be defined. I set the scale type so that the ImageView retains it's "squareness" (I think I want fitStart?). I set the square ImageView's layout_width and layout_height to "fill_parent", so the ImageView fills in as big a space as is available in the containing FrameLayout. I add the now large and square ImageView to my layout using addView().
Next I create a RelativeLayout object and also programmatically add it to myself using addView(). Because my base class is a FrameLayout, I think this will make the size of the RelativeLayout the same as the square ImageView previously added. At least that's how I read the documentation.
Next I measure the ImageView to see how large it is. I don't think I can measure myself because my previous attempts failed at this. I kept getting 0 for my size. My research said this was because I can't measure myself during construction. This turned into a Catch-22. When I tried to scale my image to the available space, I couldn't because there was no space available yet. My hope is that because I changed to using the FrameLayout as my base class and I add the ImageView to it, I will be able to measure my newly created and correctly scaled large square ImageView.
If all goes as planned, I now know how big the space available is on the user's device for my RelativeLayout because it's the same as my ImageView. By knowing how much space is available and how many rows and columns need to be displayed, I can correctly scale each ImageView I add accordingly, assuming I remember to account for the spacing between the ImageViews I add. Now I no longer need the square ImageView and can make it go away if I want.
If reasonable, I would like the large ImageView to have rounded corners and each ImageView added also have rounded corners. With a small gap between ImageViews added, this would look cool for gameplay. This way I can leave it as a background.
This seems like a good solution, and better than my previous attempts that didn't work, but if there's a better way..., I'm listening.
Here's some psuedo-code that says mostly the same thing as above to the best of my understanding:
construct()
{
ImageView squareImageView = new ImageView(Square);
LayoutParams squareImageLayoutParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
squareImageLayoutParams.addRule(fitStart);
addView(squareImageView, squareImageLayoutParams);
RelativeLayout relativeLayout = new RelativeLayout(context);
LayoutParams relativeLayoutParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
addView(relativeLayout, relativeLayoutParams);
int size = squareImageView.getWidth(); // Should be the scaled size and square.
squareImageView.setVisibility(INVISIBLE); // maybe?
loop for each row and col
{
crop, scale and add each image to the relativeLayout object.
}
}
My most basic question is if this seems like a reasonable solution? If so, there's a bunch of things in the psuedocode I don't know how to do (yet).
How do I create a small square ImageView in code?
How do I set the scaleType in code?
Will I be able to measure my square ImageView and get the correct size?
Is there a better way to remove the square ImageView other than making it invisible?
Will making my square ImageView invisible make it unmeasurable?
I see something called a ShapeDrawable, would this be better than an ImageView for making a square?
How do I crop an ImageView to be square, distributing the loss equally to both sides?
I certainly don't expect anyone to know all these answers, but if you know any answers you can share, I would appreciate it.
Thanks.
There is a lot of built-in functionality for proper scaling to the available screen space. I do not fully understand why you want to measure the ImageViews.
Have you considered using weight? I would try a fixed size GridView (or TableLayout, or a LinearLayout of LinearLayouts). If contents are weight'ed properly, they will retain their "squareness". You could use the attributes verticalSpacing or horizontalSpacing of a GridView, or you could make empty Views for spacing in order to put weight to the spaces as well.
Do not set the weightsum attribute of the parent element, but make sure the sum of your elements' weights horizontally are equal to their sum vertically, and your square ImageViews will always scale properly, regardless of how many elements you got in there.