I was trying to add a View multiple times by using a for loop, but I was getting an error
Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
My XML file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_display_list"
android:id="#+id/root_layout">
</LinearLayout>
My class file
ViewGroup ll = (ViewGroup) findViewById(R.id.root_layout);
TextView tv = (TextView) new TextView(this);
tv.setText("helloworld");
tv.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT));
//adding views in loop
for(int i=0;i<=5;i++)
{
ll.addView(tv);
}
Where am I going wrong?
You cannot add the same View multiple times to the same layout.
The following should work:
ViewGroup ll = (ViewGroup) findViewById(R.id.root_layout);
for(int i=0; i<=5; i++)
{
TextView tv = (TextView) new TextView(this);
tv.setText("helloworld");
tv.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
ll.addView(tv);
}
Also, setting either the height or the width (maybe both, depending on the orientation of your LinearLayout) of the TextView to WRAP_CONTENT might make more sense.
You should use LinearLayout, and need to create textview and params everytime, because you can't add single view multiple times -
LinearLayout ll = (LinearLayout) findViewById(R.id.root_layout);
//adding views in loop
for(int i=0;i<=5;i++)
{
TextView tv = (TextView) new TextView(this);
tv.setText("helloworld");
ll.addView(tv, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT));
}
Hope it will help :)
Try this:
for(int i=0;i<=5;i++){
ViewGroup ll = (ViewGroup) findViewById(R.id.root_layout);
TextView tv = (TextView) new TextView(this);
tv.setText("helloworld");
tv.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT));
ll.addView(tv);
}
Try it, may it help..
//adding views in loop
for(int i=0;i<=5;i++)
{
if(tv.getParent()!=null)
{
((ViewGroup)tv.getParent()).removeView(tv);
}
ll.addView(tv);
}
thanks..
Related
Dynamically adding a textView into a LinearLayout:
layout XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_layout"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
Java code:
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.main_layout);
TextView textView = new TextView(getApplicationContext());
textView.setText("Hello World");
linearLayout.addView(textView);
The textView did not show up. miss anything? Thanks.
UPDATE
Thanks for the answers. it works even without the layoutParams.
The issue is that the LinearLayout is in the middle of a UI view tree, and the following is needed:
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="mypackage.MainActivity"
tools:showIn="#layout/app_bar_main
for a Navigation Drawer activity.
add layoutParams.
try this
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
TextView textView = new TextView(getApplicationContext());
textView.setLayoutParams(params);
textView.setText("Hello World");
linearLayout.addView(textView);
you have to add a 1LinearLayout.LayoutParamsto theTextView`
look at this answer
I have to create a complicated layout (A receipt view) using a lot of
data. Because there can be x amount of charges or payments, this view must be done programmatically.
I am trying to build reusable layouts that I can attache to different textviews or edittexts and have them line up.
Broken down it looks something like this:
Which comes down to 2 basic layouts:
A full width (where the text is centered)
A Split column
a) where one column takes up 3/4's the view on either the left or right.
b) and the second column takes up 1/4 the view.
Here is my attempt. But I don't seem to be getting it right.
Here is my error:
The specified child already has a parent. You must call removeView()
on the child's parent first.
Can anyone help?
private ScrollView mScrollView;
private LinearLayout mLinearLayout;
private ProgressBar mProgressBar;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_payment, container, false);
mScrollView = (ScrollView) view.findViewById(R.id.svPayment);
mScrollView.setVisibility(View.GONE);
mProgressBar = (ProgressBar) view.findViewById(R.id.pbPayment);
mLinearLayout = (LinearLayout) view.findViewById(R.id.llPayment);
return view;
}
public void setupGUI() {
//RESUABLE LAYOUT
LinearLayout.LayoutParams paramsFull = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
paramsFull.setLayoutDirection(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams paramSmall = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
paramSmall.setLayoutDirection(LinearLayout.HORIZONTAL);
paramSmall.weight = 0.2f;
LinearLayout.LayoutParams paramLarge = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
paramLarge.setLayoutDirection(LinearLayout.HORIZONTAL);
paramLarge.weight = 0.8f;
// HOLDS THE LEFT AND RIGHT COLUMNS
LinearLayout columnShell = new LinearLayout(getContext());
columnShell.setLayoutParams(paramsFull);
//Small column
LinearLayout columnSmall = new LinearLayout(getContext());
columnSmall.setLayoutParams(paramSmall);
//Large column
LinearLayout columnLarge = new LinearLayout(getContext());
columnLarge.setLayoutParams(paramLarge);
//First get rid of all the views, incase of refresh
mLinearLayout.removeAllViews();
TextView textView = new TextView(getContext());
//CUSTOMER
textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
textView.setLayoutParams(fullwidth);
textView.setText("Mary Jane");
columnShell.addView(textView);
mLinearLayout.addView(columnShell);
LinearLayout columnRight = new LinearLayout(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
columnRight.setLayoutDirection(LinearLayout.HORIZONTAL);
//LEFT SIDE (1/4)
textView = new TextView(getContext());
textView.setLayoutParams(fullwidth);
textView.setText("PO: ");
columnSmall.addView(textView);
columnShell.addView(columnSmall);
//RIGHT SIDE (3/4)
textView = new TextView(getContext());
textView.setLayoutParams(fullwidth);
textView.setText("4465465456");
columnLarge.addView(textView);
columnShell.addView(columnLarge);
mLinearLayout.addView(columnShell);
}
}
fragment_payment.xml
<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="match_parent"
android:orientation="vertical"
tools:context="com.mycompany.myapp.Views.MasterDetails.PaymentFragment">
<ProgressBar
android:id="#+id/pbPayment"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<ScrollView
android:id="#+id/svPayment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/COLOR_LIGHT_GREY">
<LinearLayout
android:id="#+id/llPayment"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"></LinearLayout>
</ScrollView>
</LinearLayout>
Why use scrollview with linearlayout, you might have to use listview with two textview as chid, and to add new data just add it into list and notify to adpter, your new data automatically added last of the list.
I followed this piece of code written by Aby in another question: https://stackoverflow.com/a/22682248/5915747
The beginning of my text is being cut off on the left side of my screen. I'm missing quite a bit of info and not sure how to fix it, I have tried everything that worked for others but it has not worked for me.
popup.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollviewtest"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
tools:context="com.info.PopupActivity"
android:background="#f0f0f0"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
<HorizontalScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:id="#+id/rel_layout"
android:orientation="vertical">
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/table_layout"
android:background="#80000000"
android:layout_centerHorizontal="true">
</TableLayout>
</RelativeLayout>
</HorizontalScrollView>
</ScrollView>
init method:
public void init() {
View popupview = getLayoutInflater().inflate(R.layout.popup, null);
popupWindow = new PopupWindow(
popupview, LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
);
popupWindow.showAtLocation(popupview, Gravity.CENTER, 0, 0);
popup_shown[0] = true;
TableLayout tableLayout = (TableLayout) popupview.findViewById(R.id.table_layout);
TableRow row0 = new TableRow(this);
TextView text0 = new TextView(this);
text0.setText("Test Header1");
row0.addView(text0);
TextView text1 = new TextView(this);
text1.setText("Test Header2");
row0.addView(text1);
TextView text2 = new TextView(this);
text2.setText("Teset Header3");
row0.addView(text2);
TextView text3 = new TextView(this);
text3.setText("Test Header4");
row0.addView(text3);
TextView text4 = new TextView(this);
text4.setText("Test Header5");
row0.addView(text4);
tableLayout.addView(row0);
for (int i = 0; i < 8; i++) {
TableRow tableRow = new TableRow(this);
TextView tv0 = new TextView(this);
tv0.setGravity(Gravity.CENTER);
tv0.setText("long test field 0");
tableRow.addView(tv0);
TextView tv1 = new TextView(this);
tv1.setGravity(Gravity.CENTER);
tv1.setText("long test field 1");
tableRow.addView(tv1);
TextView tv2 = new TextView(this);
tv2.setGravity(Gravity.CENTER);
tv2.setText("long test field 2");
tableRow.addView(tv2);
TextView tv3 = new TextView(this);
tv3.setGravity(Gravity.CENTER);
tv3.setText("long test field 3");
tableRow.addView(tv3);
TextView tv4 = new TextView(this);
tv4.setGravity(Gravity.CENTER);
tv4.setText("long test field 3");
tableRow.addView(tv4);
tableLayout.addView(tableRow);
}
}
The longer the strings are for the text views, the more it crops off, however it's a horizontal scrollview, so it should just start at the beginning of the screen and add length to the end, which is scrollable, right?
This is what it ends up looking like with the current strings in vertical/portrait orientation:
Vertical View
This is what it looks like in horizontal, it seems to fix since my screen is large enough for the data:
Horizontal View
If you have any questions, please ask!
Solved this by adding padding to the scrollview. It seems this is a common android bug.
I don't know will it work or not but try removing
android:layout_gravity="center"
line from Relative Layout
I'm a first-day android programmer and here is my problem: in my app i have a supporting activity which uses static layout; my activity in onCreate method receives a list of data - how should i embed this data into my existing layout?
So far I've tried this code, but it doesn't shows anything, though there're no exceptions and there're few elements, hence loop works:
Activity class:
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.results);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.results, null);
// Find the ScrollView
LinearLayout sv = (LinearLayout) v.findViewById(R.id.lMain);
// getting data here
for (int i = 0; i < recipesList.getId().size(); i++) {
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
// Add text
TextView tv = new TextView(this);
tv.setText("abc");
ll.addView(tv);
sv.addView(ll);
}
results.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scroller"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:id="#+id/lMain" >
</LinearLayout>
</ScrollView>
Your apporch is wrong. You have to do like this.
try
{
super.onCreate(savedInstanceState);
setContentView(R.layout.results);
LinearLayout sv = (LinearLayout) findViewById(R.id.lMain);
// getting data here
for (int i = 0; i < recipesList.getId().size(); i++)
{
// Add text
TextView tv = new TextView(this);
tv.setText("abc");
sv .addView(tv);
}
}
I can't quite get this to work, hoping to get some hints, it seems like from my research the code should work, any thoughts would be greatly appreciated...
I have an existing layout.xml file that includes:
<RelativeLayout style="#style/bodyLayout">
<ScrollView
android:id="#+id/scrollBody"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="false"
>
<LinearLayout
android:id="#+id/scrollLinearLayout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</LinearLayout>
</ScrollView>
</RelativeLayout>
Then I have programatic code as follows:
LinearLayout ll = new LinearLayout(this);
ll = (LinearLayout)findViewById(R.id.scrollLinearLayout);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
TextView tv = new TextView(this);
tv.setId(1);
tv.setTextSize(R.dimen.text_size_medium);
tv.setText("test");
tv.setLayoutParams(lp);
ll.addView(tv);
The new TextView doesn't appear when the activity is displayed, I know I a missing something obvious... the new TextView should appear in the LinearLayout section...
I have run your code works fine
LinearLayout ll = (LinearLayout)findViewById(R.id.subLinear);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
TextView tv = new TextView(this);
tv.setId(1);
tv.setTextSize(15);
tv.setText("test adding");
tv.setLayoutParams(lp);
ll.addView(tv);
if you add new View(anything) from any button click event then add this line
ll.invalidate();
it will refresh it your component