I am relatively new to Android and am completely stuck on how to access my programmatically-defined Relative Layout (defined in a fragment) in my custom View.
In the fragment, this is what I have:
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment1, container,false);
RelativeLayout rl1 = new RelativeLayout(view.getContext());
TextView tView1 = new TextView(view.getContext());
tView1.setText("test");
rl1.addView(tView1);
rl1.setId(1);
tView1.setId(2);
...
}
Then in the custom view I call the relative Layout and TextView by id. When I try to do anything, I get a NullPointer exception.
...
RelativeLayout rl1 = (RelativeLayout) findViewById(1);
TextView tView1 = (TextView) findViewById(2);
tView1.getText();
The code above shows trying to .getText() on the TextView, but anything I do to the RelativeLayout also causes a NullPointer exception.
So basically, it looks like I'm not finding the RelativeLayout and TextViews correctly.
FYI, I've already seen this similar question, but it didn't apply here, my constructors are already set up appropriately.
You should be adding the Layout to the main View, however, you need to cast it first into a Layout:
YourLayout view = (YourLayout) inflater.inflate(R.layout.fragment1, container,false);
RelativeLayout rl1 = new RelativeLayout(view.getContext());
TextView tView1 = new TextView(view.getContext());
tView1.setText("test");
rl1.addView(tView1);
rl1.setId(1);
tView1.setId(2);
view.addView (rl1);//add rl1 to the main View
Then to access, if you're working outside onCreateView() and onCreateView() has already been called:
RelativeLayout rl1 = (RelativeLayout) getView().findViewById(1);
TextView tView1 = (TextView) rl1.findViewById(2);
tView1.getText();
If you're still trying to access the views in onCreateView(), findViewById() doesn't matter - you already have the references of your Views so use those.
It's also worth noting that adding listeners and such in onCreateView() to update the UI can be done, so you may be able to simply things a bit.
You have to add your Relative layout to your layout group... And from the parent view of your layout you can access your relative layout and its childs
Related
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();
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
Programatically I have a RelativeLayout and TextView (called title) within it defined as follows:
RelativeLayout layout = new RelativeLayout(this);
final RelativeLayout.LayoutParams parameters_title =
new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
title.setLayoutParams(parameters_title);
layout.addView(title,parameters_title);
I intend to add more textviews and buttons later. But for now, I want to "convert" (I am not sure how to put it into words) the RelativeLayout into a View in order to put it into WindowManager. I was trying to use LayoutInflater like this but it wouldn't work
LayoutInflater layoutInflater =
(LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
myView = layoutInflater.inflate(layout, null );
then the goal is to put myView into WindowManger through addView. How can I get a View from my RelativeLayout?
you can do this by getChildAt but you will have to keep the position of the view you want to get from layout. To avoid this you can set an id for your view and get the view with findViewById(). If you inflate a view from xml you will get the same views as xml. if you add some new views to the relativeLayout it will not effect the view you inflate from the xml.
when you are adding the view:
myView.setId(id);
layout.addView(myView);
when you are retrieving
View myView = layout.findViewById(id);
I am currently populating an Adapter on startup with views inflated from XML using
private void addView(Context context) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.deal_tile, this, null);
mViews.add(view);
}
However, I've found that storing the views in a list inside the AdapterView creates problems with controls within those views, so I want to change over to use the recycling functions in Adapter#getView(int position, View recycle, ViewGroup container).
For this reason I want to use a custom view class so I can do a sanity check (if(recycle!=null && recycle instanceof CustomView)) before I repopulate it in the adapter. However, I can't find out how you inflate a custom view class from XML. I can find out how you add an inflated view to a custom view, I can find out how you insert a custom view into an XML layout, etc, and obviously I am quite happily inflating these things directly using LayoutInflater, but I can't find an equivalent for generating the custom view itself. I want to reuse the XML I already have; consequently I don't want to program in the elements (and how they look) directly.
I used this to create my own slide gallery, i think it would help.
LinearLayout internalWrapper = new LinearLayout(getContext());
internalWrapper.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
internalWrapper.setOrientation(LinearLayout.HORIZONTAL);
addView(internalWrapper);
this.mItems = items;
LinearLayout generalLayout = new LinearLayout(this.getContext());
generalLayout = (LinearLayout) View.inflate(this.getContext(), R.layout.galleryrow, null);
// inside linear layout
LinearLayout generalLinear = (LinearLayout) generalLayout.findViewById(R.id.rowgenerallin);
// set height & width to the LINEAR
generalLinear.setLayoutParams(new LayoutParams(reference_width, reference_height));
ImageView ivl = (ImageView) generalLayout.findViewById(R.id.arrow_left);
ImageView ivr = (ImageView) generalLayout.findViewById(R.id.arrow_right);
internalWrapper.addView(generalLayout);
In my case, R.layout.gallery_row contains the two images I want to manage, nested by a LinearLayous (rowgenerllin), the internal wrapper is an empty LinearLayout declared in the main layout of your activity.
Double check the LayoutParams code or you will get a big NULL :)
Cheers!
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);