findViewById not working when finding layout? - android

I'm trying to make the whole screen clickable so I'm trying to set an id for a layout and find it in java class. When I do this, it says incompatiable types (layout vs a view). I understand they are different types but upon googling this, several posts have suggested selecting the layout in an activity in this manner. They can make a call such as this -
RelativeLayout theLayout = (RelativeLayout) this.findViewById(R.id.Layout)
and they don't seem to be getting this error.
Another stackoverflow post with this - onTouchListener for entire screen
My code referencing this is below -
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:id="#+id/thelayout" >
<TextView android:text="This will change with speech" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="#+id/textview"/>
</RelativeLayout>
And in activity -
RelativeLayout theLayout = this.findViewById(R.id.thelayout);
Am I missing somethinng?

Instead of this,
RelativeLayout theLayout = this.findViewById(R.id.thelayout)
Try this in your Activity,
RelativeLayout theLayout = (RelativeLayout) this.findViewById(R.id.thelayout)

Instead of using setContentView(int layoutResID) with the layout id, inflate the layout get the view reference and then use the setContentView(View view).
View layout = View.inflate(context, R.layout.theLayout, null)
setContentView(layout)
You don't need to cast the layout to RelativeLayout, as you can add the click/touch listener to a View class.

Related

How can I create Views in xml which I can use for any layout?

When creating an ImageView for example, I know I can create it within a Layout:
Example a LinearLayout:
<LinearLayout...>
<ImageView
android:id="#id/hello_world_id"/>
</LinearLayout>
But can I define an View outside a layout, and then add it to any other layout?
I want to have a RelativeLayout which adds/removes views programmatically and dynamically, so that the RelativeLayout starts off with no views inside it, then I add some, remove some etc. Would there be any way to do this? Or is it better just to have these views already inside some other Layout, and then I add the Layout (whatever it is--containing my view(s)) to my RelativeLayout?
What you are searching for is LayoutInflator
Create a xml file - buttons.xml
<LinearLayout...>
<ImageView
android:id="#id/hello_world_id"/>
In your activity access it by
final LayoutInflater inflater
= (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.buttons,
null);// this is a layout in your master activity
lLayout = (LinearLayout)findViewById(R.id.layout1);
lLayout.addView(itemView);
Hope this helps.

findViewById() from custom view return null

It seem similar to other questions but I doesn't found solutions. I have a layout defined by xml file:
main_layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
... >
<package.CustomView
... >
</package.CustomView>
<TextView
android:id="#+id/text_view"
... >
</TextView>
</RelativeLayout>
where CustomView extends SurfaceView.
In onCreate I have setContentView(R.layout.main_layout). Now, If I want to inflate, for example, the TextView in the activity I have to add after setContentView(...)
TextView textView = (TextView) findViewbyId(R.id.text_view);
and all works fine. But if I put this line in a method of my CustomView I got a null pointer. Why?
findViewById() will traverse only the given view and its children. It will not find sibling views. Your textview is a sibling to the custom view, not a child view.
In an activity, the root view where findViewById() traversal starts is the activity window (Activity.findViewById()). In a view, it is the view itself (View.findViewById()).
Understanding helpful explanation above I would like to give an easy way to find a view by its ID from CustomViews:
(Activity)getContext()).findViewById(R.id.youViewToBeFound);
inside your CustomView class.
This code must be run AFTER constructor code e.g. inside onAttachedToWindow()

NPE when inflating layout

I have to set a layout inside other layout's child (linearlayout). To do this, I write this code on the layout's activity that I want to set into the root layout:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
**setContentView(R.layout.main);**
/**Define root layout's child where I want to set the layout*/
LinearLayout inside_menu_view = (LinearLayout)findViewById(R.id.activitycontent);
/**Inflate this layout and add it to the root layout*/
LayoutInflater inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View this_layout = inflater.inflate(R.layout.main, null);
inside_menu_view.addView(this_layout);
But I'm getting a NULLPOINTEREXCEPTION in this last line inside_menu_view.addView(this_layout);
UPDATE
-Added the setContentView() after super.onCreate
This line will return null because you have not yet called setContentView()
LinearLayout inside_menu_view = (LinearLayout)findViewById(R.id.activitycontent);
You need to call setContentView(R.layout.layout_with_activitycontent); first
From the Docs
Finds a view that was identified by the id attribute from the XML that was processed in onCreate(Bundle).
Returns The view if found or null otherwise.
You have not yet processed an xml layout file with setContentView() or by using a LayoutInflater so it will return null causing a NPE when you try to call a method on it like addView().
Edit
I'm not sure why you are doing it that way but you can't. As in my link above, you can only use findViewById() to find a View inside the inflated layout. You can't use it to find a View inside some other layout which hasn't been inflated.
Put that layout file in setContentView() if that is the one you want to use.
Different approach
You probably want to use Fragments then to achieve this.
See the docs on how to use these
Or you can use <include> to include the "menu" layout that you want to include in all of the Activities then you can switch Activities when you need to show the inner part of your layout.
See here about re-using layouts
Example of <include>. You have some layout that you want to re-use, say main.xml, then in an Activity in which you want to re-use it you simply do something like
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="30dp"
android:background="#drawable/blue">
<include layout="#layout/main"
android:id="#+id/main_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<!-- other layouts -->
/<RelativeLayout>
yours will obviously be different but this is an example of one I have. Hope this helps.
Let's say your R.layout.main is a LinearLayout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/main_layout" >
</LinearLayout>
Now in onCreate():
LinearLayout layout = (LinearLayout) findViewById(R.id.main_layout);
LayoutInflater inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View this_layout = inflater.inflate(R.layout.main_layout, layout, true);
And this_layout is automatically added to the activity's layout.

