Adding ScrollView to existing XML Layout - android

I'm answering my own question because even though I figured it out, I wasn't able to get a clear solution. This may help someone else.
I know the exception I receive is a common one, but I couldn't solve my problem with the following pages:
The specified child already has a parent. You must call removeView() on the child's parent first
java.lang.IllegalStateException: The specified child already has a parent
Call removeView() on the child's parent first
http://www.phonesdevelopers.com/1716777/
What I want to do it add a bunch of TextViews to a ScrollView, and then put the ScrollView on the screen. The problem is that the ScrollView is only part of the screen, so I can't just use setContentView(scrollView) because that would replace the buttons and things I already have.
I have an XML file that contains the template for my layout, and I simply want to replace the ScrollView with the one I generated in my Activity.
Here is the layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/mostParent" >
<RelativeLayout
android:id="#+id/loadingPanel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" >
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
</RelativeLayout>
<Button
android:id="#+id/btnLogout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="#string/logout" />
<ImageButton
android:id="#+id/refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:src="#drawable/ic_action_refresh" />
<ToggleButton
android:id="#+id/lockToggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text=""
android:textOff="#string/toggle_off"
android:textOn="#string/toggle_on" />
<TextView
android:id="#+id/loggedInAs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/refresh"
android:layout_centerHorizontal="true"
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium" />
<ScrollView
android:id="#+id/postsView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/btnLogout"
android:layout_marginTop="30dp"
android:scrollbarSize="3dip" />
</RelativeLayout>
The ScrollView at the bottom is the one I want to add the TextViews to and it has the id postsView.
So I'm going to create a LinearLayout, add the TextViews to that layout, and then add that layout to the ScrollView. Like this:
ScrollView postsView = (ScrollView)findViewById(R.id.postsView);
LinearLayout layout = new LinearLayout(MyActivity.this);
layout.setOrientation(LinearLayout.VERTICAL);
for (final TextView post : posts) {
// add post to layout
layout.addView(post);
}
postsView.addView(layout);
But with this, I get the LogCat:
java.lang.IllegalStateException: ScrollView can host only one direct child
How can I remove the view from the ScrollView?

You can use removeAllViews() on the ScrollView. This is happening because whenever the code is being run more than once, more than one view is being added to the ScrollView.
Your code would change this:
postsView.addView(layout);
To:
postsView.removeAllViews()
postsView.addView(layout);

Related

Elements superposed using Android RelativeLayout

I have the following Android layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
android:orientation="vertical" >
<TextView
android:id="#+id/slideTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dip"
android:padding="#dimen/px20"
android:text="#string/login_message"
android:textSize="#dimen/px25"
android:textStyle="bold" />
<TextView
android:id="#+id/slideDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="#drawable/password"
android:drawablePadding="#dimen/px20"
android:drawableStart="#drawable/password"
android:padding="#dimen/px20"
android:text="#string/login_message_body"
android:textSize="#dimen/px20" />
<TextView
android:id="#+id/swipeMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="" />
</RelativeLayout>
But all the elements are positioned at the top of the screen one on top of the other, like if they didn't occupy any space.
That's not what what it seems to happen in the RelativeLayout documentation, where all elements are vertically positioned one below the other.
What's going on here?
So you need to use the id of the other components to align then properly.
For example the TextView with the id #+id/slideDescription should also have
android:layout_below="#+id/slideTitle" as one of the properties of the xml.
And the TextView with the id #+id/swipeMessage should also have
android:layout_below="#+id/slideDescription" as one of the properties of the xml.
In order to place one view below another in RelativeLayout you have to use layout_below property and set the ID of View you want to be above the specified one. But actually in order to place views vertically below each other it is more convenient to use LinearLayout with orientation set to vertical
layout_below is missed in the above xml code.I replaced the code with that please use that.
In Relative layout elemnets will be arranged relative to other elements in order to do this we should use id values of individual view elments
android:layout_below="#id/slideTitle" should be placed in description text view
android:layout_below="#id/slideDescription" should be placed in message text view
in order to get the output you desired please use the below code
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="16dp" >
<TextView
android:id="#+id/slideTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dip"
android:padding="#dimen/px20"
android:text="#string/login_message"
android:textSize="#dimen/px25"
android:textStyle="bold" />
<TextView
android:id="#+id/slideDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/slideTitle"
android:drawableLeft="#drawable/password"
android:drawablePadding="#dimen/px20"
android:drawableStart="#drawable/password"
android:padding="#dimen/px20"
android:text="#string/login_message_body"
android:textSize="#dimen/px20" />
<TextView
android:id="#+id/swipeMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="#id/slideDescription"
android:text="" />

