My intent is to inflate numerous instances of the same view on a LinearLayout, and then modify their views accordingly. However, whenever I inflate a view multiple times, I always end up with the same reference to the first inflated view.
Simplified example:
View v = getActivity().getLayoutInflater().inflate(R.layout.inflatable_layout,rootLinearLayout,true);
TextView t = (TextView) v.findViewById(R.id.text1);
t.setText("Foo");
View v2 = getActivity().getLayoutInflater().inflate(R.layout.inflatable_layout,rootLinearLayout,true);
TextView t2 = (TextView) v2.findViewById(R.id.text1);
t2.setText("Bar");
By doing this, I end up with two inflated views. However, the first view's TextView contains "Bar", and the second one unaltered.
Is there a way to be able to maintain reference to the views I inflate individually?
To solve your problem, just change:
View v = inflater.inflate(R.layout.inflatable_layout,rootLinearLayout,true);
to
View v = inflater.inflate(R.layout.inflatable_layout,rootLinearLayout,false);
rootLinearLayout.addView(v1);
Note that you now have to add the view manualy to your layout.
(Do the same for v2)
This way you should receive two different references.
Please try this:
View v = getActivity().getLayoutInflater().inflate(R.layout.inflatable_layout,null); // Note the null replacing the "ViewGroup"
TextView t = (TextView) v.findViewById(R.id.text1);
t.setText("Foo");
View v2 = getActivity().getLayoutInflater().inflate(R.layout.inflatable_layout,null); // Note the null replacing the "ViewGroup"
TextView t2 = (TextView) v2.findViewById(R.id.text1);
t2.setText("Bar");
// Manually append each layout to your linear layout.
I think this should work, as no root is defined
Related
I have inflated one layout in my Activity now in that Activity I have some common fields for multiple times, so I have created one more layout with those common fields and included in my layout.And I got inflated all those fields.But now My problem is that While I am inserting data in those fields only first included fields gets inserted with data not the second, third, and so on... So how to get data inserted in such fields with common ids..
LayoutInflater inflater = LayoutInflater.from(getContext());
View w4FragmentRowView = inflater.inflate(R.layout.weekly_report4_row_item, null);
etWhere = (EditText)w4FragmentRowView.findViewById(R.id.et_weekly_reports_where_w4_tab);
etHowSubStd = (EditText)w4FragmentRowView.findViewById(R.id.et_weekly_reports_how_sub_std_w4_tab);
Now I have to insert data multiple times in same activity with these edit Text fields.
Say you have two views and they have common ids and you inflate them
Like shown below
now for common ids when you are doing find view by id make sure
the point to right parent
//look at item and item2 as while finding view
LinearLayout item = (LinearLayout) mLayoutInflater.inflate(
R.layout.layout1, null);
TextView skunitNameTextView = (TextView) item.findViewById(R.id.textView);
LinearLayout item2 = (LinearLayout) mLayoutInflater.inflate(
R.layout.layout1, null);
TextView skunitNameTextView2 = (TextView) item2.findViewById(R.id.textView);
i think this should solve your problem
Take example you have a layout file with name "reuse.xml" where you have only one view TextView with id "txv".
Now in your Activity you are inserting this layout file multiple times like:-
TextView tv1 = (TextView) mLayoutInflater.inflate(
R.layout.reuse, null);
tv1.setId(R.id.txv_activity_1);
TextView tv2 = (TextView) mLayoutInflater.inflate(
R.layout.reuse, null);
tv2.setId(R.id.txv_activity_2);
TextView tv3 = (TextView) mLayoutInflater.inflate(
R.layout.reuse, null);
tv3.setId(R.id.txv_activity_3);
Now you are using the same layout file but they gave different id so you can easily update any of file which one you want.
But if you are using the same layout more than 3-4 times it is recommended to use it as ListView or RecyclerView item, which also provide you better performance in case of large layout and easy to maintain.
I have a custom layout xml which i use as a template for creating items in a list dynamically. However I can't seem to change the text and color of elements within this custom layout properly before I add it to the main layout. I need to do this as each item in the list can be different.
If I have added more than one of these custom layouts to the main layout any changes I make to the TextView object always happen on the first item in the list.
My custom layout has a textview and a check box within a relative layout in a file called 'cat_panel.xml'.
My coding to produce the layout is:
LinearLayout rootEl = (LinearLayout) findViewById(R.id.pageWrapper);
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
View vw;
vw=inflater.inflate(R.layout.cat_panel, rootEl, false);
catTitleTv = (TextView) findViewById(R.id.catPanelTitle);
catTitleTv.setText("testing 1");
rootEl.addView(vw);
//the above is then repeated
vw=inflater.inflate(R.layout.cat_panel, rootEl, false);
catTitleTv = (TextView) findViewById(R.id.catPanelTitle);
catTitleTv.setText("testing 2");
rootEl.addView(vw);
Thanks in advance
Change
catTitleTv = (TextView) findViewById(R.id.catPanelTitle);
to
catTitleTv = (TextView) vw.findViewById(R.id.catPanelTitle);
I have a LinearLayout with many nested LinearLayouts and TextViewss
My main activity inflates the main LinearLayout,
Then I load data from a server and based on the data received, I add multiple Layouts in a place holder (LinearLayout)
This is simple a news page where I load Images associated with the news and place it inside an initially empty LinearLayout.
Each Image has the following info: Title(TextView), Date(TextView), Image(ImageView) so what I actually do is the following:
*Please notice that this is only the essential coded in the question I elemenated all the try -> catch ... if/else ....etc
public void addImages(JSONArray images){
ViewGroup vg = (ViewGroup) findViewById(R.id.imagesPlaceHolder);
// loop on images
for(int i =0;i<images.length;i++){
View v = getLayoutInflater().inflate(R.layout.image_preview,vg);
// then
I think that here is the problem
ImageView imv = (ImageView) v.findViewById(R.id.imagePreview);
TextView dt = (TextView) v.findViewById(R.id.dateHolder);
TextView ttl = (TextView) v.findViewById(R.id.title);
// then
dt.setText("blablabla");
ttl.setText("another blablabla");
// I think the problem is here too, since it's referring to a single image
imv.setTag( images.getJSONObject(i).getString("image_path").toString() );
// then Image Loader From Server or Cache to the Image View
}
}
The code above works good for a single image
But for multiple images the Image Loader doesn't work I guess it's because all ImageViews (Inflated multiple times) have the same ID
When you provide a ViewGroup to be used as the parent, the View returned by inflate() is this parent (vg in your case) and not the newly created View. Therefore, v points toward the ViewGroup vg and not toward the newly created View and as all of your children have the same id, the same subviews (imv, dt, ttl) are returned each time.
Two solutions. The first one is to change their id right after you are finished with them, before the next iteration. Therefore, on the next creation at the beginning of the next iteration, the newly created Views will have a different IDs from the older Views because they will still use the old constant defined in R.
The other solution would be to add the parameter false to the call to inflate() so that the newly created view will not be attached to the ViewGroup and will then be returned by the inflate() function instead of the ViewGroup. The rest of your code will then works as attended with the exception that you will have to attach them to the ViewGroup at the end of the iteration.
Notice that you still need to provide a ViewGroup because it will be used to determine the value of the LayoutParams.
I had the same problem, and based on the answer from #SylvainL, here'a a working solution:
// myContext is, e.g. the Activity.
// my_item_layout has a TextView with id='text'
// content is the parent view (e.g. your LinearLayoutView)
// false means don't add direct to the root
View inflated = LayoutInflater.from(myContext).inflate(R.layout.my_item_layout, content, false);
// Now, before we attach the view, find the TextView inside the layout.
TextView tv = (TextView) inflated.findViewById(R.id.text);
tv.setText(str);
// now add to the LinearLayoutView.
content.addView(inflated);
Is there a reason why the ImageView in the layout XML needs to have an ID? Could you erase the android:id attributes from the image_preview.xml layout and then simply iterate through the children of the inflated LinearLayout? For example:
ViewGroup v = (ViewGroup)getLayoutInflater().inflate(R.layout.image_preview,vg);
ImageView imv = (ImageView) v.getChildAt(0);
TextView dt = (TextView) v.getChildAt(1);
TextView ttl = (TextView) v.getChildAt(2);
I inflate XML-Layout with dynnamic and get text of id
private val onAddView = View.OnClickListener {
val parent = viewForm.findViewById<LinearLayout>(R.id.layout_parent)
LayoutInflater.from(activity).inflate(R.layout.layout_child, parent) // layout_child has id "tv_attribute"
}
private val onSave = View.OnClickListener {
val parent = viewForm.findViewById<LinearLayout>(R.id.layout_parent)
for (i in 0 until parent.childCount) {
val getText = parent.getChildAt(i).findViewById<TextView>(R.id.tv_attribute).text
}
}
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);
I want to get a a childView whose name is "name" inside a ViewGroup. I knew that the nameView is the second item inside the GroupView, so I used following code:
TextView nameView = (TextView)((ViewGroup)view).getChildAt(2); //2 is magic number
However, it is possible that ,in the future, I might add some other Views before the nameView and above code will became invalid. So, I am wondering how could get the ChildView by name, something like:
TextView nameView = (TextView)((ViewGroup)view).getChildByID(R.id.name);
EDIT: thanks to kcoppock. I realize getChildByName("name") does not make sense. So i will purse something like getChildByID.
You method are looking for is View.findViewById(id). Per your example:
TextView nameView = (TextView) view.findViewByID(R.id.name);
(It is not necessary to cast to ViewGroup)
Barry
If you just need to find a particular child of a ViewGroup by its ID, just first get a reference to the ViewGroup:
ViewGroup vg = (ViewGroup)findViewById(R.id.myGroupLayout);
Then call findViewById() on that ViewGroup:
View v = (TextView)vg.findViewById(R.id.name);