dynamic generation of layout view inside scrollbar - android

I am facing an issue where I need to generate dynamic views one below another inside a scrollview. Views should be generated after button click.
for the first button click, it is working fine but after second click it is failing with error "java.lang.IllegalStateException: ScrollView can host only one direct child"
can anyone help me to get this fixed.
My main activity layout where scrollview is activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity" android:layout_width="match_parent" android:layout_height="match_parent"
android:id="#+id/parentRL">
<Spinner android:id="#+id/spinState" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<Spinner android:id="#+id/spinCity" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_below="#id/spinState"/>
<TextView android:id="#+id/cityCount" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_toRightOf="#id/spinCity" android:layout_below="#id/spinState" android:layout_marginLeft="5dp"
android:textIsSelectable="false"/>
<Button android:id="#+id/showAddress" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_toRightOf="#id/spinState" android:onClick="populateAddress" android:text="Search"/>
<ScrollView android:id="#+id/scView" android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_below="#id/spinCity">
</ScrollView>
</RelativeLayout>
And the view layout that need to be attached with scrollview is address_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<TextView android:id="#+id/center" android:layout_width="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content" android:text="#string/hello_world" android:layout_margin="10dp"
android:textColor="#FF0000" android:textSize="30dp"
/>
In main activity, inside button click listener:
LayoutInflater inflater = (LayoutInflater)MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View myView = inflater.inflate(R.layout.address_layout, null);
TextView _c_ = (TextView)(myView.findViewById(R.id.center));
_c_.setVisibility(View.VISIBLE);
_c_.setText(my_random_number);
View insertPoint = findViewById(R.id.scView);
((ViewGroup) insertPoint).addView(myView, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

the android scrollview supports only child so that it throws java.lang.IllegalStateException.
You should add one LinearLayout or Relative layout in scrollview and then add children into that layout.
<ScrollView android:id="#+id/scView" android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_below="#id/spinCity">
<LinearLayout android:id="#+id/layout"
android:layout_width="match_parent" android:layout_height="wrap_content">
</LinearLayout>
</ScrollView>

Related

How can I add programmatically TextView in included layout?

I have a BaseLayout, the BaseLayout is a ParentLayout for other layouts. In other words, the other Layouts inherit/include it. The BaseLayout has DrawerLayout (shared for all layouts) but each Activity has a different content.
My BaseLayout looks like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<android.support.v4.widget.DrawerLayout
android:id="#+id/myDrawer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--Main Content-->
<LinearLayout
android:id="#+id/rootLinearLayout"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<!--Content-->
<!--must add Other Layout elements there
must add Other Layout elements there
must add Other Layout elements there
must add Other Layout elements there
must add Other Layout elements there !-->
</LinearLayout>
<!-- Left Navigation Derawer -->
<LinearLayout
android:id="#+id/llLeftDrawer"
android:orientation="vertical"
android:layout_width="240dp"
android:layout_height="match_parent"
android:background="?attr/colorAccent"
android:padding="15dp"
android:layout_gravity="right">
<!-- Left Navigation Derawer Content-->
<TextView
android:text="Categories"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/textView1"
android:gravity="center"
android:textColor="#FFFFFF"
fontPath="fonts/MobileFont.ttf" />
<ListView
android:id="#+id/lvLeftMenu"
android:layout_height="match_parent"
android:layout_width="match_parent" />
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
and included in Postlayout like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<include
layout="#layout/BaseLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
How can I add PostLayout elements into the BaseLayout LinearLayout id rootLinearLayout?
postLayout element is this:
<LinearLayout
android:orientation="vertical"
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/linearLayout1">
<TextView
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/txtPostTitle"
android:gravity="right" />
<TextView
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/txtPostDate"
android:gravity="right" />
<android.webkit.WebView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/wbvPostContent" />
</LinearLayout>
First of all, provide id attribute to the included Baselayout in the Postlayout.
Then, you can get the View object from the included view by calling the following from the activity that has the Postlayout :-
View includedView = (View)findViewById(R.id.idThatYouGaveToIncludedLayout);
Then, you can access all Baselayout views from the includedView object and perform the operations that you require.
For example,
LinearLayout rootLinearLayout = (LinearLayout)includedView.findViewById(R.id.rootLinearLayout);
Similar to the above code, you can obtain objects of the other views of your Baselayout.
Bruno Bieri get solution is java and i converted to xamarin:
LayoutInflater inflater = Application.Context.GetSystemService(Context.LayoutInflaterService) as LayoutInflater;
View v = inflater.Inflate(Resource.Layout.your_layout, null);
// fill in any details dynamically here
TextView textView = v.FindViewById<TextView>(Resource.Id.a_text_view);
textView.Text="your text";
// insert into main view
ViewGroup insertPoint = FindViewById<ViewGroup>(Resource.id.insert_point);
insertPoint.addView(v, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
and Rohan Stark solution good for Access to elements of Included Layout
tanQ Bruno Bieri and Rohan Stark,
when you add view as include, can use all view like own main layout views. find the layout as a view and add view to it. like below:
LinearLayout linearLayout1 = (LinearLayout)findViewById(R.id.linearLayout1);
linearLayout1.addView(new TextView(context));

Make an ExpandableListView and Textview scroll together

I have this code xml layout that I am trying to implement in a round android wear watch. I want the TextView above the ExpandableListView to scroll with it rather than staying on the top and taking up space.
I tried using ScrollView with it rather than RelativeLayout (ScrollView in RelativeLayout and vice versa as well) but what that does is that the LinearLayout requires a set height for the ExpandableListView to show the list which is not possible as the list dynamically changes (so it can have a random number of group members) and if I use "wrap_content" it only shows one group at a time. Each group has 4 child members as well.
Can someone tell me how to make this layout suitable for me so that the TextView and the ExpandableListAdapter scroll together without having a set height for the ExpandableListAdapter?
round_activity_card_view_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
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"
tools:context="com.jawad.wifihotspotfinder.CardViewLayout"
tools:deviceIds="wear_round"
android:background="#FF3C00"
android:smoothScrollbar="true">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="20dp"
android:paddingLeft="15dp"
android:paddingRight="10dp"
android:paddingBottom="10dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cardViewHeader"
android:textSize="17sp"
android:textColor="#color/white"
android:fontFamily="sans-serif"
android:paddingLeft="20dp"
android:paddingRight="5dp"/>
<ExpandableListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/round_expandableListView"
android:background="#FF3C00"
android:choiceMode="multipleChoice"
android:groupIndicator="#null"
android:longClickable="true"/>
</LinearLayout>
</ScrollView>
Look into addHeaderView(View v). Create your TextView programmatically or inflate from XML and then add it to your ExpandableListView using that method.
The TextView should then scroll with your ExpandableListView.
Thanks for showing me what to do, Alex. I had to come up with some way to do that which took ages but finally got it right. Thanks for the instructions which really helped me a lot! The code is used is given below:
LinearLayout mLayout = (LinearLayout) getLayoutInflater().inflate(R.layout.expandable_header, expListView, false);
mLayout.setLayoutParams(new AbsListView.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
expListView.addHeaderView(mLayout);
Also the changed xml files:
expandable_header.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#FF3C00">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/expCardViewHeader"
android:textSize="17sp"
android:textColor="#color/white"
android:fontFamily="sans-serif"
android:paddingLeft="20dp"
android:paddingRight="5dp"
android:paddingBottom="2dp"
android:background="#FF3C00"
android:text="#string/no_results"/>
</LinearLayout>
round_activity_card_view_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context="com.jawad.wifihotspotfinder.CardViewLayout"
tools:deviceIds="wear_round"
android:background="#FF3C00"
android:smoothScrollbar="true">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#FF3C00"
android:paddingTop="20dp"
android:paddingLeft="15dp"
android:paddingRight="10dp"
android:paddingBottom="10dp">
<ExpandableListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/round_expandableListView"
android:background="#FF3C00"
android:choiceMode="multipleChoice"
android:groupIndicator="#null"
android:longClickable="true"
android:smoothScrollbar="true" />
</LinearLayout>
</RelativeLayout>

How to make a Relative Layout Duplicate Itself Inside a Linear Layout On Button Click

I have an alert dialogue set up inside a RelativeLayout. A small section is a ListView with a RelativeLayout inside. My xml file is as follows:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
...
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/bar_main"
android:id="#+id/dialoguelistview"
android:padding="10dp">
<RelativeLayout>
<EditText
android:id="#+id/Item"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:hint="#string/Item"
/>
<EditText
android:id="#+id/Quantity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_alignParentLeft="true"
android:hint="#string/Quantity"
android:layout_below="#id/Item"/>
<EditText
android:id="#+id/Cost"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_toRightOf="#id/Quantity"
android:hint="#string/Cost"
android:layout_below="#id/Item"/>
<Button
android:id="#+id/Button01"
android:layout_width="30dip"
android:layout_height="30dip"
android:layout_alignParentRight="true"
android:layout_marginTop="20dp"
android:layout_marginRight="10dp"
android:layout_below="#id/Item"
android:background="#drawable/round_button"
android:text="#string/another_item"
android:textColor="#fff"
android:onClick = "addAnotherItem"></Button>
</RelativeLayout>
</ListView>
...
</RelativeLayout>
</ScrollView>
When the button is clicked, I need the inner relative layout to duplicate itself inside the list view. How can I do this? Thanks in advance!
Create a separate layout xml file for RealtiveLayout that you want to inflate.
Example
The xml of the parent page is:
<RelativeLayout 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"
tools:context="em.example.InfoActivity">
<LinearLayout
android:id="#+id/infolayout"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="15dp"
android:layout_marginTop="50dp">
</LinearLayout>
</RelativeLayout>
Child Page
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#55934d"
android:padding="5dp">
<TextView
android:id="#+id/TextAddress"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="TEXT ADDRESS:"
android:textSize="10sp"
android:textColor="#fff"
/>
</RelativeLayout>
And this is your activity.java code
public void addChildLayout(){
//Inflater service
LayoutInflater layoutInfralte=(LayoutInflater)getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//parent layout xml refrence
LinearLayout linearLayout=(LinearLayout)findViewById(R.id.infolayout);
//Child layout xml refrence
View view=layoutInfralte.inflate(R.layout.infoitem, null);
//add child to parent
linearLayout.addView(view);
}
Using the above pattern you can dynamically add new views.
Another way of doing it would be to keep two copies of the relativelayout in the parent linearlayout . Keep the visibility of one of them as 'gone' and mark it visible when you want it to appear.
Benefit of this approach would be to minimize code.

Vertically centering two TextViews in a RelativeLayout

What's Happening
I am writing a PopupWindow containing two TextViews, where the second TextView should be centered vertically in the popup, and the first TextView should be directly above it.
The problem is that the RelativeLayout seems to be treating the two TextViews as a single element, and vertically centering the middle of them. I want the lower TextView to be the one centered, though, and the upper one to be resting just above it (hence the android:layout_above="#id/first_name").
XML Layout
Note the apparently unnecessary LinearLayout there because the RelativeLayout refused to completely vertically fill the screen (the PopupWindow is using ViewGroup.LayoutParams.MATCH_PARENT).
<?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="match_parent" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" >
<TextView
android:id="#+id/first_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:singleLine="true"
android:text="Christopher" />
<TextView
android:id="#+id/lbl_hello"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/first_name"
android:gravity="center"
android:singleLine="true"
android:text="#string/hello" />
</RelativeLayout>
</LinearLayout>
Java Activity
LayoutInflater inflater = LayoutInflater.from(this);
final View popupView = inflater.inflate(R.layout.<fragment name>,
<parent object>,
false);
final PopupWindow pwindow = new PopupWindow(popupView,
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
true);
pwindow.setTouchable(true);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
pwindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
}
}, 100L);
As Sushil said, you can probably remove your LinearLayout completely. The following fix should work; if it does, try removing the linear layout as well.
The issue here is the android:gravity="center" on the RelativeLayout. If you remove that, you can get the placement you desire:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
You can remove your Linearlayout simply. Right now your textview are child views of Relativelayout which is a child view to LinearLayout.
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" >
<TextView
android:id="#+id/first_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:singleLine="true"
android:text="Christopher" />
<TextView
android:id="#+id/lbl_hello"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/first_name"
android:gravity="center"
android:singleLine="true"
android:text="#string/hello" />
</RelativeLayout>
Use this xml:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:layout_marginTop="90dp">
<TextView
android:id="#+id/inv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="#string/invfam"
android:textColor="#f5f5f5"
android:textSize="20dp" />
<TextView
android:id="#+id/promo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/inv"
android:gravity="center"
android:layout_marginTop="10dp"
android:text="Enjoy an additional 15 AED off your first video consultation. Sign up for a Health at Hand account and you will be credited 30 AED as a new user plus an extra 15 AED! #feel better today"
android:textColor="#f5f5f5"
android:textSize="14dp" />
</RelativeLayout>

