I have a custom layout called "debug.xml" in folder "layout/" which is desired to add programmatically into a predefined Layout in activity_main.xml called centerLayout. The "debug.xml" is something like:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/debug_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<EditText
android:id="#+id/commandEditText"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:inputType="text" />
</LinearLayout>
</LinearLayout>
I want to add this "debug_layout" into a centerLayout:
LinearLayout centerLayout = (LinearLayout) findViewById (R.id.center_layout);
LinearLayout debugLayout = (LinearLayout) findViewById (R.id.debug_layout);
centerLayout.addView(debugLayout);
But it encounters NULL pointer excetion at "centerLayout.addView(debugLayout);". So it seems the debug_layout is not initialized or something. Does anyone can help me?
Are you sure that your centerLayout is not null? If not, did you tried?:
LinearLayout centerLayout = (LinearLayout) findViewById (R.id.center_layout);
LinearLayout debugLayout = getLayoutInflater().inflate(R.layout.debug, centerLayout, false);
centerLayout.addView(debugLayout);
you need to inflate the debugLayout with the LayoutInflater
Related
Using Xamarin.Android native in Visual Studio 2017.
Here is an example of my layout. Let's call it 'headache.axml'.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/topLinearLayoutId"
android:paddingLeft="20dp"
android:paddingTop="0dp"
android:paddingRight="20dp"
android:paddingBottom="15dp"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_width="match_parent"
android:onClick="showPasswordDialog"
android:orientation="horizontal" >
<TextView android:id="#+id/sampleId_0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/sampleId_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
. . . more views . . .
</LinearLayout>
And here is the code where I inflate this layout.
View view = inflater.Inflate(Resource.Layout.fragment_selection, container, false);
ViewStub stub = (ViewStub) view.FindViewById(stubIds[i]);
stub.LayoutResource = Resource.Layout.headache;
View inflatedView = stub.Inflate();
Then I can use inflatedView.FindViewById() to get any view from my layout except the top LinearLayout.
For example, these lines work perfect:
var txtView0 = (TextView) inflatedView.FindViewById(Resource.Id.sampleId_0);
var txtView1 = (TextView) inflatedView.FindViewById(Resource.Id.sampleId_1);
Both txtView0 and txtView1 are initialized.
And here is my problem, when I try to get the top View from my layout I get null:
var top = (LinearLayout) inflatedView.FindViewById(Resource.Id.topLinearLayoutId); // returns null
As a workaround,
I've added a pre-top LinearLayout to my 'headache.axml'. It's become like this:
<?xml version="1.0" encoding="utf-8"?>
<!-- workaround: pre-top LinearLayout (still inaccessible) -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/glitchyLinearLayout"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="horizontal">
<!-- workaround: accessible LinearLayout -->
<LinearLayout
android:id="#+id/topLinearLayoutId"
android:paddingLeft="20dp"
android:paddingTop="0dp"
android:paddingRight="20dp"
android:paddingBottom="15dp"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_width="match_parent"
android:orientation="vertical">
<TextView android:id="#+id/sampleId_0"
... all the same ... />
<TextView android:id="#+id/sampleId_1"
... all the same ... />
. . . more views . . .
</LinearLayout>
Now I can get my topLinearLayoutId.
var top = (LinearLayout) inflatedView.FindViewById(Resource.Id.topLinearLayoutId);
In this case, the top is initialized and my application works well.
But I'd like to understand why the hell I've got this problem.
I have to include one layout in my application. So that I have used
<include
android:id="#+id/support_layout"
android:width="match_parent"
android:height="match_parent"
layout="#layout/support"/>
I have referenced this include tag in my java file using View.
View v = (View) findViewById(R.id.support_layout);
But at some point of my code I have to Hide this layout.
so that I used v.GONE
But it's not Hiding.
I want to reference those text and button attributes located in XML programatically.
How can I do that?
There is my support.xml:
<LinearLayout
android:id="#+id/support_layout"
android:width="match_parent"
android:height="match_parent">
<TextView
android:id="#+id/txt"
android:width="match_parent"
android:height="wrap_content"/>
<Button
android:id="#+id/btn"
android:width="match_parent"
android:height="wrap_content"
android:text="Button"/>
</LinearLayout>
Since <include/> is not a View type in android and visibility is the property of View, we can not access the visibility from included layout's reference.
However if you are using kotlin with view binding, we can get the reference of root of the included layout like binding.supportLayout.root which probably will be one of the View (ConstraintLayout, RelativeLayout, LinearLayout etc.)
Now we have reference of view means we can play with their visibility like below code.
binding.supportLayout.root.visibility = View.GONE
Hope you got the idea.
We need to see your actual implementation of hiding that View you mentioned.
But, straight from reading of your question, I presume that you've might do it the wrong way.
To hide or make a view invisible, use this:
yourView.setVisibility(View.INVISIBLE);
Bear in mind that this does not remove the view compeletly; it would still remain in your layout and you could get a reference to it or even try to manipulate it.
To remove it compeletly, use this instead:
yourView.setVisibility(View.GONE);
Now if you call this, yourView would be compeletly removed from the layout. You will no longer able to get a reference to it.
Put that view into a linearlayout and hide the linearlayout. It will work.
<LinearLayout
android:id="#+id/support_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<include
layout="#layout/support"
android:height="match_parent"
android:width="match_parent" /> </LinearLayout>
And don't forget writing Linearlayout instead of View.
Briefly, instead of
View v = (View) findViewById(R.id.support_layout);
Do this
LinearLayout v = (LinearLayout) findViewById(R.id.support_layout);
You can hide this "included" layout with calling setVisibility() :
v.setVisibility(View.GONE)
and show it later with calling :
v.setVisibility(View.VISIBLE)
To reference button and textview from support layout you can use findViewById method on your included View (I'm not sure but I think it's even not mandatory, you can call it directly on your activity's view) :
View supportLayout = (View) findViewById(R.id.support_layout);
Textview txv = (TextView) findViewById(R.id.txt);
Button btn = (Button) findViewById(R.id.btn);
(if it's not working try with : Button btn = (Button) supportLayout.findViewById(R.id.btn);)
-- FYI --
When you give attributs to include tags it override ones of the included layout (there support_layout LinearLayout) so you don't need to do that
you must use like this includedLayoutId.viewId.visibility = View.GONE in this case you can access to included view, now for example:
loading.xml
<com.airbnb.lottie.LottieAnimationView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:lottie_autoPlay="true"
app:lottie_fileName="loading.json"
app:lottie_loop="true" />
in fragment_a.xml :
<include layout="#layout/loading"
android:id="#+id/anim_loading"
android:layout_width="match_parent"
android:layout_height="#dimen/_80sdp"/>
and finally use it animLoading.loading.visibility = View.GONE
Thanks to the new ConstraintLayout.
This is how I do it with widget.Group
<include
android:id="#+id/bottom_bar_action"
layout="#layout/bottom_bar_back_action"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<androidx.constraintlayout.widget.Group
android:id="#+id/bottom_bar_group"
android:layout_width="0dp"
android:layout_height="0dp"
app:constraint_referenced_ids="bottom_bar_action" />
Then you can hide the include layout by doing binding.bottomBarGroup.visibility = View.GONE. Cheers
// 1 - copy this
<?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"
tools:context=".Add">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="gone"
android:onClick="onclick_gone_include"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="visible"
android:onClick="onclick_visible_include"/>
<LinearLayout
android:id="#+id/support_layout"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="100dp"
>
<include
layout="#layout/support"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
//code
//2 copy this to Add cliass
//this methods on click in Add class
public void onclick_gone_include(View view) {
View v = (View) findViewById(R.id.support_layout);//view is the v
v.setVisibility(View.GONE);
}
public void onclick_visible_include(View view) {
View v = (View) findViewById(R.id.support_layout);
v.setVisibility(View.VISIBLE);
}
//3 activity that included 'support activity'
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
tools:context=".Add"
android:gravity="center"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="textview1"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="textview2"
/>
</LinearLayout>
I have an activity with a background:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:minWidth="25px"
android:minHeight="25px"
android:background="#drawable/background_fingerboard" />
How can I change background image from code? I actually use mono, but Java samples will also be helpful.
first add LinearLayout id as in your layout xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/linearLayoutid"
android:minWidth="25px"
android:minHeight="25px"
android:background="#drawable/background_fingerboard"
and in code part set background as::
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linearLayoutid);
linearLayout.setBackgroundResource(R.drawable.background_fingerboard);
In java we do like this
Give id to LinearLayout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id=#+id/parentLayout
Then in code
LinearLayout layout=(LinearLayout)findViewById(R.id.parentLayout);
layout.setBackgroundColor(Color.BLUE); Or
layout.setBackgroundDrawable(d); Or
layout.setBackgroundResource(resid);
LinearLayout vi = (LinearLayout ) findViewById(<id>)
vi.setBackgroundResource(R.drawable.<id2>);
you need to provide the id to your LinearLayout in XML as well....
I have this main.xml layout which has a fixed header and footer. The body content has to change based on the parameters received.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="#FFFFFF"
android:id="#+id/main_view">
<com.HeaderView
android:id="#+id/HeaderView"
android:layout_alignParentTop="true"
android:layout_width="fill_parent" android:layout_height="wrap_content" />
<com.FooterView
android:id="#+id/FooterView"
android:layout_alignParentBottom="true" android:layout_width="match_parent"
android:layout_height="wrap_content" />
<RelativeLayout android:layout_width="fill_parent"
android:layout_height="wrap_content" android:id="#+id/BodyView"
android:layout_below="#id/HeaderView"
android:layout_above="#id/FooterView"/>
</RelativeLayout>
Based on the below conditions I need to load the BodyView in the main.xml.
If parameter == Apple
then load layout AppleView in the BodyView
if parameter == Bat
then load layout BatView in the BodyView
I have AppleView and BatView xml layout defined. Could somebody please guide me as to how I can load either of the views and set/get values into/from it.
Here is an example of inflating, hope this is what you need.
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.temp, null);
RelativeLayout rl = (RelativeLayout)findViewById(R.id.glavenfrejm);
RelativeLayout.LayoutParams parametri = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
parametri.addRule(RelativeLayout.ALIGN_PARENT_TOP);
rl.addView(v, parametri);
I want to decompose my UI into several XML Layouts. The first one would be the main layout, and the other ones would be the content layouts.
I would like to be able to set which content_layout should be included dynamically at run-time, so I don't want to set a "layout="#+layout/content_layout" in my XML file.
Here are my layouts:
main_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="600dp"
android:layout_height="800dp" >
<TextView
android:id="#+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" />
<include /> <!-- I WANT TO INCLUDE MY CONTENT HERE -->
<Button
android:id="#+id/cancelButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="Cancel" />
</RelativeLayout>
content_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/whatever"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
content_layout2.xml:
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/whatever2"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
How can I do that?
Thanks!
<RelativeLayout android:id="#+id/rl" ...
In your code:
// get your outer relative layout
RelativeLayout rl = (RelativeLayout) findById(R.id.rl);
// inflate content layout and add it to the relative layout as second child
// add as second child, therefore pass index 1 (0,1,...)
LayoutInflater layoutInflater = (LayoutInflater)
this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rl.addView(1, layoutInflater.inflate(R.layout.content_layout, this, false) );
You could try using a ViewStub and just change which layout it is going to inflate programatically.
This answer discusses using one ViewStub.