addView to TableRow programatically in for loop - android

I'am stuck for about 2 hour in order to try to create a TableRow who was multiples infalted layouts in it.My code looks like this:
LayoutInflater inflater = LayoutInflater.from(this);
TableLayout tblLayout = inflater.inflate(R.layout.tblL,parent,false);
TableRow tableRow = (TableRow) tblListItems.findViewById(R.id.tableRow );
View headerCell = inflater.inflate(R.layout.header_col,tblListItems,false);
TextView tvCellName = (TextView) headerCell.findViewById(R.id.tvCellName);
for(String item: items) {
tvCellName.setText(item);
tableRow.addView(tvCellName);
}
relativeLayout2.addView(tblLayout);
The error I get :
The specified child already has a parent. You must call removeView() on the child's parent first.
What I'am doing wrong and how should I do it right ?

A view can only have one parent. You're trying to add the same view over and over again.
for(String item: items) {
tvCellName.setText(item);
tableRow.addView(tvCellName); // this will add the same view.
}
If you want to add another view you need to create the view dynamically, inside the for, and not inflate it, like:
tvCellName = new TextView(this);//this creates a new view, that doesn't have a parent.
edit
Inflate your views inside the for:
View headerCell;
TextView tvCellName;
for(String item: items) {
headerCell = inflater.inflate(R.layout.header_col,tblListItems,false);
tvCellName = (TextView) headerCell.findViewById(R.id.tvCellName);
tvCellName.setText(item);
tableRow.addView(tvCellName);
}

Related

how to use custom layout in existing layout using dynamic linearlayout

Hello i am developing one app where i want to inflate layout in my Card view fro existing layout.And i want to show list of text view dynamically according to my string array.
Here is my existing layout
and i want to inflate following layout in last cardview of above layout
so tried with coding to do it but it display only one textview
my coding is as follows
But it is not working it display only one textview
i want to add textview dynamically according to my string size
I want to inflaate layout just like listview but i dont want to use listview.i want to implement this without listview dynamically
it display only one textview i want to add textview dynamically
according to my string size
Probably due to inflating inflate_specification every time for each TextView and initializing container inside for-loop.
Do it as :
LinearLayout container = (LinearLayout)findViewById(R.id.temp);
LayoutInflater inflater = (LayoutInflater) getApplicationContext().
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for(int i=0;i<5;i++)
{
View view = inflater.inflate(R.layout.inflate_specification, container,false);
// Create TextView
TextView product = (TextView)view.findViewById(R.id.speci);
product.setText("i= " + i);
container.addView(view);
}
Try this code:
LinearLayout container = (LinearLayout)findViewById(R.id.temp);
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
container.removeAllViews();
for(int i=0;i<5;i++) {
View view = inflater.inflate(R.layout.inflate_specification, container,false);
// Create TextView
TextView product = (TextView)findViewById(R.id.speci);
product.setText("i= " + i);
container.addView(view);
}

findViewById() returns null for an inflated layout

I have an Activity and its layout. Now I need to add a LinearLayout from another layout, menu_layout.xml.
LayoutInflater inflater;
inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.menu_layout, null);
After this, findViewById() returns null. Is there is any solution for that?
Note: I can't put both XML in one place, and using <include> also is not working.
Explanation
When you inflate a layout, the layout is not in the UI yet, meaning the user will not be able to see it until it's been added. To do this, you must get a hold of a ViewGroup (LinearLayout,RelativeLayout,etc) and add the inflated View to it. Once they're added, you can work on them as you would with any other views including the findViewById method, adding listeners, changing properties, etc
Code
//Inside onCreate for example
setContentView(R.layout.main); //Sets the content of your activity
View otherLayout = LayoutInflater.from(this).inflate(R.layout.other,null);
//You can access them here, before adding `otherLayout` to your activity
TextView example = (TextView) otherLayout.findViewById(R.id.exampleTextView);
//This container needs to be inside main.xml
LinearLayout container = (LinearLayout)findViewById(R.id.container);
//Add the inflated view to the container
container.addView(otherLayout);
//Or access them once they're added
TextView example2 = (TextView) findViewById(R.id.exampleTextView);
//For example, adding a listener to the new layout
otherLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Your thing
}
});
Assuming
main.xml contains a LinearLayout with the id container
other.xml is a layout file in your project
other.xml contains a TextView with the id exampleTextView
Try using
layoutObject.findViewById();

I've a linear layout in a fragment. How to dynamically add a view to it from the activity?