Not able to add linerlayout in scrollview programatically in android

I need to use scrollview pragmatically, while include linearlayout in scrollview its shows error like E/AndroidRuntime(22309): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.sample.program/com.sample.program.details}: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
Check it out my coding :
My linearlayout which i want to add in scrollview
mScrollTolinear = (LinearLayout) findViewById(R.id.toscroll);
My ScrollView
ScrollView mScroll = new ScrollView(Appointmentdetails.this);
mScroll.addView(mScrollTolinear);
To remove the view
mScrollTolinear.removeAllViews();
mScrollTolinear.removeView(mScrollTolinear);
Try to to remove the view some thing like that but no luck, have tried with google also but dint get the solution, any suggestion or help highly accepted.
My XML
<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:background="#color/whitebackground"
android:orientation="vertical"
>
<!-- <ScrollView -->
<!-- android:id="#+id/favscroll" -->
<!-- android:layout_width="fill_parent" -->
<!-- android:layout_height="wrap_content" -->
<!-- android:visibility="invisible" > -->
<LinearLayout
android:id="#+id/toscroll"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/topheaderbg" >
<ImageView
"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerInParent="true"
android:contentDescription="#string/app_name"
android:paddingLeft="10dip"
android:src="#drawable/listbutton" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#color/White"
android:textSize="16sp"
android:textStyle="bold" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:contentDescription="#string/app_name"
android:paddingRight="10dip"
android:src="#drawable/notificationicon" />
</LinearLayout>
</LinearLayout>
Thanks
The problem is that you are trying to add a view which was inflated from XML file hence it already has a parent (because it is already situated in view hierarchy). Instead of the following
mScrollTolinear = (LinearLayout) findViewById(R.id.toscroll);
you will have to implement something like this:
mScrollTolinear = getLayoutInflater().inflate(R.layout.your_layout_file, null);
And also keep in mind that ScrollView can only have one child view, otherwise you can get exceptions
UPD
Update corresponding to your comment
So in case if you want to add ScrollView to LinearLayout you will have to call:
ScrollView scroll = new ScrollView(yourContext); //you may also want to specify LayoutParams for it
mScrollTolinear.addView(scroll);
I hope I've understood your comment correctly

Scrollview with Linear and Relative Layout is all boxed up, so I cannot reposition items

