7
package com.example.dell.helloworld;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void showToast(View view)
    {
        Toast t= new Toast(this);
        LayoutInflater inflater=getLayoutInflater();
        View v=inflater.inflate(R.layout.toast, (ViewGroup) findViewById(R.id.toastViewGroup));
        t.setView(v);
        t.show();


    }
}

From the android developer site findViewById searches for child views with give id.

In the above code, who is the parent view, whose children are being searched for given id?

q126y
  • 1,589
  • 4
  • 18
  • 50

3 Answers3

3

in the XML file when we add an element and set the properties to it we only set the values for these properties, now for each element, there is a class that draws it at the screen, this class has attributes with the same names of the properties in the XML file now using algorithms of read-write from files these values from the XML file are transmitted to the java file (class) of the element, and then the class draws that element on the screen.

Before the class of the element draws it, there is a superclass of all elements, the parent for all of them it is called View (every element in the activity is called view) this class has the basic properties of all elements and this class is the one which the properties from the XML file will be transmitted to it.

Method findViewById() returns an object of View type, this object holds the properties values then we need to cast it to the specific element, for example, TextView which is a class to draw the text view this class and all elements' classes are subclasses of View class so what we do is downcasting, that when this method returns the object of View type we downcast it to the element class

How it finds the properties? it finds the properties of the element using the id if the tag in the XML file first it searches in the XML file for the tag that holds the element's name and then it looks at the id if it is the id which it wants then it takes it otherwise it searches for another tag (with the same element name).

We give it the id by this approach. there is a class is called R (resources), this class has nested classes (id, string, colors) these classes have attributes from the same type and hold specific values, for instance, the id class it has attributes that stores each id of each element in the XML file, so when we want to give the method findViewById() the id we go to this class and tell it to enter id class and choose the id of the element we want.

ِِAnd the process goes that it enters to the XML file and look for the element that has this id and it takes the properties and passes them to the class view object and when it returns the object we downcast it to the element's class that we want to draw it and deal with it.

2

The root view in an Activity is determined by setContentView(int layoutId) or setContentView(View rootView).

In your case, it is

setContentView(R.layout.activity_main);

Therefore, any call you make to findViewById will lookup the id from activity_main.xml.

If it is unable to find the id that you have specified, it will return null.


It is worth mentioning that that you aren't calling that method and this is typically how a Toast is made.

Toast.makeText(getApplicationContext(), "Hello toast!", Toast.LENGTH_SHORT).show();
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • "Therefore, any call you make to findViewById will lookup the id from activity_main.xml. " --- But the Id I am seraching is in toast.xml and it works. – q126y Feb 12 '16 at 08:39
  • In the code you've shown, `findViewById` **is** called on activity_main because you are calling it from the Activity class (like `this.findViewById`). If you want to call it on the toast layout, then you'll need to do `v.findViewById`. If it works the current way, then I imagine you have duplicated that `R.id` value in both XML files – OneCricketeer Feb 12 '16 at 08:52
  • http://pastebin.com/sXrTpDc0 http://pastebin.com/QLbbLUdL I have not duplicated the ids. – q126y Feb 12 '16 at 08:55
  • So you're problem is that it isn't showing anything? See my answer where it says it will return null if it cant find the id? That's exactly what is happening because you are finding the view in the wrong layout – OneCricketeer Feb 12 '16 at 08:58
  • It works as it should. What I meant was, if View inflated from R.layout.toast is set as child of root View of activity(as said by @Grestmann) why doesn't it show up, as soon as it is inflated. But it shows up when show method of toast is called. Therefore the statement that the view inflated from R.layout.toast is set as child of root view of activity seems wrong. – q126y Feb 12 '16 at 09:08
  • I think that last statement you said is correct. There is nowhere in this code that you set the toast layout to a child view (or content view) of this Activity's root view – OneCricketeer Feb 12 '16 at 09:13
  • Then how does `findViewById` work? Who is the parent view whose children are searched? – q126y Feb 12 '16 at 09:15
  • Also, he never said the toast layout was a child view...?You are inflating both the MainActivity xml and the Toast xml. You manually inflated the toast xml and Android handles inflating the MainActivity xml for you. I think that is where you're confused – OneCricketeer Feb 12 '16 at 09:17
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/103267/discussion-between-cricket-007-and-q126y). – OneCricketeer Feb 12 '16 at 09:17
1

In the case of an Activity, findViewById starts the search from the content view (set with setContentView) of the activity which is the view hierarchy inflated from the layout resource.

Gerstmann
  • 5,368
  • 6
  • 37
  • 57
  • So the `View` inflated from `R.layout.toast` is set as child of content view? if yes, then why It doesn't show up, as soon as it is inflated? – q126y Feb 12 '16 at 08:29
  • @cricket_007 I call the method on button click. What I am saying is if `View` inflated from `R.layout.toast` is set as child of root `View` of activity why doesn't it show up, as soon as it is inflated? I tried setting `.setVisibility(View.VISIBLE)` on the inflated view. – q126y Feb 12 '16 at 08:38
  • 1
    @q126y Check the layout parameters (width, height) of the inflated view and the parent view (`R.id.toastViewGroup`). It could be that it does not know how to calculate its size. – Gerstmann Feb 12 '16 at 08:43
  • @Gerstmann They know how to calculate their size. here is the layout file http://pastebin.com/QLbbLUdL – q126y Feb 12 '16 at 08:46