Linearlayout inside scrollview with even distriburtion - android

I have a data entry type activity and im using a linear layout to space out evenly the sets of textviews and edittexts. Then I have a scroll view that is supposed to make it so the user can scroll while the softkeyboard is up.
If I use android:fillViewport the linearlayout works properly and fills the screen and spreads each item out evenly but then when the keyboard comes up and stops each item being spread out evenly. If i use android:windowSoftInputMode="stateVisible|adjustPan" then the linearlayout remains spread out but the scroll view doesn't work anymore (from all the unsolved posts on this i don't think you can have a working scroll view with adjustPan)
is there any way to have a linearlayout inside a scrollview, with items spread out evenly and still work while the softkeyboard is up with out changing the linearlayout?
<?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
>
<LinearLayout
android:gravity="left"
android:orientation="vertical"
android:id="#id/tab2"
android:paddingLeft="40.0dip"
android:paddingTop="0.0dip"
android:paddingRight="40.0dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.0">
<TextView
android:id="#id/textViewBrand"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/brand" />
<AutoCompleteTextView
android:id="#id/editTextBrand"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
</AutoCompleteTextView>
</LinearLayout>
...more linearlayouts with textview and edittext to be spaced out evenly

set the property android:fillViewport="true" in your scrollview it will work

Maybe the ScrollView isn't working because your
android:layout_height attribute
is defined to match_parent. You have to put
wrap_content

Follow This Code, I hope it resolves your Problem
<?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">
//Your Main Layout
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:weightSum="100">
// First Sub Layout Under Main Layout
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:layout_weight="10"
android:weightSum="100" >
<TextView
android:id="#+id/textView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="TextView"
android:layout_weight="70" />
<EditText
android:id="#+id/editText1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="30" />
</LinearLayout>// Finishing First Sub layout
// Second Sub Layout Under Main Layout
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:layout_weight="10"
android:weightSum="100" >
<TextView
android:id="#+id/textView2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="TextView"
android:layout_weight="70" />
<EditText
android:id="#+id/editText2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="30" />
</LinearLayout>// Finishing Second Sub layout
similarly for 3rd,4rth,5th sub layouts and so on........
</LinearLayout> // Finishing Main Layout
</ScrollView> // Finishing ScrollView

you can go over the child views of the LinearLayout and set their size to a fixed size yourself in code using a ViewTreeObserver.OnGlobalLayoutListener.
the following code sets the sizes to not change, so you can use the android:fillViewport option with weights, and then essentially remove the weights, but keep the calculated sizes.
I used this code with some modifications to also make sure child views are distributed evenly in a LinearLayout that is inside a ScrollView, where the LinearLayout is too big for the android:fillViewport option to get the weights to actually work. this was done by doing 2 iterations over the children. first getting the max view's height, and then setting all child views to that max height.
private void distributeViewsEvenlyInLinearLayout() {
ViewTreeObserver observer = linearParentView.getViewTreeObserver();
final ViewTreeObserver.OnGlobalLayoutListener globalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
#SuppressWarnings("deprecation")
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
linearParentView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
linearParentView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
for (int i = 0; i < linearParentView.getChildCount(); i++) {
View child = linearParentView.getChildAt(i);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, child.getHeight());
child.setLayoutParams(layoutParams);
}
}
};
observer.addOnGlobalLayoutListener(globalLayoutListener);
}

Related

LinearLayout weights not filling parent