how to add linearlayout inside of linearlayout when application running

I want to know, there is a linearlayout and use that with setContentView function. Also there is a spinner inside of linearlayout. What I want to do is, create a new layout inside of /res/layout folder and add it into layout that I set with setContentView.
Is there anyway or I need to do that programmatically?
EDIT:
I think I couldn't tell.
I have 2 two layouts(ready). I use the first layout with setContentView.For example, there is a buton and if user click that button, I want to add second layout bottom of first layout when application running.
Easiest you do that with include in the xml of your main layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<include layout="#layout/second" />
</LinearLayout>
It´s also possible to do it programmatically, but this way I think it is more clear.
Edit:
To do this programmatically, put this code in listener of the first button.
RelativeLayout view = (RelativeLayout) findViewById(R.id.RelativeLayout1);
Button b = new Button(getApplicationContext());
b.setText("Click me too!");
view.addView(b);
Instead of creating a button (or whatever you want) you can also inflate a premade layout.
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.second, null);
view.addView(v);
I don't think you can change the res folder programmatically. You need to add any layout programmatically only.
Edited:
Get the 2nd layout's instance using findViewById and use setVisibility method to control the layout's visibility.

Android including an xml layout to activity

I've an activity.java file in which my setContentView(R.layout.x); Now,I've an y.xml in which I've an Linear Layout,I've to attach an onclick() method to my view.
Attaching onclick() has to be in my activity.java file, How do I include y.xml.
I tried this,
1. layout = (LinearLayout) findViewById(R.layout.y);
eView = (EditText)layout. findViewById(R.id.editview);
2. eView = (EditText)findViewById(R.id.editview);
but both gives my null pointer exception, How do I include my editText
Update
final LayoutInflater lyInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
showLinearLayout = (LinearLayout) lyInflater.inflate(R.layout.y, null);
showView = (EditView) showLinearLayout.findViewById(R.id.edittext);
You can use inflation as shown below:
final LayoutInflater lyInflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout yLayout = (LinearLayout) lyInflater .inflate(
R.layout.y, null);
eView = (EditText)yLayout.findViewById(R.id.editview);
So you won't get exception anymore. Hope it helps.
LayoutInflater is used to instantiate layout XML file into its corresponding View objects.in other words, it takes as input a XML file and builds the View objects from it.
in your scenario, you have to use LayoutInflater. read this article.
Ram.
If you want to include y xml file into your x xml file then follw this steps.
I am assuming that you want to include Linear Layout into your Activity on click of onclick() method of the button or whatever, then add the Linear Layout into your x xml file and add the android:visibility="gone" so at begin you can not show the linearlayout.
<LinearLayout
android:id="#+id/history_value_body"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone" > <<<<<<<<<<< HERE
----------------------------
-----------------------------
</LinearLayout>
Now, From the java class make it visible when needed, in your case into onclick method.
Like...
linear.setVisibility(View.VISIBLE); // linear is the object of your Linearlayout
If any prob then ask me.
Good Luck.
If I understand the question correctly, your Activity uses x.xml, and you also want to include another layout that is defined in y.xml.
You can do so using the <merge> or <include> tags, as described in the documentation.
Alternately, you can use a ViewStub to conditionally inflate another layout in a given place in a layout. For example, you can include a ViewStub tag in x.xml, and inflate y.xml in the same spot in the view hierarchy. Then, you may attach any click listeners you need (by using findViewById()).
You can use addView method of ViewGroup.
addView(layout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));

Categories

Resources