I am trying to get the Id of a text view in a fragment's onCreate() method. It returns null everytime.
I want to display my contacts in a fragment. For that at the end of FetchContact() method I assign the contact list to TextView.
Since my code is returning null when I find the TextView my application gives NullPointerException.
Anyone who could tell me how to get the Id of TextView of a Fragment in onCreate() method.
I tried making an object of activity class to get the TextView, still the code returned null. No luck.
public class ContactsFragment extends Fragment {
public TextView outputtext;
Context context;
class ActivityObj extends Activity{
public TextView text;
Context objContext;
#Override
public void onCreate(Bundle savedInstanceState) {
text =(TextView)findViewById(R.id.textContact);
objContext = getApplicationContext();
super.onCreate(savedInstanceState);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
ActivityObj obj = new ActivityObj();
super.onCreate(savedInstanceState);
outputtext =(TextView) getView().findViewById(R.id.textContact);
// outputtext= obj.text;
context=getActivity().getApplicationContext();
//fetchContacts();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.contacts_layout, container, false);
return rootView;
}
find the TextView my application gives NullPointerException.
Because in Fragment lifecycle onCreate method called before onCreateView method.
override onViewCreated which call after onCreateView method and use use first parameter of onViewCreated method for accessing views from Fragment layout:
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
TextView text =(TextView)view.findViewById(R.id.textContact);
/// your code here....
}
use
rootView.findViewById(R.id....) in your oncreateView there is where you should do the UI related work
You should use like this on onActivityCreated method
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
TextView tv = (TextView) getActivity().findViewById(R.id.textView1);
}
}
Or use callbacks
You cannot initialize any view using findViewById before onCreateView method calls.
So you must have to wait for the callback to run. And there are two ways to get it. And it will work on onActivityCreated because it called after onCreateView
As described by ρяσѕρєя K using the View param came from onViewCreated.
You can call getView() in any callback(delegate) which call after
onCreateView()
Like
TextView tv = (TextView) getView().findViewById(R.id.tv_id);
Related
lately, I was working on a very small training project.
But there is one error in my code:
public class MainActivity extends AppCompatActivity {
TextView textView = (TextView) findViewById(R.id.textview);
#override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView.setText("Welcome");
}
}
but when I tried to cut the textview global variable and paste it inside the onCreate method, the error has gone. Why is this error occur although I already have inflated the textView in a global variable ?!
You need to call findViewById(...) after calling setContentView(...).
Fetching the view before inflating the layout isn’t possible since there is no view.
findViewById() should only be used after setContentView() in onCreate.
That's where your entire layout get inflated. Only then you can access views using findViewById().
This is what you want:
public class MainActivity extends AppCompatActivity {
TextView textView;
#override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textview);
textView.setText("Welcome");
}
}
My first app is working fine alone but now I am trying to add tabs following a tutorial but I get stuck.
I've been searching and many users had same issue, I've tried those solutions but still unable to get it working fine.
My App
package es.ea1ddo.antenacubica;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
frecuencia = findViewById(R.id.frecuencia);
cal3el = (Button) findViewById(R.id.calcular3);
And now this is where I am trying to copy the previous app
package es.ea1ddo.calculadoraantenascubicas;
public class TabFragment2 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View v= inflater.inflate(R.layout.tab_fragment_2, container, false);
frecuencia = EditText.findViewById(R.id.frecuencia);
cal3el = (Button) getView().findViewById(R.id.calcular3);
I've been searching around, trying many examples and different ways but I am stuck.
You can see I added getView(). before every findViewById but I am still getting same error:
non-static method findViewById(int) cannot be referenced from a static context where T is a type-variable:
T extends View declared in method findViewById(int)
Please any advice?
Thanks
In your fragment code, you have two problems.
The first, as others have pointed out, is that View.findViewById() is a non-static method, so you would invoke it like myView.findViewById() as opposed to EditText.findViewById().
The second relates to how the Fragment's getView() method works. This method only works after onCreateView() has returned, because getView() returns whatever onCreateView() returned. That means that you can't call getView() from within onCreateView(); it will always return null.
Put together, your code should look like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View v= inflater.inflate(R.layout.tab_fragment_2, container, false);
frecuencia = (EditText) v.findViewById(R.id.frecuencia);
cal3el = (Button) v.findViewById(R.id.calcular3);
...
}
replace
frecuencia = EditText.findViewById(R.id.frecuencia);
cal3el = (Button) getView().findViewById(R.id.calcular3);
with
recuencia = (EditText) v.findViewById(R.id.frecuencia);
cal3el = (Button) v.findViewById(R.id.calcular3);
if not work please add full xml code in your question
Replace
EditText.findViewById
with
(ExitText) getView().findViewById
However, this will result in a NullPointerException.
You need to move any code that uses getView() into onViewCreated(), or reference v instead.
Can someone tell me where I am going wrong?
I'm trying to change my textview called MyText to something else, but when I try I get the error:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.Window.findViewById(int)' on a null object reference
at android.app.Activity.findViewById(Activity.java:2071)
public class MainScreen extends Activity {
TextView texting = (TextView) findViewById(R.id.MyText);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_screen);
texting.setText("Test");
};
}
This is how your code should look like:
public class MainScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_screen);
// If you're not using this view anywhere, you don't have to declare it globally. Use only a local variables
TextView texting = (TextView) findViewById(R.id.MyText);
texting.setText("Test");
};
}
You should ALWAYS initialize your views after you have your root layout. In this case, right after you did setContentView(R.layout.activity_main_screen); This scenario applies to Activites.
In case you use a fragment you should do this right after you inflated your root layout in the onCreateView method. Something like:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = (LinearLayout) inflater.inflate(R.layout.my_fragment, container, false);
// THIS is where you start initializing your views
return view;
}
The TextView is not available until after setContentView is called. So, findViewById will return null when MainScreen is instantiated. The solution is to move the findViewById call to the onCreate method as follows:
public class MainScreen extends Activity {
TextView texting;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_screen);
texting = (TextView) findViewById(R.id.MyText);
texting.setText("Test");
}
}
Do the following:
public class MainScreen extends Activity {
TextView texting;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_screen);
texting = = (TextView) findViewById(R.id.MyText);
texting.setText("Test");
};
}
You have to initialize your TextView object inside your onCreate method.
I have a spinner that i populate with an array list from a resource. I have it populated and the code is compiling correctly. My problem now is that I can't seem to figure out how to access the spinner from my main class. For instance, I have my class "CreateExerciseActivity" where I have my method "createExercise"
public class CreateExerciseActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_create_exercise_activiy);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
public void createExercise(View view){
EditText name = (EditText) findViewById(R.id.editText1);
DataBaseWrapper dbHandler = new DataBaseWrapper(this);
Exercise exercise = new Exercise(name.getText().toString(), category);
dbHandler.addExercise(exercise);
name.setText("");
}
}
And below is the code for my fragment where I initialize and populate the spinner
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
private Spinner spinner;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater
.inflate(R.layout.fragment_create_exercise_activiy,
container, false);
loadSpinnerCategories(rootView);
return rootView;
}
private void loadSpinnerCategories(View view){
spinner = (Spinner) view.findViewById(R.id.category_spinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getActivity().getBaseContext(), R.array.categories,
android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
}
}
I want to know how I can access my spinner from the first class "CreateExerciseActivity" now that it has been populated from the fragment. I want to be able to take the option someone has selected and enter it into the database along with exercise name in the method "createExercise".
There's many ways of doing this.
Usually, you want to respond to some type of event in the fragment. For example, a button is pressed. From the fragment you can call the activity like this:
CreateExerciseActivity activity = (CreateExerciseActivity) getActivity();
activity.createExercise(....);
A better way would be for the activity to implement an interface IOptionSelectedListener for example. The interface could have a method called OnOptionSelected(value). Then you could do:
IOptionSelectedListener listener = (IOptionSelectedListener) getActivity();
listener.OnOptionSelected(....);
You could also pass the activity reference to the newInstance() method of the fragment, instead of calling getActivity().
The activity could also have a reference to the fragment and call a method on the fragment to get the actual value of the spinner.
I have the following Activity:
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new StartFragment())
.commit();
}
Button login = (Button) findViewById(R.id.loginButton);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Intent intent = new Intent(MainActivity.this,LoginActivity.class);
startActivity(intent);
}
});
}
I get a NPE when I try to invoke findViewByID for R.id.loginButton, and I'm guessing this is because loginButton is within a separate Fragment, which I have as:
public static class StartFragment extends Fragment {
public StartFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container, false);
}
}
However, I am unsure of how to fix this so that I can find the loginButton ID. I haven't worked with fragments before, so I realize I may be using them/implementing them incorrectly. fragment_main contains a few buttons in a LinearLayout, and activity_main has nothing but a single FrameLayout.
Try to implement your onCreateView(...) in Fragment like
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
View something = rootView.findViewById(R.id.something);
something.setOnClickListener(new View.OnClickListener() { ... });
return rootView;
}
The Button is in the fragment layout (fragment_main.xml) and not in the activity layout (activity_main.xml). onCreate() is too early in the lifecycle to find it in the activity view hierarchy, and a null is returned. Invoking a method on null causes the NPE.
Write code to initialize button from fragment becuase your button is into fragment layout not into activity's layout.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
Button login = (Button) rootView.findViewById(R.id.loginButton);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Intent intent = new Intent(MainActivity.this,
LoginActivity.class);
startActivity(intent);
}
});
return rootView;
}
And remove the login button related code from onCreate of Activity.
findViewById() works with reference to a root view.
Without having a view in the first place will throw a null pointer exception
In any activity you set a view by calling setContentView(someView);.
Thus when you call findViewById() , its with reference to the someView.
Also findViewById() finds the id only if its in that someView. So in you case null pointer exception
For fragments, adapters, activity, .... any view's findViewById() will only find if the id exixts in the view
Alternately if you are inflating a view, then you can also use inflatedView.findViewById() to get a view from that inflatedView
In short make sure you have the id in your layout you are referring to or make findViewById() call in appropriate place(Ex. adapters getView(), activity's onCreate() or onResume() or onPause() , fragments onCreateView(), ....)
Also have an idea about UI & background thread's as you cannot efficiently update UI in bg-threads