After looking around for some time, I've yet to find a question that matches my problem. My issue is this, I have a ListView whose entries adhere to the following layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:orientation="horizontal"
android:descendantFocusability="blocksDescendants" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
amdroid:layout_weight="1"
android:orientation="vertical" >
...
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:orientation="vertical" >
...
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
...
</LinearLayout>
</LinearLayout>
I would expect this to produce an entry in which the 1st nested layout gets 1/4 of the available width, the 2nd gets 1/2 of the width, and the 3rd gets 1/4 of the width. This isn't what happens, though; instead, the width of each nested layout is wrapped for some reason.
Interestingly, if I specify a particular width in the parent LinearLayout instead of "match_parent", the nested layout widths obey the weights as expected. For example, the following produces the expected result:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="290dp"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:orientation="horizontal"
android:descendantFocusability="blocksDescendants" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
amdroid:layout_weight="1"
android:orientation="vertical" >
...
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:orientation="vertical" >
...
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
...
</LinearLayout>
</LinearLayout>
Obviously, though, specifying a particular width ignores the whole point of weights. So my question is this: why aren't the weights actually filling the parent LinearLayout when "match_parent" is used, and how can this be corrected?
Oh and one final point of interest, the graphical layout preview in Eclipse produces expected results when "match_parent" is used for the parent LinearLayout width. It's only when emulated or used on an actual device that the contents of the nested LinearLayouts get width-wrapped. I'm guessing that this is due to the layout's use inside of a ListView, but who knows?
Thanks
Alright, I feel dumb now; my suspicion was correct: the problem was with the ListView.
I had specified "wrap_content" for the ListView width in the layout that instantiates the ListView. Correcting the ListView width by specifying "match_parent" produces the expected results for the entry layout without relying on a hard-coded layout_width.

Custom Button Class not resizing based on layout_weight android

I have a CircularMeter class which is derived from Button. The problem is that it is not resizing even if the weight given is 0.5 (ie. half the vertical screen).
<LinearLayout
android:id="#+id/WidgetDataLayout"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_alignParentTop="true"
android:layout_weight="0.5"
android:orientation="vertical"
android:layout_gravity="center_horizontal">
<com.test.CircularMeter
android:id="#+id/cm1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal" />
</LinearLayout>
Any Ideas ?
You can take help from this example to make your circularmeter fill half of the vertical screen
eg.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:weightSum="1">
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_weight="0.5"
android:background="#123456"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#123456"
android:text="#string/hello_world" />
</LinearLayout>
</LinearLayout>
There's no layout_weight in CircularMeter.
It's parent LinearLayout has both android:layout_alignParentTop="true" and android:layout_weight="0.5" which is not correct since layout_alignParentTop is a layout attribute for a RelativeLayout parent while android:layout_weightis an attribute for a LinearLayout parent. The layout XML does not show what is the parent layout actually is. android:layout_height="0dp" would make the layout invisible unless there really is a vertical LinearLayout as a parent.
Also note that layout_weight="0.5" won't make the view size half the screen. After doing first pass layout for a linear layout, the weight mechanism just distributes any remaining space in proportion of element weights. By default an element's weight is 0. So if you have just one element with non-zero weight, it will get all remaining space in its linear layout parent.

Horizontal scroll view hiding some children

Android 4.1.0.
I have one horizontal scroll view, inside it - LinearLayout.
In LinearLayout I add some children programmatically in fragment onResume.
In the case when children fit in the view, everything is fine.
In the case when children do not fit in the view, HorizontalView hides first n elements from the left and keep free space for n elements on the right.
I tried to call computeScroll or requestLayout/forceLayout, but it didn't help.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<HorizontalScrollView
android:id="#+id/productListScroll"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/productListLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:orientation="horizontal"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingTop="10dp" />
</HorizontalScrollView>
...
</LinearLayout>
and the code in fragment:
public void onResume() {
super.onResume();
productsPanel.removeAllViews();
for (Product product : currentOrder.getProductList()) {
productsPanel.addView(new ...); //view with calculated height and width
productsPanel.addView(new ...); //view with fixed width and height = MATCH_PARENT
}
}
<HorizontalScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
<LinearLayout android:id="#+id/top_buttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- Lots of items -->
</LinearLayout>
</HorizontalScrollView>
It was issue. Horizontal scroll view hides its children if you set android:layout_gravity="center_horizontal" for inner container.
link is here
The problem was solved by setting linear layout layout_gravity=left, gravity=center.
I also moved view creation code to onActivityCreated, but I don't think it helped to solve this problem.

