I tries to set up a listView in a fragment but my app crashes,tried to search on the internet but couldn't find an answer.
Java Source code:
public static class FragmentFind extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
String [] cinemas={
"Cinema 1","Cinema 2","Cinema 3"
};
ArrayAdapter<String> adapter=new ArrayAdapter<>(getActivity(),android.R.layout.simple_list_item_1,cinemas);
ListView list=(ListView) getActivity().findViewById(R.id.cinema_list);
list.setAdapter(adapter);
return inflater.inflate(R.layout.fragment_find,container,false);
}
}
Android XML layout for the fragment
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cinema_list"
android:layout_alignParentTop="true"/>
</RelativeLayout>
Thanks.
Because your ListView is Null. As your Listview is part of Fragment layout you have to call findViewById() on view inflated by that fragment layout file.
So try like,
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_find,container,false);
String [] cinemas={"Cinema 1","Cinema 2","Cinema 3"};
ArrayAdapter<String> adapter=new ArrayAdapter<>(getActivity(),android.R.layout.simple_list_item_1,cinemas);
ListView list=(ListView) view.findViewById(R.id.cinema_list);
list.setAdapter(adapter);
return view;
}
I believe the error is probably a null exception. The main differences that I saw from my fragment from yours.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.whatever, container, false);
View testview= (View) v.findViewById(R.id.id);
return v;
}
I suggest you to look at the Difference between onCreateView() and onViewCreated() in Fragment.Even tough you can do do the same thing in onCreateView() method, it is best to do the setting of the Adapter in the onViewCreated() method
This is where the issue is,
ListView list=(ListView) getActivity().findViewById(R.id.cinema_list);
Here is how I would do it.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_find,container,false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState){
String [] cinemas={
"Cinema 1","Cinema 2","Cinema 3"
};
ArrayAdapter<String> adapter=new ArrayAdapter<>(getActivity(),android.R.layout.simple_list_item_1,cinemas);
ListView list=(ListView) view.findViewById(R.id.cinema_list);
list.setAdapter(adapter);
}
Your activity does not have the ListView R.id.cinema_list when the app tries to search for it by: getActivity().findViewById(R.id.cinema_list);
So you should better search the ListView within inflated view by:
View view = inflater.inflate(R.layout.fragment_find,container,false);
ListView myList = (ListView)view.findViewById(R.id.cinema_list);
And then set the adapter and return the view .
You are lucky that your app crashed. It is also possible that getActivity().findViewById(R.id.cinema_list) could find a ListView if your activity layout has a ListView with R.id.cinema_list. I am telling this because it is obvious that you will have only one ListView with such specific id, but sometimes people use common ids such as listView1. So you better be careful.
Replace this:
ListView list=(ListView) getActivity().findViewById(R.id.cinema_list);
with this:
ListView list = (ListView) view.findViewById(R.id.cinema_list);
Related
I am following a tutorial on Udemy using RecyclerView using Fragments. Everything works fine until this line 44 recyclerView = view.findViewById(R.id.rcl)
I searched a lot on internet but did not get any solution related to this. I debugged the code and view was null. Either there was a problem in that tutorial or only i am having the problem.
1- Fragment_list.xml
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ListFrag">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rcl"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
2- ListFrag.jave
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_list, container, false);
// Inflate the layout for this fragment
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
recyclerView = view.findViewById(R.id.rcl);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this.getActivity());
recyclerView.setLayoutManager(layoutManager);
adapter = new PersonAdapter(this.getActivity(), ApplicationClass.people);
recyclerView.setAdapter(adapter);
}
3- This is the Error :
Error :
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
at com.example.recyclerfragments.ListFrag.onActivityCreated(ListFrag.java:44)
at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2619)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:904)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2659)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1391)
at android.app.Activity.performStart(Activity.java:7214)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3189)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:185)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:170)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:147)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:73)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2031)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7083)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:536)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:928)
Error is here:
recyclerView = view.findViewById(R.id.rcl);
view is null.
Try to replace by:
private RecyclerView mRecyclerView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_list, container, false);
// Add this.. Here, view won't be null
recyclerView = view.findViewById(R.id.rcl);
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// recyclerView = view.findViewById(R.id.rcl); --> Remove this from here.
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this.getActivity());
recyclerView.setLayoutManager(layoutManager);
adapter = new PersonAdapter(this.getActivity(), ApplicationClass.people);
recyclerView.setAdapter(adapter);
}
Another options is replacing view by getActivity():
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
recyclerView = getActivity().findViewById(R.id.rcl);
....
}
put your code in onViewCreated() this is for kotlin, for java just override the method and put your code in it
make sure your view object is globally declared so it will not be null after view created
like this:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
recyclerView = view.findViewById(R.id.rcl)
recyclerView.setHasFixedSize(true)
layoutManager = LinearLayoutManager(this.activity)
recyclerView.setLayoutManager(layoutManager)
adapter = PersonAdapter(this.activity, ApplicationClass.people)
recyclerView.setAdapter(adapter)
}
You are initializing view in onCreateView but using view recyclerView = view.findViewById(R.id.rcl); in onActivityCreated, thats why you are getting error.
There are multiple ways to resolve this error:
First One:
private RecyclerView mRecyclerView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_list, container, false);
recyclerView = view.findViewById(R.id.rcl);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this.getActivity());
recyclerView.setLayoutManager(layoutManager);
adapter = new PersonAdapter(this.getActivity(), ApplicationClass.people);
recyclerView.setAdapter(adapter);
return view;
}
2nd :
private RecyclerView mRecyclerView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_list, container, false);
recyclerView = view.findViewById(R.id.rcl);
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this.getActivity());
recyclerView.setLayoutManager(layoutManager);
adapter = new PersonAdapter(this.getActivity(), ApplicationClass.people);
recyclerView.setAdapter(adapter);
}
I am on creating an application and at the moment, I have created two fragments which is going to be a "navigation" sort of thing. On the second of the two fragments, I have put a spinner on which is where the user would be able to select a particular option. All of the spinners have unique ID's but the findViewById method cannot be resolved
All of the strings are in the strings xml file and when I tried this spinner in my testing app, it worked
public class Frag2 extends Fragment implements AdapterView.OnItemSelectedListener{
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.frag2_layout, container, false);
Spinner spinner = findViewById (R.id.spinner1);
ArrayAdapter.createFromResource(getActivity(), R.array.insulin, android.R.layout.simple_spinner_item);
ArrayAdapter<CharSequence> adapter;
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this);
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String text = parent.getItemAtPosition(position).toString();
Toast.makeText(parent.getContext(), text, Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
The spinner should work within the one fragment and then I would like to have it another few times
This is fragment you're dealing with, not an activity. Fragment doesn't extend Context or View classes and does not have this findViewById method.
What you should do is to move your code from onCreateView to onViewCreated which gets a reference to the root view as a parameter. Then use the same method but with that view, as below:
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
Spinner spinner = view.findViewById(R.id.spinner1);
...
}
Another thing you may do is replacing:
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.frag2_layout, container, false);
Spinner spinner = findViewById (R.id.spinner1);
// I'm not sure how you didn't see all errors when writing code after a return statement.
...
}
With:
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag2_layout, container, false);
Spinner spinner = view.findViewById(R.id.spinner1);
...
return view; // after finishing all logic.
}
UPDATE:
Didn't see that there is also a problem with the ArrayAdapter.
As mentioned in Csongi77 answer, you need to to instantiate the adapter properly. Again, the fragment cannot use as context, you must use the containing activity for that:
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getActivity(), R.array.insulin, android.R.layout.simple_spinner_item);
ArrayAdapter.createFromResource creates and returns a new adapter and currently you just disposing it immediately by not saving its reference.
I think first you should instantiate adapter like this: ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getActivity(), R.array.insulin, android.R.layout.simple_spinner_item); please let me know if it works. Regards, Csongi
I've got a problem. For school project I have to create app in Android Studio with few activities so i decided to add Navigation Drawer, but when i try to create simple calculator to app i can't even reference button or textview. This is code for activity where I want to create calculator. Also I have to add Map Activity and SQLite Database.
public class Calculator_main extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootview = inflater.inflate(R.layout.calculator, container, false);
return rootview;
}
}
Use rootView to find your item when referencing in a Fragment:
public class Calculator_main extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootview = inflater.inflate(R.layout.calculator, container, false);
//Notice the TextView being referenced with rootView in front of the findViewById statement
TextView namefield = (TextView) rootView.findViewById(R.id.namefield);
return rootview;
}
}
You need to do this when using Fragment, as this is the only way your app can reference an item in your Fragment's XML view
This is however not necessary in an Activity and should not be confused with the method of referencing in a Fragment
I'm new to android programming. I want to write an android program which contains two fragments. Designs' will be same but I can't write layout file twice as it has a lot of widgets so is there a way to handle this?
If I copy xml file widget ids' stay same and I can't reach them in my java class...
Lets assume you have fragment_container.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fraContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
What you need to do is to replace this container with one of the fragments in your program like this for example:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_container);
if (findViewById(R.id.fraContainer) != null)
{
MyFragmentA myFragment = new MyFragmentA();
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fraContainer, myFragment)
.commit();
}
}
This will replace the fragment layout (container) with the fragment you want.
Now lets examine MyFragmentA, and MyFragmentB
public class MyFragmentA extends Fragment {
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_both, container, false);
TextView x = (TextView)view.findViewById(R.id.textView);
x.setText("I am fragment A");
return view;
}
...
And the second fragment
public class MyFragmentB extends Fragment {
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_both, container, false);
TextView x = (TextView)view.findViewById(R.id.textView);
x.setText("I am fragment B");
return view;
}
...
Both inflate the same fragment_both.xml, and both use the same TextView with the same ID, by referring to the view object!
I hope that helps you understand it.
You can simply use the same xml file in more fragments, like this:
Fragment A
public class FragmentA extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.your_layout, container, false);
...
return v;
}
}
Fragment B
public class FragmentB extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.your_layout, container, false);
...
return v;
}
}
my name is Augusto, I'm developing a Messaging/Social app for Android on Android Studio and I implemented SlidingTabLayout (com.google.samples.apps.iosched.ui.widget) with 2 tabs (Chats and Friends ).
I wish to know how to access the views inside the Tabs' xml files on my activity.
I have:
MainActivity.class with activity_main.xml as contentview and the tabs's layouts(friendsview.xml and chatsview.xml) for the tabs.
I want to access tabs' layouts view (e.g: EditText, ImageView) from MainActivity.class, How do I "import" them to the activity?
Thanks!
SlidingTabLayout it's only a layout. To manage content use fragments with FragmentPagerAdapter for your tabs.
Here (link) is nice tutorial for you.
If you follow this example tutorial, you will have
public class Tab1 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.tab_1,container,false);
return v;
}
}
and to access EditText and other widget inside tab, you need to have reference from view, so change above code to:
public class Tab1 extends Fragment {
private EditText editText;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.chatsview,container,false);
editText = v.findViewById(R.id.YOUR_EDIT_TEXT_ID);
return v;
}
}