Programmatically using MATCH_PARENT for a RelativeLayout inside a FrameLayout - android

I'm subclassing HorizontalScrollView (which is a FrameLayout) and adding a RelativeLayout to it programmatically.
The FrameLayout correctly fills the parent view, but RelativeLayout inside doesn't show up.
MainActivity::OnCreate()
setContentView(R.layout.activity_main);
CustomHorizontalScrollView custom = new CustomHorizontalScrollView(this);
ViewGroup contentView = (ViewGroup) findViewById(R.id.content);
contentView.addView(custom,new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 180));
CustomHorizontalScrollView::Constructor()
this.setBackgroundColor(Color.MAGENTA);
relativeLayout = new RelativeLayout(context);
relativeLayout.setBackgroundColor(Color.BLACK);
this.addView(relativeLayout, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
Result:
The RelativeLayout should be black and should fill parent but is not.
The weird thing is that if I specify width and height in pixels instead using MATCH_PARENT, the RelativeLayout appears.
this.addView(relativeLayout, new FrameLayout.LayoutParams(90, 90));
Does that mean that I can't use MATCH_PARENT when programmatically adding a RelativeLayout to a FrameLayout? Or am I missing something? Or maybe HorizontalScrollView only supports having a child with fixed width and height?

I do not find strict info in Android SDK API Reference, but actually the HorizontalScrollView is a "Layout container for a view hierarchy that can be scrolled by the user, allowing it to be larger than the physical display."
So, why do you need a HorizontalScrollView if its unique child must have the same width?
Likely, you can try the following:
this.addView(relativeLayout, new FrameLayout.LayoutParams(90, FrameLayout.LayoutParams.MATCH_PARENT));
... and the RelativeLayout will appear.
But maybe the following makes more sense:
this.addView(relativeLayout, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.MATCH_PARENT));
Then the RelativeLayout will be large enough to contain its children and you'll can scroll it using the HorizontalScrollView.
The HorizontalScrollView has the property fillViewport that you can set to true if you want
that the HorizontalScrollView "stretch its content to fill the viewport": I think it can be useful only when the content is less large than the HorizontalScrollView, but (I repeat), if the content is ALWAYS less large than the HorizontalScrollView, then the HorizontalScrollView is useless.

Related

Problems displaying AdMob in the bottom of a relativeLayout

I have problems with this special case, I need to tell my relativelayout that it is divided in two portions, one portion must be 80% of the height of the screen and it is a scroll grid view with images. The other percentage must be for the Admob banner.
The problem is that when this app is loaded in devices with low resolution, the Admob banner is not being displayed. I think because the height of the add is more than the height of the banner container in my layout.
What is the correct way to do this? I tried putting MATCH_PARENT in the height of my gridView and WRAP_CONTENT and ALIGN_PARENT_BOTTOM combined with BELOW, GridView but does not works, the add is not displayed on the screen, I think because of the MATCH PARENT of the gridview.
This is some of my code:
RelativeLayout mainLayout = new RelativeLayout(this);
mainLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
setContentView(mainLayout);
gridView = new GridView(this);
gridView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
gridView.setId(1);
mainLayout.addView(gridView);
adViewContainer = new LinearLayout(this);
adViewContainer.setId(2);
RelativeLayout.LayoutParams adViewContainerParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
adViewContainerParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
adViewContainerParams.addRule(RelativeLayout.BELOW, 1);
mainLayout.addView(adViewContainer, adViewContainerParams);
I tried putting 80% of the height to the gridView and 20% to the banner but then when the app is displayed in low resolution devices, the banner is not being displayed.
Your layout structure should be below:
// Root view
<LinearLayout ...>
<GridView
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<AdView ... />
</LinearLayout>
Why don't you use the default size of the admob add banner? Make your add container height to wrap content, give it alignparentbottom to true and put layout_above in gridview and give id of the add container. Make sure you first declare the ad container and then declare the gridview.

android explaination addview & layoutparams during runtime

