edit xml layout params dynamically before inflate - android

I would like to change layout params like layout_weight dynamically before inflating the layout and setting the content view for an activity. How would u do this?:
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//edit layout weight for some views in my layout here, before setting content view
setContentView(R.layout.mylayout);
}

I mean yes you can do it. By R.layout.mylayout you are just referencing to your layout resource. Just get a Layout object from that resource which might be like Layout mylayout = (Layout)findresourcebyid(R.layout.mylayout). After getting the reference you can change it dynamically and then inflate by setcontentview().

Related

How do I get a reference to a LinearLayout?

I am trying to get a reference to a LinearLayout so I can add an element.
Here is my xml.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/myLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
tools:context=".MainActivity">
Is it acceptable to have the line android:id="#+id/myLayout" in there?
My incorrect attempt to try and get a reference to my layout is with the following:
LayoutInflater myLayoutInflater;
LinearLayout myLayout;
if((myLayoutInflater = m_Context.getLayoutInflater()) != null) {
myLayout = (LinearLayout) myLayoutInflater.inflate(R.id.myLayout, null);
}
It underlines the R.id.myLayout in the inflate() line in red saying:
Expected resource of type Layout. Ensure resource ids passed to APIs are of the right type.
There's a misunderstanding about those methods.
LayoutInflater.inflate
This method expects the id of a layout file (and not of a layout view). So, you should call:
myLayoutInflater.inflate(R.layout.<NAME_OF_THE_XML_LAYOUT_FILE>, null);
That method will return whole view that was inflated. So, now that you have the inflated view, you can search Views inside of it. You can search view by their ID.
findViewById()
This method expects the id of the View. So, here, you should call:
View inflatedView = myLayoutInflater.inflate(R.layout.<NAME_OF_THE_XML_LAYOUT_FILE>, null);
LinearLayout linearLayout = inflatedView.findViewById(R.id.myLayout); // Assuming you added android:id="#+id/myLayout" to the LinearLayout
Note that first, we inflated the xml file and then, we started to seach for views inside of it.
HOWEVER
If your view is part of an Activity, you don't need to inflate that layout. You can instead:
public void onCreate() {
....
// This will inflate and add your layout to the actvity
setContentView(R.layout.<NAME_OF_THE_LAYOUT_FILE);
// After that line, you can call:
LinearLayout linearLayout = inflatedView.findViewById(R.id.myLayout); // Assuming you added android:id="#+id/myLayout" to the LinearLayout
// Since your view was added to the activity, you can search for R.id.myLayout
// If you search for any view before setContentView(), it will return null
// Because no view was added the screen yet
}
It is ok to find a view by id for a layout just like you do for a view:
LinearLayout layout = (LinearLayout) findViewById(R.id.myLayout);
This will do the trick if you are in an Activity context.
To add a view to it you can then do:
layout.addView(...)
You are getting that error because the LayoutInflater expects the name of the layout file not your layout id, so something like R.layout.item_layout. You also don't want to pass null for the parent view group in most cases so I would not recommend inflating it this way unless you know the parent layout.
Try something like this,
LayoutInflater myLayoutInflater = LayoutInflater.fromContext(mContext);
LinearLayout myLayout = myLayoutInflater.inflate(R.layout.layout_file, null);
View view = (LinearLayout)view.findViewById(R.id.myLayout);

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();

NullPointerException when accessing RelativeLayout from a custom view

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

Add & remove custom layout element in Activity Java code

I have a main activity
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//HOW TO: dynamically add or remove <com.my.custom.MyCustomLayout>
}
}
The content of the above main Activity is:
main.xml
<FrameLayout ...>
<LinearLayout ...>
<com.my.custom.MyCustomLayout
android:id="#+id/custom">
<FrameLayout>
As you see above, I have a custom layout element, which is a Java class extends LinearLayout like following:
public class MyCustomLayout extends LinearLayout{
...
}
In my activity java code, I would like to dynamically add or remove the custom layout element<com.my.custom.MyCustomLayout> in main.xml layout.
How to do it in My activity Java code?
Create a different layout file with your custom view like:
difflayout.xml:
<com.my.custom.MyCustomLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/custom">
Take a reference of your container LinearLayout on your code section. Use LayoutInflater and addView() and removeAllViews() of the ViewGroup class(here your LinearLayout)
First consider if you really want to remove the view from the layout or just completely hide it. You need to have a very good reason to go for the latter.
To just hide the view you would do in your activity
findViewById(R.id.custom).setVisibility(View.GONE) // to hide
// or
findViewById(R.id.custom).setVisibility(View.VISIBLE) // to show
If you really want to completely remove the view from the layout, you can
View customView = findViewById(R.id.custom);
ViewGroup parentView = (ViewGroup) customView.getParent();
parentView.removeView(customView)
you must have defined , id for the custom layout. use this id in java code
example : customLayout = (LinearLayout)findViewById(id);
now with customLayout call the layout

Android onCreate ClassCastException

I have this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = (LinearLayout) View.inflate(this, R.layout.main, null);
setContentView(layout);
s = (Spinner) findViewById(R.id.spinner1);
It throws a ClassCastException why is it?
If I do setContentView(R.layout.main) everything goes well. But i need to have the layout in a variable because I need it to use an advertsiment library. Is there a a way to inflate the XML and have the layout in an variable?
Thanks
Which line is throwing the ClassCastException?
Also you can use setContentView(R.layout.main); then still use a normal find view by id call to get a reference to your root layout.
LinearLayout layout = (LinearLayout)findViewById(R.id.yourParentId);
as long as this comes after you've called setContentView() you should get returned a reference to your layout object that you can use however you wish.
On what line does it throw the exception? Maybe the root view of the layout is not really a LinearLayout. Or maybe R.id.spinner1 is not a Spinner.

Categories

Resources