Adding a layout dynamically into a Scrollview

This question seems to have been asked a dozen times already bu I haven't been able to deduce the solution from them.
I have a layout called tile.xml that looks like this:
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginTop="10dp"
android:text="May Fong Robinson"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textStyle="bold" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginTop="10dp"
android:text="Beautiful star-shaped spillway, Kechut Reservoir, Jermuk, Armenia"
android:textAppearance="?android:attr/textAppearanceMedium" />
I need to add this one of my views called feed.xml which I've declared as a ScrollView because I want to have multiple objects in it so I can vertically scroll though them. Here's my feed.xml file:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView1"
android:layout_width="fill_parent"
android:background="#F1F1F1"
android:layout_height="fill_parent" >
</ScrollView>
I'd like to dynamically add my "tile" from tile.xml to my "feed" feed.xml view while changing the text of the TextViews on the fly.
How can I do this? Thanks
The new feed.xml:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#F1F1F1" >
<LinearLayout
android:id="#+id/tiles"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</LinearLayout>
</ScrollView>
...and the new tile.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:background="#FFFFFF"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginTop="10dp"
android:text="May Fong Robinson"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textStyle="bold" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginTop="10dp"
android:text="Beautiful star-shaped spillway, Kechut Reservoir, Jermuk, Armenia"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
First of all, add the 2 TextViews inside a layout.
then, in your code, where you want to dynamically add the TextViews you do the following :
ScrollView scroll = (ScrollView) findViewById(R.id.scrollView1);
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.tile, null);
scroll.addView(view);
To access the TextViews you have to do the following :
TextView textView1 = (TextView) view.findViewById(R.id.textView1);
textView1.setText("");
Also make sure to give your TextViews different IDs in the XML file. Currently they are both textView1
ScrollView can only have 1 child, meaning the current structure of your "tile" layout can't be added to the ScrollView.
What you need is to add another Layout, let's say LinearLayout to your ScrollView so that it would be the ScrollView's only direct child. To this LinearLayout you can add as many childs as you want.
This can be done by using the LayoutInflater which you've probably encountered in numerous examples.
**TRY THIS**
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#F1F1F1" >
<LinearLayout
android:id="#+id/tiles"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<include layout="#layout/tile" />
</LinearLayout>

Categories

Resources