I am creating a ScrollView to house my relativelayout. The RelativeLayout seems to need to be inside a LinearLayout (from online). However it has gone all boxed up, with the items overlapping each other. This means I cannot reposition stuff. How can I fix this? My code is like this:
<ScrollView 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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:scrollbarAlwaysDrawVerticalTrack="true"
tools:context=".AddParty" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<Button
android:id="#+id/addparty_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="65dp"
android:onClick="switch_peoplechoice"
android:text="#string/addparty_switch" />
<Button
android:id="#+id/addparty_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/addparty_switch"
android:layout_alignLeft="#+id/addparty_switch"
android:layout_marginBottom="10dp"
android:onClick="cancel"
android:text="#string/addparty_cancel" />
<EditText
android:id="#+id/addparty_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/addparty_venue"
android:layout_marginTop="11dp"
android:ems="10"
android:hint="#string/addparty_title"
android:inputType="text" />
<EditText
android:id="#+id/addparty_venue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/addparty_title"
android:layout_marginTop="26dp"
android:ems="10"
android:hint="#string/addparty_venue"
android:inputType="text" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/addparty_venue"
android:layout_alignBottom="#+id/addparty_venue"
android:layout_marginLeft="13dp"
android:layout_toRightOf="#+id/addparty_venue"
android:text="TextView" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/addparty_venue"
android:layout_alignLeft="#+id/textView2"
android:text="TextView" />
<TimePicker
android:id="#+id/addparty_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/addparty_venue"
android:layout_below="#+id/addparty_venue"
android:layout_marginTop="16dp" />
<DatePicker
android:id="#+id/addparty_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/addparty_time"
android:layout_below="#+id/addparty_time"
android:layout_marginTop="19dp" />
</RelativeLayout>
And like all properly filled out. I actually just inserted the LinearLayout and ScrollView around my relativelayout I already had. Is there a better solution to needing a RelativeLayout to scroll, or what am I doing wrong.
It get's all bunched up in the UI viewer in Eclipse...
Thanks for the help!!
Your items are overlapping one another in the RelativeLayout as you most likely did not specifiy the positions of each item individualy, though it is difficult to determine without seeing the entire layout xml.
Please read http://developer.android.com/guide/topics/ui/layout/relative.html for more information on how RelativeLayouts work.
As far as the XML is concerned, it seems that their is a conception mistake on how your Views are related to each others.
Let's start with the RelativeLayout that has a wrap_content height. No problem on that but it must be noted.
The first element inside this RelativeLayout is positioned at the bottom of the RelativeLayout. Still no problem on this point.
Thing is, the second View is positioned ABOVE the first one, this means that the height of the RelativeLayout is getting bigger when the second View is inserted, but the first View should be at the bottom of the layout so it is repositioned again thus overlap with the second View.
Can you try to position the first View with layout_alignParentTop="true" ?
Maybe this will fixe your problem.

RelativeLayout weight

In a layout resource XML, I have 3 RelativeLayout(s) which are inside a main RelativeLayout. The view will be shown vertically. These 3 RelativeLayout() are set next to each other, and I want them to fill the whole screen, doesnt matter what will be the screen size. My, layout view:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/backg"
>
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="#dimen/top_mr_image"
android:src="#drawable/temp" />
<RelativeLayout
android:id="#+id/r1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_below="#+id/imageView1"
android:layout_marginLeft="10dp"
android:background="#drawable/r1bg"
android:layout_weight="1"
>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="#dimen/txt_mr_right"
android:layout_marginRight="#dimen/txt_mr_right"
android:layout_marginTop="39dp"
android:text="S"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#id/textView1"
android:layout_marginLeft="#dimen/txt_mr_right"
android:layout_marginRight="#dimen/txt_mr_right"
android:text="T"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/r2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignTop="#+id/r1"
android:layout_toRightOf="#+id/r1"
android:layout_weight="1" >
</RelativeLayout>
<RelativeLayout
android:id="#+id/r3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignTop="#+id/r2"
android:layout_toRightOf="#+id/r2"
android:layout_weight="1" >
</RelativeLayout>
I set weight=1 and layout_width=0dp for each relativeLayout and this technique works with buttons, I thought the same will be with relativeLayout, seems my thoughts were wrong. Any idea?
UPD1: I have added an image of what I would like to have
RelativeLayout does not pay attention to android:layout_weight. (That's a property of LinearLayout.LayoutParams, but not of RelativeLayout.LayoutParams.)
You should be able to get the layout you want with a much simpler view hierarchy. It's not clear what you are trying to do, since the last two RelativeLayouts are empty. If you need a purely vertical organization, I'd suggest using LinearLayout instead of RelativeLayout.
EDIT Based on your edit, it looks like you want a horizontal layout of three compound views, each one clickable. I think something like the following will work:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!-- First column -->
<LinearLayout
android:id="#+id/firstColumn"
android:orientation="vertical"
android:gravity="center_horizontal"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="..." />
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="text 1"
. . . />
</LinearLayout>
<!-- Second column -->
<LinearLayout . . . >
. . .
</LinearLayout>
</LinearLayout>
If the contents of the buttons aren't correct, you can replace the second-level LinearLayout views with RelativeLayout if that helps organize the layout better.
RelativeLayouts do not support weight. You need to use a LinearLayout as a parent container if you want to use weights.
Solution is very simple. I have been looking for weight distribution in relative layout.
It's a small trick for all these kind situations.
Use LinearLayout with android:orientation="horizontal"
You can use Horizontally oriented LinearLayout Manager in the Recycler View, and place each RelativeLayout in each item, of its Adapter.
The Link: How to build a Horizontal ListView with RecyclerView?
If your RelativeLayouts are set to a fixed width and height, that is to the size of the Screen, that you can get from DisplayMatrics, that will be OK.
The Link: Get Screen width and height
If the contents of your RelativeLayouts are different, then you can use getItemViewType() method.
Please see: How to create RecyclerView with multiple view type?
Happy Coding :-)