I'm posting data from one fragment and updating the other fragment by adding a view to it. I'm not using listView. I am using LinearLayout.
I've a very simple doubt. How do I get the view and update it by adding another view to it?
Basically I want to inflate the linearlayout that already has the data and add a view to it in the main activity that adds the fragment.
Edit:
LinearLayout ll = (LinearLayout)fragment.getView().findViewById(R.id.commentFragmentLayout);
ViewGroup view = (ViewGroup) ll.getParent();
View customView = view;
TextView commentContext = (TextView) customView.findViewById(R.id.commentText);
commentContext.setText("hello");
view.addView(customView);
I tried to do that in the main activity but my view gave null pointer exception.
Edit 2:
FragmentManager fm = getSupportFragmentManager();
// You can find Fragments just like you would with a View by using FragmentManager.
android.support.v4.app.Fragment fragment = fm.findFragmentById(R.id.fragmentCommentContent);
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(getApplicationContext().LAYOUT_INFLATER_SERVICE);
View child = inflater.inflate(R.layout.comments_list_item, null);
LinearLayout ll = (LinearLayout)fragment.getView().findViewById(R.id.commentFragmentLayout);
TextView newText = (TextView) child.findViewById(R.id.commentText);
newText.setText("Important text");
ll.addView(newText);
I tried that and got : The specified child already has a parent. Call removeView() on child's parent first. The problem is, if I call remove view, I lose the previous data that I've inserted in the layout.
The code you posted doesn't make any sense. You get the parent of the LinearLayout with the id R.id.commentFragment from the fragment, in that parent you search for a TextView to set some text and then you add the parent to itself.
I've a very simple doubt. How do I get the view and update it by
adding another view to it?
You get the View of a fragment with getView(). You search for the desired component on the view returned by getView() and then add the desired view to that container:
LinearLayout ll = (LinearLayout)fragment.getView().findViewById(R.id.commentFragmentLayout);
TextView newText = new TextView(context);
newText.setText("Important text");
ll.addView(newText);
Basically I want to inflate the linearlayout that already has the data
and add a view to it in the main activity that adds the fragment.
You inflate a layout file not a view that is already present. I really don't understand what you want here try to explain better.
LayoutParams params =new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
lay=(LinearLayout)rootView.findViewById(R.id.Lay);
lay.addView(yourView);

How to add same view to parent multiple times by inflating it only once

