scrollview doesn't scroll setting height programmatically - android

I would start with my goal. What I want to achieve is to have layout which is 3 times bigger then real screen of phone.
Right now I try to test my solution, but I have problem with scrolling.
This is how look my layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="400dp"
tools:context=".Zo"
android:id="#+id/zo_root"
>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="9">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
android:background="#color/Red"
></FrameLayout >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
android:background="#color/Yellow"
></FrameLayout >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
android:background="#color/Blue"
></FrameLayout >
</LinearLayout>
</ScrollView>
My code behind:
#Override
protected void onCreate (Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_zo);
setParameterForScroolView();
}
private void setParameterForScroolView()
{
ParameterKeeper parameterKeeper = new ParameterKeeper(this);
LinearLayout linearLayout = (LinearLayout)findViewById(R.id.zo_root);
linearLayout.getLayoutParams().height = parameterKeeper.getHeightOfScreen() *3;
}
The code behind works well, cause my whole screen is red, but I can't scroll it at all.
There was answer which said, that I need to remove from scrollView android:fillViewport="true". After that my LinearLayout diseapers like in this question.
I added LinearLayout as root (source) but it not helped me at all.
Have you got any idea to solve it?
I try also set height 1600dp instead 400dp for Root LinearLayout in xml to be sure, that it's not problem with recalculating view. It's not working too.

You are changing the size of the wrong layout. you suppose to modify the height of the first layout inside the scroll view.

Some way scroll doesn't work if the child elements have layout_weight and I change programmatically value of height in parent's view.
In my case the only way to make it works was to set height equal to size of screen in every of frame layout in code of activity. This way I could reach my goal which was to have layout height == 3 x real screen size

Related

Android view not visible when adding layout_weight

I'm trying to split my screen into different sizes using four Linear layouts within a linear layout. When I add weights to my project, it shows on the screen that the layout is split into 4 even parts on the layout preview. But when I run the app on a device or emulator, the views are not shown. But when I remove the weight attributes, the views are shown.
I've used code samples which successfully used the weight property but don't work on my program. I've also programmatically got the width and height of all the sub-views on the code. They are not null so they are there but just not visible. I've tried adding properties like visibility = true and focusable = true but to no avail. I've added a drawView to the view using this code
DrawView drawView = new DrawView();
ViewGroup mainLayout = (ViewGroup) findViewById(R.id.main);
mainLayout.addView(drawView);
DrawView is a class that extends View and I call the methods canvas.drawLine() and canvas.drawText() to draw to the screen
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:weightSum="4">
<LinearLayout
android:visibility="visible"
android:focusable="true"
android:id="#+id/l1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#color/colorAccent"
android:orientation="horizontal"></LinearLayout>
<LinearLayout
android:visibility="visible"
android:id="#+id/l2"
android:orientation="horizontal"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/colorBtnText"></LinearLayout>
<LinearLayout
android:id="#+id/l3"
android:orientation="horizontal"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/colorBtnBackground"></LinearLayout>
<LinearLayout
android:id="#+id/l4"
android:orientation="horizontal"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/colorLbl"></LinearLayout>
</LinearLayout>
Nothing I tried above worked. I've spent quite a bit of time on this and would really appreciate some feedback.
I think the DrawView need setLayoutParams(LinearLayout.LayoutParams) before add to LinearLayout, set fixed height or weight by LayoutParams. if you don't, DrawView height is MATCH_PARENT, that will make other view's height is 0.
you can try this:
DrawView drawView = new DrawView();
LinearLayout mainLayout = (LinearLayout) findViewById(R.id.main);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,0, 1); // or new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,100); to set fixed height
mainLayout.addView(drawView, params);
If it work, i think the best way is DrawView override onMeasure method, and calculate height itself.
As you can see, you set the "android:weightSum" to 4 in your xml file. While it still have 4 childs under the main linear layout, the code shows no error. However, when you run your code, you programmatically add another view into your main linear layout which exceed the weight sum of your main layout.
So, what i would suggest is, you may try to remove the android:weightSum="4" attribute from your xml layout that way it will automatically calculate the layout size by its weight.

match_parent won't work on children of a layout with minHeight

Disclaimer: I'm not able to reproduce this on all devices. I was able to reproduce it on a Galaxy Nexus running 4.2.1 and on a Galaxy Tab A. It doesn't happen on a Nexus 6 running 7.0, though.
Here's a minimum example to explain the situation:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#ff0000"
android:minHeight="500dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000" />
</FrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="some large text here aaaaaaaaaaaaaaaaaaaaaaaaaaa"
android:textSize="100sp" />
</LinearLayout>
</ScrollView>
This is a simple layout where I want my parent FrameLayout to take up all the space left by the TextView (that's why I have android:layout_weight="1"). If the TextView leaves a space smaller than the FrameLayout's minHeight, than the content becomes scrollable and the FrameLayout sticks to its minHeight.
Everything works fine while content isn't scrollable, but if the FrameLayout reaches its minHeight and the content becomes scrollable, the child FrameLayout vanishes because its height becomes zero for some reason.
If you look at the Android Studio preview, you'll always be able to see the child FrameLayout, but when you run it (on some devices), you'll only see the parent's background.
The simplest solution is to add the same minHeight to the child FrameLayout, but in my case this isn't a good solution (my child is actually a custom view with some other child views).
Another solution is to force the child height in runtime:
private void ensureChildHeight() {
parent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override public void onGlobalLayout() {
if (parent.getHeight() > 0) {
parent.getViewTreeObserver().removeOnGlobalLayoutListener(this);
if (parent.getHeight() == parent.getMinimumHeight()) {
child.getLayoutParams().height = parent.getMinimumHeight();
child.requestLayout();
}
}
}
});
}
But that's not great either. Does anyone know what's going on and whether there's a better solution for this? After working on it for some time and from my coworker's feedback, I feel minHeight is just not reliable and I should just avoid it whenever I can.