Dynamically adding views to RelativeLayout inside ScrollView

I am trying to add dynamically created several RelativeLayouts into a LinearLayout which is inside a RelativeLayout, which is inside a ScrollView. When the total height of the all views exceed the size of the phone screen, all views are displayed correctly. But when the total size of dynamically added views is not enough for filling the screen, only the first RelativeLayout element is shown and the others are not displayed in the screen. I am really hopeless and do not understand why.
Here is the code to dynamically populate views inside linear layout:
LinearLayout commentsLayout = (LinearLayout) findViewById(R.id.comments_layout);
LayoutInflater inflater = (LayoutInflater)
this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for(Comment c: commentsList) {
RelativeLayout layoutItem = (RelativeLayout) inflater.inflate(
R.layout.list_item_comment, null, false);
TextView tv = (TextView) layoutItem.findViewById(R.id.textView);
ImageView iv = (ImageView) layoutItem.findViewById(R.id.imageView);
// set tv's text
// set iv's image and onclicklistener, nothing fancy here, everything goes well
commentsLayout.addView(layoutItem);
}
Here is list_item_comment.xml:
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/white"
>
<ImageView
android:id="#+id/imageView"
android:layout_width="50dip"
android:layout_height="50dip"
android:layout_alignParentLeft="true"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
/>
<TextView
android:id="#+id/textView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="10dp"
android:textSize="16sp"
android:layout_toRightOf="#id/imageView"
/>
</RelativeLayout>
And here is the xml file for this activity:
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/main_layout"
>
...
<ScrollView
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
android:id="#+id/scrollView"
>
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/relativeContainer"
>
...
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/comments_layout"
/>
</RelativeLayout>
</ScrollView>
</RelativeLayout>
And the screenshots:
Without sufficient layouts: (INCORRECT, needs to show 3 comments)
With enough layouts: (CORRECT ONE, screen is filled)
I just need to show all three comments in the first case :/ Thanks in advance.
instead of fill_parent, try changing the layout_height of the <RelativeLayout> of your list_item_comment.xml to wrap_content.
Also, why do you need another <RelativeLayout> inside your <ScrollView> of the xml of your activity. The LinearLayout is sufficient to do what you want your activity to look like. Maybe you can just remove it.

How to scale an Android layout object during runtime?

I want to set the width of a LinearLayout to half of the screen width dynamically in my UI initialization. I have a RelativeLayout wrapped around the LinearLayout, the hierarchy is the following:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:id="#+id/left_linear_layout"
android:layout_alignParentLeft="true"
android:layout_height="fill_parent"
android:layout_width="155dp" <!--want to set this to 1/2 screen width-->
android:orientation="vertical">
...
</LinearLayout>
<LinearLayout
android:id="#+id/right_linear_layout"
android:layout_alignParentRight="true"
android:layout_height="fill_parent"
android:layout_width="385dp"><!--want to set this relative to screen width as well-->
....
</LinearLayout>
</RelativeLayout>
Alternatively, can this problem be solved using View instead of Layout? Any suggestion is appreciated!
You can do this by using layout_weight, but you'll need to add some invisible views for padding. For instance the following would make your top panel half the screen width:
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:id="#+id/left_linear_layout"
android:layout_alignParentLeft="true"
android:layout_height="fill_parent"
android:layout_width="0dp"
android:layout_weight="1"
android:orientation="vertical"
>
...
</LinearLayout>
<!-- need this view to fill the other half of the screen -->
<View
android:id="#+id/spacer"
android:layout_toRightOf="#id/left_linear_layout"
android:layout_height="fill_parent"
android:layout_width="0dp"
android:layout_weight="1"
/>
....
</RelativeLayout>
The amount each view will take up is layout_weight/total_layout_weight. In this case total_layout_weight = 1+1 = 2 and each view has a layout_weight of 1, so each view takes up 1/2 of the screen.
You could simply use a LinearLayout as your top-level layout, and then set the weight of the two child layouts.

Categories

Resources