Here's my code in the main activity don'tn know why error in findViewById occurs
.. this is just my first time in JSON paarsing .
public class HomeFragment extends Fragment{
public HomeFragment(){}
View rootView;
ListView list;
ActorsAdapter adapt;
ArrayList<Actors> actorslist;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.home_fragment, container, false);
list = (ListView)findViewById(R.id.listFeeds);
actorslist = new ArrayList<Actors>();
return rootView;
new ActorsAsynTask().execute("http://jcasim.5gbfree.com/Project/login.php");
}
listFeeds It's a component I'm pretty sure is a component that lives in your fragment. Since you haven't return the root view yet, the findViewById is not going to find it. you have to wait until it's on screen to ask for it using findViewById (in onStart() method) or ask it form the root view before you return it.
it would be list = (ListView)rootView.findViewById(R.id.listFeeds);
The View of the Fragment is not set before the onCreateView() returns. Therefore the findViewById() tries to find the specified R.id.listFeedsfrom a null reference.
Try this instead list = (ListView)rootView.findViewById(R.id.listFeeds);
Related
I have a ConstraintLayout (the child) nested in another ConstraintLayout (the parent). I want to be able to call the child from within my Fragment class, but outside onCreateView. This what I have so far:
public class HomeFragment extends Fragment {
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
HomeViewModel = new ViewModelProvider(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);
return root;
}
ConstraintLayout MyLayout = (ConstraintLayout) getView().findViewById(R.id.my_layout);
}
Which results in a NullPointerException:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
I even tried declaring a global root variable in the Fragment class and assigning the inflated view result to it, but the problem persists.
I cannot place myLayout inside OnCreateView so I need a solution where I can use it outside of it.
Your issue stems from a misunderstanding about when and for how long a fragment's view exists.
Currently, you are assigning your MyLayout variable during construction of your fragment.
According to the Android documentation on a Fragment's lifecycle a fragment won't have a view associated with it until after onCreateView is called. Later on in the fragment's lifecycle, the view is destroyed when onDestroyView is called.
So, the fragment's view only lives during the intervening time between onCreateView and onDestroyView. If you call getView before onCreateView is called, or after onDestroyView is called, you will get null.
So, if you want to set listeners on views, do so either from onCreateView or onViewCreated and remove them in onDestroyView.
Also, if you want to hold onto your view via a member variable, set it in onCreateView and null it out in onDestroyView and any place you reference it, make sure to check for null first.
You can declare global variable for your view and initialize with a method.
public class HomeFragment extends Fragment {
private ConstraintLayout MyLayout;
private void init(View v) {
MyLayout = v.findViewById(R.id.my_layout);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_home, container, false);
init(root);
return root;
}
}
Or you can declare your root and you can find your views with root variable:
public class HomeFragment extends Fragment {
private View root;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
root = inflater.inflate(R.layout.fragment_home, container, false);
init()
return root;
}
private void init(){
ConstraintLayout MyLayout = root.findViewById(R.id.my_layout);
.
.
.
}
}
I can also suggest you ViewBinding. It simplifies the syntax.
https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc
But definitely learn about basic Android lifecycle and reasons why you cannot access views before onCreateView.
How are these methods different from each other when trying to get the view?
First:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_a, container, false);
listView = view.findViewById(R.id.listview);
return view;
}
Second:
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
listView = getActivity().findViewById(R.id.listview); }
* some say this is used to get activity views but i used it for getting fragment views(which didn't existed in the activity) and it worked fine.
Third:
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
listView = getView().findViewById(R.id.listview);
}
Three methods are good. In the onCreateView you create the view (!), it's the really first time you can use what you inflated. Then onViewCreated is called with the view you returned in the onCreateView, You can directly use the view given as parameter, it is the same the getView() provides. My advice is to initialise your UI variables here
For onActivityCreated, it is the best place to modify your UI elements. It is called when fragment creation is complete and when fragment is re-attached. There you can use the variables you initialised before, without having to get the activity just for that purpose.
I have 2 fragments each fragments has a different java logic. Where should i put the java logic? if i did put it in the fragments,then error message displays :
cannot resolve method findViewById, Cannont resolve method getApplicationContext
it appear that you did not inflate the view correctly, change your code to be something like this :
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.your_fragment, container, false);
mButton = (Button) view.findViewById(R.id.mButton );
list_content = (ListView) view.findViewById(R.id.list_content);
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(dataAdapter);
return view;
}
and you should use 'getActivity()' method for context not 'This' .
You can find other view's Id's in your fragment like this.
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.your_layout,container,false);
tabLayout = (TabLayout)view.findViewById(R.id.tabs);
return view;
}
When you inflate the view on the oncreateview make a view field like this :
View view = inflater.inflate(R.layout..., container, false);
and return with this view.
After that with this variable you can reach the findViewById, like
view.findViewById
Instead of getApplicationContext you can use getContext in fragment.
Good luck.
I'm starting to learn android app development and currently practicing with simple apps. I'm writing this app that includes a listview and i want to fill it with fake data but, when i use findViewbyId() in my code the app gives me force close BUT when i set the content view to my fragment instead of activity_main i get no force close, but the app shows me an empty list.
This is my code :
package com.example.karen.please;
public class MainActivityFragment extends Fragment {
private ArrayAdapter<String> mForecastAdapter;
public MainActivityFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String[] forecastArray =
{
"sunny",
"cloudy",
"asteroids",
"rainy",
"sunny"
};
List<String> weekforecast = new ArrayList<String>(Arrays.asList(forecastArray));
mForecastAdapter =
new ArrayAdapter<String>(
getActivity(),
R.layout.list_item_forecast,
R.id.list_item_forecast_textview,
weekforecast
);
ListView mylistview = (ListView)container.findViewById(R.id.listview_forecast); //screws upp in this line
mylistview.setAdapter(mForecastAdapter);
return inflater.inflate(R.layout.fragment_main, container, true);
}}
Any help would be appreciated.
You're trying to find a view before you inflate your layout... Try inflating at the top of your method, like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myView = inflater.inflate(R.layout.fragment_main, container, true);
<all the other init code you have>
return myView;
}
First you need inflate your layout...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
...
ListView mylistview = (ListView)rootView.findViewById(R.id.listview_forecast);
...
Before using findViewById you should Create a View variable, use the inflate.. line, use findViewById on the View variable you created, and then return that.
This is what your code should look like:
package com.example.karen.please;
public class MainActivityFragment extends Fragment {
private ArrayAdapter<String> mForecastAdapter;
public MainActivityFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Instead of inflate and return instantly, store it in a variable,
// Then return at the end of the method.
View view = inflater.inflate(R.layout.fragment_main, container, true);
[...]
// Here, use findViewById on the View you have just inflated.
ListView mylistview = (ListView) view.findViewById(R.id.listview_forecast); //screws upp in this line
mylistview.setAdapter(mForecastAdapter);
// Return the view you created on the beginning.
return view;
}}
You should start with a proper tutorial not chaotically adding code that you don't understand. Start reading here:
Creating and Using Fragments
After you understood how it goes then you will see that first you need to inflate the layout that contains the stuff you want to find by id and then by using the view(that defines the layout) you can find the desired view(listview, etc).
ListView my listview = (ListView).findViewById(R.id.listview_forcast);
I think this is how it should be, no container in the code
I am new in android and I have been created simple app which have 3 tabs that I build them with Fragment Activity .
in Activities we can use findViewById method . but Fragments don't have this method . how can I access to my views ?
You can call your getAcivity() method within your fragment class to call the context of your activity that is bounded in it and after you can call findViewById();
sample:
public void onViewCreated()
TextView txSample = (TextView)getView().findViewById(R.id.yourid);
TextView tv;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_simple_lights, container, false);
tv = (TextView) rootView.findViewById(R.id.yourid);
return load;
}
You would better do all the view-related operations in onCreateView() and all the functional operations in onActivityCreated()