Insert a linearLayout inside another linearLayout

I'm trying to insert a LinearLayout inside another LinearLayout. I don't know if what I am doing is right or not. I need to try it this way, without using inflation.
LinearLayout address2;
address2 = new LinearLayout(this);
address2 = (LinearLayout)findViewById(R.id.sfsp2_layout);
LinearLayout teste3 = (LinearLayout)findViewById(R.id.se_contentAdressPostal);
LinearLayout teste4 = (LinearLayout)teste3.findViewWithTag("teste");
teste4.addView(address2);
LinearLayout teste3
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/se_contentAdressPostal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:background="#drawable/background_tile_address_postal"
android:orientation="vertical" >
<include
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="#layout/socio_form_structured_postal" />
LinearLayout teste4
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sfsp_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/background_tile"
android:orientation="vertical"
android:tag="teste" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sfsp_layout_horizontal"
android:layout_width="wrap_content"
android:layout_height="49dp"
android:layout_gravity="right"
android:background="#drawable/background_tile"
android:orientation="horizontal"
android:tag="teste" >
<Button
android:id="#+id/sfsp_btStructuredPostal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginBottom="2dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="2dp"
android:hint="#string/sfsp_btStructuredPostal" /> .......
LinearLayour address2 ( The layout that i need to insert in layout4)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sfsp2_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/background_tile"
android:orientation="vertical" >
<EditText
android:id="#+id/sfsp2_etStructuredPostalApartado"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:layout_marginLeft="65dp"
android:layout_marginRight="55dp"
android:layout_marginTop="2dp"
android:layout_weight="0.14"
android:ems="10"
android:hint="#string/sfsp2_etStructuredPostalApartado"
android:inputType="textMultiLine"
android:scrollHorizontally="false" >
The LinearLayout "teste4" is inside "teste3". I need to insert LinearLayout "address2" inside "teste4". Can you tell me what I'm doing wrong?.
I think there is some misunderstanding here about how the findViewById works. I'll try to explain it below. Hope this helps, let me know if it doesn't.
There are two possible findViewById() that can be used.
Activity.findViewById(): this can be used to find a view in the current activity's main content view -- that is, the view that was set using setContentView(). It cannot be used for any other purpose. For example, it cannot find a view from any other layout file -- the function simply would have no way of knowing how to find it. As far as I can tell, this is the function you're trying to use. If the last XML file you have is not the main layout, then the line address2 = (LinearLayout)findViewById(R.id.sfsp2_layout) will fail.
View.findViewById(): this function can be used to find a view that is contained in some other view. E.g. if you have view1 that contains view2, and view2 has ID some_id, then you can find view2 by calling view1.findViewById(R.id.some_id). In order for this to work, view1 has to be fully initialized. E.g. if view1's description is in XML, it has to be fully inflated first.
In essence, if you want to work with a view that is described in a separate XML file, you have to inflate it first. I don't think there is a way around it.

Categories

Resources