Android - Placing one layout on top of another layout

I am trying to place one layout in top of another. I can do it but there is a problem in a case. Let me describe it first :
Here is my layout codes:
<RelativeLayout>
<LinearLayout
android:id="#+id/smallVideoRenderLayoutOutgoing"
android:layout_width="120dp"
android:layout_height="170dp"
android:orientation="vertical"/>
<LinearLayout
android:id="#+id/largeVideoRenderLayoutOutgoing"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"/>
</RelativeLayout>
There are other things but they are not necessary here . If i run code with these two view works fine. But if i setVisibility(GONE) for the "smallVideoRenderLayoutOutgoing" in my onCreate() or onResume() method on my Activity. It don't show at all. Though i can see the visibility of that "smallVideoRenderLayoutOutgoing" on my program and it show it is visible but i don't see it on my screen. I think it is overlapped by the "largeVideoRenderLayoutOutgoing" . What do you think and how can i solve this matter?
Complete View heirarchy:
Here is my code part:
private LinearLayout smallVideoRenderLayoutOutgoing, largeVideoRenderLayoutOutgoing;
private VideoCallImageRenderView smallPlayerGLView, largePlayerGLView;
private void initVideoRenderer() {
Constants.debugLog(TEST_TAG, "initVideoRenderer");
Constants.debugLog(TAG, "initVideoRenderer");
smallPlayerGLView = new VideoCallImageRenderView(this);
largePlayerGLView = new VideoCallImageRenderView(this);
VideoCallCamera.getInstance().startCamera();
VideoCallCamera.getInstance().cameraCallBack(largePlayerGLView, this);
isOwnSurfaceViewLarge = true;
largeVideoRenderLayoutOutgoing.addView(largePlayerGLView);
largeVideoRenderLayoutOutgoing.setOnClickListener(this);
smallVideoRenderLayoutOutgoing.addView(smallPlayerGLView);
smallVideoRenderLayoutOutgoing.setOnClickListener(this);
smallVideoRenderLayoutOutgoing.setVisibility(View.GONE);
}
Try instead of:
<RelativeLayout>
<LinearLayout
android:id="#+id/smallVideoRenderLayoutOutgoing"
android:layout_width="120dp"
android:layout_height="170dp"
android:orientation="vertical"/>
<LinearLayout
android:id="#+id/largeVideoRenderLayoutOutgoing"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"/>
</RelativeLayout>
To use LinearLayout with vertical orientation as root layout. And for your large layout have height of 0dp and weight 1 - it will make your large layout to occupy all available space - and it will be under small layout.
Something like the following:
<LinearLayout
android:orientation="vertical">
<LinearLayout
android:id="#+id/smallVideoRenderLayoutOutgoing"
android:layout_width="120dp"
android:layout_height="170dp"
android:orientation="vertical"/>
<LinearLayout
android:id="#+id/largeVideoRenderLayoutOutgoing"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"/>
</RelativeLayout>
Try changing the layout width and height from match parent to wrap content.
Or when you make the view invisible call bringToFront() method for the other view.
You should check this.

Scrollview doesn't scroll after resizing it's child using animation

I have a LinearLayout inside a ScrollView. At some point I collapse and expand the LinearLayout. After that the scrollview does scroll. Any ideas?
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="false">
<LinearLayout
android:id="#+id/detailsView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="visible"
>
........
</LinearLayout>
</ScrollView>
Expand and collapse is done using ValueAnimator over LayoutParams (height) of the LinearLayout.
Update: I think important is that it breaks down after animated expansion/collapse. Until that it works fine.
Update 2: For expanding again, I measured the expected height as follows:
int expectedHeight = detailsView.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
and animate expansion to that height. This measured the height to 2000+ instead of expected 800 something. Thus the sizes were equal and scrollview didn't scroll, although it didn't show the full hierarchy.
As a quick-fix I save the current height before collapsing and use it as the target height on expanding. The question is, can this be done automatically without dirty-height saving?
your scrollview is android:layout_height="wrap_content" just make it match_parent. I'm not sure but you can remove android:fillViewport too
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:id="#+id/detailsView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="visible"
>
........
</LinearLayout>
</ScrollView>

How to Prevent Scrolling within FrameLayouts and Instead Have the Parent LinearLayout Handle all Scrolling?

I have a scrollable LinearLayout parent with a few FrameLayouts nested inside it as follows:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbars="vertical"
android:orientation="vertical">
<FrameLayout
android:id="#+id/hb_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#+id/gn_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#+id/yt_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
I would like FrameLayouts to take up the space they need, allowing for scrolling of the full view through the LinearLayout.
Issue is: the LinearLayout will only take up the screen, it won't scroll, instead the FrameLayout's will scroll if the content overflows the bottom of the screen.
To be clear, I just want the FrameLayouts to fill whatever space they need, and the LinearLayout can scroll it like one long view. Must I fix the FrameLayout heights to achieve this? If so, is there risk of my layout breaking on different screen sizes/densities (or does DP really work in all cases?).
Thank you immensely!
EDIT: I have confirmed that setting fixed heights in the FrameLayout does exactly what I want this to do: scroll as one. However, why doesn't wrap_content measure the height and then go from there? That is what I expected the case was... I'm not certain how to judge the right heights for each element.
Try adding a scrollview to the layout
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:orientation="vertical">
<FrameLayout
android:id="#+id/hb_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#+id/gn_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#+id/yt_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</ScrollView>

Categories

Resources