just want to know what happens when I set new layout params to a new instance of an ImageView and then add it on an empty layout. It seems like doing it reset the parent layout hosting the new ImageView and also reset position and size of every sibling ImageView.
So what happens? Parent layout takes the layoutparams of the child?
thanks
Layout params have direct affect to views which use that params. But that also affects other views under same parent. Think about width, height and weight attrs of linear layout params. For example, if you set a layout params which has a weight attr defined, this will all change the visual of your parent.
From the doc:
LayoutParams are used by views to tell their parents how they want to
be laid out.
Note:
A parent is a view group, a container for child views. There are some types of view groups, ie LinearLayout, RelativeLayout etc(subclasses of ViewGroup can be googled), and they have specific layout behaviours and LayoutParams. While adding views to view groups layout params are used (both on xml and programmatically) for setting position, width, height inside that view group(container).

Android - Aligning a view (button) within another View in code?

I have a custom view which will be jar'ed up and added into another project. In the view I want to give an option of a button.
Here is what I have in the CustomView class.
final CustomView currentView = (CustomView) findViewById(this.getId());
RelativeLayout.LayoutParams params = (new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT ));
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
closeButton.setLayoutParams(params);
currentView.addView(closeButton);
This is all wrapped in a RelativeLayout Tag as well as the other objects of the application
Everything compiles however in the CustomView the Button is aligning left instead of right.Any Ideas???
I would guess the problem is your CustomView. It probably doesn't take the entire width of the window, and is just wide enough to fill its children (which, in your case, is the close button). Make sure your CustomView has a fill_parent horizontal layout.
Since your CustomView extends WebView, which, in turn, extends AbsoluteLayout, you can't expect it to handle RelativeLayout's parameters. Instead, it's best you put your customview and your close button inside a RelativeLayout and position them properly.
When adding your closeButton to your currentView you need to supply the LayoutParams as an argument as well in order for them to take effect.
Basically, switch
currentView.addView(closeButton);
with
currentView.addView(closeButton, params);
Since the width of your button is set to wrap_content, you could also try setting its layout_gravity to right.
params.gravity = Gravity.RIGHT;

Scroll a View and refresh content

I use the following user interface:
A parent relative layout parentLayout with the dimensions 800x600 (width x height)
A second relative layout childLayout, which is a child of the parent layout.
It has the dimensions 800x1000, i.e. it is larger than the parent layout.
parentLayout.addView(childLayout);
My goal: Scrolling childLayout by using childLayout.scrollTo(x,y).
When I use childLayout.scrollTo(x,y), Android scrolls childLayout but doesn't refresh (redraw) it. The effect is, that childLayout is cut to the same dimensions as parentLayout.
Unfortunately, the following solutions don't solve the problem:
childLayout.scrollTo(x,y);
childLayout.invalidate();
childLayout.requestLayout();
Any ideas how to solve this problem?
You can use parentLayout as ScrollView instead of RelativeLayout and keep childLayout as RelativeLayout.

Android: RemoveAllItems from view doesn't refresh size

I have a ScrollView that contains a LinearLayout.
In code I add items to the LinearLayout and it nicely expands.
When I remove, in code, all the items from the LinearLayout, the LinearLayout stays the same size, it's empty though.
How do I get the ScrollView to reclaim the height that the LinearLayout used when it had items and shrink back the LinearLayout to use the least height as it is now empty?
I have tried (in C#):
linearLayout.RemoveAllViewsInLayout();
linearLayout.PostInvalidate();
scrollView.PostInvalidate();
Java or C# answers are fine.
I only have Java experience with Android, so I would try using:
linearLayout.requestLayout();
This should cause another layout pass, and assuming your LinearLayout is set to WRAP_CONTENT it will measure all the children and size itself to fit the smallest space that the children occupy (or minHeight if you have that set and it is larger).
This trick seems to work. The result is that the linearlayout ids resized and the scrollview as well:
linearLayout.RemoveAllViewsInLayout();
linearLayout.Visibility = ViewStates.Gone;
scrollView.SmoothScrollTo(0, 0);
linearLayout.Visibility = ViewStates.Visible;
There must be a better way, but this works.

Categories

Resources