I have a LinearLayout with vertical orientation as parent, I want to add some view programmatically multiple times to this parent. Right now I am inflating the child every time getting new references to every UI element before adding to parent. This doesn't seem to be very efficient, is there any better way of doing this.
Current code I am using is below, If I inflate only once before for loop I get runtime error "he specified child already has a parent. You must call removeView() on the child's parent first."
LayoutInflater inflator = LayoutInflater.from(getBaseContext());
LinearLayout parentPanel = findViewById(R.id.parent_pannel);
ArrayList<String> myList = getData();
for(String data : myList) {
// inflate child
View item = inflator.inflate(R.layout.list_item, null);
// initialize review UI
TextView dataText = (TextView) item.findViewById(R.id.data);
// set data
dataText.setText(data);
// add child
parentPanel.addView(item);
}
Did you actually check if inflate is slow? As far as I know, inflating view is very fast (almost as fast as creating views manually).
It might be surprising for you to hear but inflate in fact does not parse the XMLs at all. XMLs for layout are parsed and pre-processed at compile time - they are stored in a binary form which makes view inflation very efficient (that's why you cannot inflate a view from an XML generated at runtime).
I'm not sure what your view is but have you creating it manually over inflating the XML:
ArrayList<String> myList = getData();
for(String data : myList) {
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
TextView textView = new TextView(this);
textView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
textView.setText(data);
layout.addChild(textView);
parentPanel.addView(layout);
}
But yeah your clearly attempting something that has been done for you with Simple ListView & API
You can't, even if you try to create a new view from the old view object the object will be passed by reference not value, and hence you will got an Exception as the childAlreadyHasParent, and so, the only way is to put the view into a for loop with the number of times you want it to be inflated, and this loop must contain the creating process from beginning not only the inflating lines.
Inflating multiple times cannot be done the same way doing it in single shot. Hope this works
LayoutInflater inflator = (LayoutInflater).getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout parentPanel = findViewById(R.id.parent_pannel);
ArrayList<String> myList = getData();
for(String data : myList) {
// inflate child
View item = inflator.inflate(R.layout.list_item, null);
// initialize review UI
TextView dataText = (TextView) item.findViewById(R.id.data);
// set data
dataText.setText(data);
// add child
parentPanel.addView(item);
}
This will work, at the least worked me

How to inflate one view with a layout

I have a layout defined in XML. It contains also:
<RelativeLayout
android:id="#+id/item"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
I would like to inflate this RelativeView with other XML layout file. I may use different layouts depending on a situation. How should I do it? I was trying different variations of
RelativeLayout item = (RelativeLayout) findViewById(R.id.item);
item.inflate(...)
But none of them worked fine.
I'm not sure I have followed your question- are you trying to attach a child view to the RelativeLayout? If so you want to do something along the lines of:
RelativeLayout item = (RelativeLayout)findViewById(R.id.item);
View child = getLayoutInflater().inflate(R.layout.child, null);
item.addView(child);
You inflate an XML resource. See the LayoutInflater doc .
If your layout is in a mylayout.xml, you would do something like:
View view;
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.mylayout, null);
RelativeLayout item = (RelativeLayout) view.findViewById(R.id.item);
Though late answer,
but would like to add that one way to get this
LayoutInflater layoutInflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.mylayout, item );
where item is the parent layout where you want to add a child layout.
It's helpful to add to this, even though it's an old post, that if the child view that is being inflated from xml is to be added to a viewgroup layout, you need to call inflate with a clue of what type of viewgroup it is going to be added to. Like:
View child = getLayoutInflater().inflate(R.layout.child, item, false);
The inflate method is quite overloaded and describes this part of the usage in the docs. I had a problem where a single view inflated from xml wasn't aligning in the parent properly until I made this type of change.
Even simpler way is to use
View child = View.inflate(context, R.layout.child, null)
item.addChild(child) //attach to your item
Try this code :
If you just want to inflate your layout :
View view = LayoutInflater.from(context).inflate(R.layout.your_xml_layout,null); // Code for inflating xml layout
RelativeLayout item = view.findViewById(R.id.item);
If you want to inflate your layout in container(parent layout) :
LinearLayout parent = findViewById(R.id.container); //parent layout.
View view = LayoutInflater.from(context).inflate(R.layout.your_xml_layout,parent,false);
RelativeLayout item = view.findViewById(R.id.item); //initialize layout & By this you can also perform any event.
parent.addView(view); //adding your inflated layout in parent layout.
layout inflation
View view = null;
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.mylayout, null);
main.addView(view);
If you're not in an activity you can use the static from() method from the LayoutInflater class to get a LayoutInflater, or request the service from the context method getSystemService() too :
LayoutInflater i;
Context x; //Assuming here that x is a valid context, not null
i = (LayoutInflater) x.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//OR
i = LayoutInflater.from(x);
(I know it's almost 4 years ago but still worth mentioning)
AttachToRoot Set to True
Just think we specified a button in an XML layout file with its layout width and layout height set to match_parent.
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/custom_button">
</Button>
On This Buttons Click Event We Can Set Following Code to Inflate Layout on This Activity.
LayoutInflater inflater = LayoutInflater.from(getContext());
inflater.inflate(R.layout.yourlayoutname, this);
Hope this solution works for you.!
If you want to add a single view multiple time then you have to use
layoutInflaterForButton = getActivity().getLayoutInflater();
for (int noOfButton = 0; noOfButton < 5; noOfButton++) {
FrameLayout btnView = (FrameLayout) layoutInflaterForButton.inflate(R.layout.poll_button, null);
btnContainer.addView(btnView);
}
If you do like
layoutInflaterForButton = getActivity().getLayoutInflater();
FrameLayout btnView = (FrameLayout) layoutInflaterForButton.inflate(R.layout.poll_button, null);
and
for (int noOfButton = 0; noOfButton < 5; noOfButton++) {
btnContainer.addView(btnView);
}
then it will throw exception of all ready added view.
If you are you trying to attach a child view to the RelativeLayout? you can do by following
RelativeLayout item = (RelativeLayout)findViewById(R.id.item);
View child = getLayoutInflater().inflate(R.layout.child, item, true);
I had the hardest time with this error, because of my unique circumstances, but finally found a solution.
My situation: I am using a separate view (XML) which holds a WebView, then opens in an AlertDialog when I click a button in my main activity view. But somehow or another the WebView belonged to the main activity view (probably because I pull the resource from here), so right before I assigned it to my AlertDialog (as a view), I had to get the parent of my WebView, put it into a ViewGroup, then remove all the views on that ViewGroup. This worked, and my error went away.
// set up Alert Dialog box
AlertDialog.Builder alert = new AlertDialog.Builder(this);
// inflate other xml where WebView is
LayoutInflater layoutInflater = (LayoutInflater)this.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
View v = layoutInflater.inflate(R.layout.your_webview_layout, null);
final WebView webView = (WebView) v.findViewById(R.id.your_webview_id);
// more code...
.... later on after I loaded my WebView ....
// first, remove the parent of WebView from it's old parent so can be assigned a new one.
ViewGroup vg = (ViewGroup) webView.getParent();
vg.removeAllViews();
// put WebView in Dialog box
alert.setView(webView);
alert.show();
With Kotlin, you can use:
val content = LayoutInflater.from(context).inflate(R.layout.[custom_layout_name], null)
[your_main_layout].apply {
//..
addView(content)
}
When add a layout to an Activity in Kotlin, see these steps:
Add just in Activity - One layout as a parent
Xml file of new
Layout Give the value of R.
val parent: LinearLayout =findViewById(R.id.stars)
val view =
LayoutInflater.from(applicationContext).inflate(R.layout.another, parent,false)
Where parent is not necessary, can be null But warning message will be appear
view.findViewById<ImageView>(R.id.ivTimer).setImageResource(R.drawable.t2)
Any view must be set value in this way, finally add
parent.apply { addView(view)}
I had used below snippet of code for this and it worked for me.
LinearLayout linearLayout = (LinearLayout)findViewById(R.id.item);
View child = getLayoutInflater().inflate(R.layout.child, null);
linearLayout.addView(child);

Categories

Resources