I want to refresh the fragment on a button click - i.e, destroy the fragment and force recall on onCreateView() method. However, it keeps crashing because of a GRRRR NullPointerException on the line fragment.getFragmentManager().findFragmentByTag("Frag1");
This is my code:
import android.app.ProgressDialog;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Toast;
public class UserListRecycler extends Fragment {
RecyclerView recyclerView;
static UserAdapter adapter;
RecyclerView.LayoutManager layoutManager;
ArrayList<UserInfo> list;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.userlistGUI, container, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.reUsers);
recyclerView.setHasFixedSize(true);
list = new ArrayList<UserInfo>();
// Instantiate new adapter here
adapter = new MusicRecyclerAdapter(list);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
// Sets the adapter here
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
return rootView;
}
#Override
public void onStart() {
super.onStart();
populateRecyclerList();
}
public void populateList(){
PopulateUsers userList = new PopulateUsers(list, adapter, recyclerView);
userList.execute();
}
public void recallFragment(){
Fragment fragment = null;
fragment.getFragmentManager().findFragmentByTag("TabOne");
getFragmentManager().beginTransaction()
.detach(fragment)
.attach(fragment)
.commit();
}
}
It is the recallFragment() method that is causing the issue. I want to recall on onCreateView() as that would physically refresh the fragment and redisplay the recyclerview. It is getting NullPointerException on fragment.getFragmentManager().findFragmentByTag("TabOne");. This is my stack trace:
java.lang.NullPointerException
at lukazs.usersapp.UserListRecycler.recallFragment()(TabOne.java:160)
at lukazs.usersapp.UserListRecycler$RecommendUser.onPostExecute(TabOne.java:300)
at lukazs.usersapp.UserListRecycler$RecommendUser.onPostExecute(TabOne.java:306)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
This is my onCreateView() method:
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.userlistGUI, container, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.reUsers);
recyclerView.setHasFixedSize(true);
list = new ArrayList<UserInfo>();
// Instantiate new adapter here
adapter = new MusicRecyclerAdapter(list);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
// Sets the adapter here
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
return rootView;
}
UPDATED XML:
<?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"
android:id="#+id/rLayouts">
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/listFrag"
class="lukazs.usersapp.UserListRecycler"/>
<view
android:layout_width="wrap_content"
android:layout_height="wrap_content"
class="android.support.v4.view.ViewPager"
android:id="#+id/viewPager"
android:layout_alignParentStart="true" />
<android.support.v7.widget.RecyclerView
android:id="#+id/usersList"
android:layout_width="match_parent"
android:layout_height="420dp"
android:layout_gravity="center_horizontal|top"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"></android.support.v7.widget.RecyclerView>
</RelativeLayout>
Fragment fragment = new WhatEverFragmentClassYouHave();
You set your fragment to null that is why you have a null exception.
If you're going to detach and then attach something. Just call replace() if you know how to use it.
<fragment
android:id="#+id/article_fragment"
android:layout_weight="2"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.example.android.fragments.ArticleFragment"
/>
For the Refresh
public void recallFragment(){
Fragment fragment = new WhatEverFragmentClass();
getFragmentManager().beginTransaction().replace(R.id.article_fragment,fragment,"MyFragmentTag").commit();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.userlistGUI, container, false);
return rootView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
recyclerView = (RecyclerView) rootView.findViewById(R.id.reUsers);
recyclerView.setHasFixedSize(true);
list = new ArrayList<UserInfo>();
// Instantiate new adapter here
adapter = new MusicRecyclerAdapter(list);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
// Sets the adapter here
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
Instead of detaching and attaching the fragment, you should either have an API in your fragment that tells it to refresh its content, or you should create a new instance of the fragment and replace the existing instance with the new one. Telling the fragment to refresh itself is obviously more efficient than destroying and creating a new fragment.
Related
Can I use a spinner in a fragment? I want to use a spinner in one of the fragment of my activity to set the time on my countdown timer. All the tutorials and videos I've seen uses activity and not fragment and i'm not sure if its the same way to make a spinner in a fragment.
package com.softeng.applockerproject;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.util.concurrent.TimeUnit;
public class page2 extends Fragment {
private static final String TAG = "page2";
private Button btntest;
private TextView timer;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.page2_fragment,container,false);
btntest = (Button) view.findViewById(R.id.button2);
timer = (TextView) view.findViewById(R.id.Timer);
btntest.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
countDownTimer.start();
}
});
return view;
}
//timer part
private CountDownTimer countDownTimer = new CountDownTimer(7200000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
long millis= millisUntilFinished;
String hms= String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis))
//TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
);
timer.setText(hms);
}
#Override
public void onFinish() {
Toast.makeText(getActivity(), "timer stopped",Toast.LENGTH_SHORT).show();
}
};
}
The following is how you'd set a spinner in a fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.manual, container, false);
String [] values =
{"Time at Residence","Under 6 months","6-12 months","1-2 years","2-4 years","4-8 years","8-15 years","Over 15 years",};
Spinner spinner = (Spinner) v.findViewById(R.id.spinner1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this.getActivity(), android.R.layout.simple_spinner_item, values);
adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
spinner.setAdapter(adapter);
return v;
}
Replace the layout files with the ones in which you are using, good luck :)
In terms of adding components, Fragments and Activities behave in a similar way. Fragments can be thought of mini-activities with there own lifecycle methods with some additional methods like onCreateView() and onDestroyView(). You can add a spinner to the fragment in the following way:
Here's the code for Fragment's Java File:
public class MainFragment extends Fragment {
// Default Constructor to instantiate a Fragment object
public MainFragment(){
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main_fragment,container,false);
Spinner spinner = (Spinner) view.findViewById(R.id.spinner);
// Creating an Array Adapter to populate the spinner with the data in the string resources
ArrayAdapter<CharSequence> spinnerAdapter = ArrayAdapter.createFromResource(getContext(),R.array.spinner_choices
,android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(spinnerAdapter);
return view;
}
}
The code for the layout file used for the Fragment is :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Spinner
android:id="#+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"/>
</LinearLayout>
Now to attach the fragment to an activity the code is as follows:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainFragment fragment = new MainFragment();
FragmentManager manager = getSupportFragmentManager();
manager.beginTransaction().add(R.id.fragment_container,fragment).commit();
}
}
The string resource used to provide the ArrayAdapter with data is in the strings.xml file. It is as follows:
<string-array name="spinner_choices">
<item>Deafult Choice</item>
<item>Choice 1</item>
<item>Choice 2</item>
<item>Choice 3</item>
<item>Choice 4</item>
<item>Choice 5</item>
</string-array>
The only difference between adding a spinner item to a Fragment and an Activity is here:
ArrayAdapter<CharSequence> spinnerAdapter = ArrayAdapter.createFromResource(getContext(),R.array.spinner_choices
,android.R.layout.simple_spinner_item);
In an Activity you would have to replace the getContext() with this or ActivityName.this. Rest of the code will be same.
Note: You should write the code to fetch the Spinner from Fragment Layout file in the onCreateView() method only because it is called before the Parent Activity's onCreate() method to ensure that all views are created before the fragment being attached to the parent activity.
Try this in your fragment to set and use spinner
public class ExamsFragment extends Fragment {
private static final String[] spinner_data= {"Term I", "Term II", "Term III"};
View view;
Spinner mySpinner;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_layout, container, false);
setSpinnerData();
mySpinner.setEnabled(true);
//Setting the UI.
return view;
}
method to initialize spinner and set adapter
private void setSpinnerData() {
mySpinner= (Spinner) getActivity().findViewById(R.id.spinner_sp);
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(getActivity(),
R.layout.spinner_item_layout, testTypes);
mySpinner.setAdapter(spinnerAdapter);
}
spinner_item_layout.xml //your spinner item layout
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:gravity="start"
android:paddingLeft="#dimen/padding_10"
android:paddingRight="#dimen/padding_10"
android:paddingTop="#dimen/padding_3"
android:paddingBottom="#dimen/padding_3"
android:background="#color/colorPrimary"
android:textSize="16sp"/>
fragment_layout.xml // put this in your main layout
<Spinner
android:id="#+id/spinner_sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textStyle="bold">
</Spinner>
I have a mainActivity with a fragment container which i set one of three fragments in it.
In each one i have a recycler view and I move to the next fragment on an item click.
The first fragment with the recyclerView is set as follows
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_courses, container, false);
mRootRef = FirebaseDatabase.getInstance().getReference();
mCoursesList = view.findViewById(R.id.courses_rv);
linearLayoutManager = new LinearLayoutManager(getContext());
mCoursesList.setLayoutManager(linearLayoutManager);
mCoursesList.setHasFixedSize(true);
updateView();
return view;
}
the error happens when entering the second fragment which is done as
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_subjects, container, false);
mSubjectsList = view.findViewById(R.id.subjects_rv);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
mSubjectsList.setLayoutManager(layoutManager);
mSubjectsList.setHasFixedSize(true);
Bundle bundle = this.getArguments();
if (bundle != null) {
courseName = bundle.getString( "CourseName");
subjectName = bundle.getString( "SubjectName");
}
// Inflate the layout for this fragment
return view;
}
Apparently they are the same but with the error
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference
The XML files
Main2Activity:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.crash.mathtest.Views.Main2Activity">
<LinearLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
></LinearLayout>
</LinearLayout>
CoureseFragment:
<FrameLayout 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"
tools:context="com.example.crash.mathtest.Views.CoursesFragment">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/courses_rv"
/>
</FrameLayout>
Subjects fragment is the same as courses fragment
Again, this only appears on the second fragment (onCreateView)
The error points to the setLayoutManager(linearLayout)
Can't I make new layouts in the same activity ?
doesn't the new one override the last ?
You don't need to declare twice setLayoutManager() method. You are doing:
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
mSubjectsList.setLayoutManager(layoutManager);
mSubjectsList.setLayoutManager(mSubjectsList.getLayoutManager());
Instead of this, just declare:
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
mSubjectsList.setLayoutManager(layoutManager);
Try to move your recyclerView data from onCreateView to onViewCreated.
Inside onCreateView() method:
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.your_fragment, container, false);
}
Now add your recyclerView content to onViewCreated() method:
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
RecyclerView recyclerView = (RecyclerView) getActivity().findViewById(R.id.recyclerViewId);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
mSubjectsList.setLayoutManager(layoutManager);
}
UPDATE
do this stuff in
onActivityCreated from onCreateView
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
mSubjectsList.setLayoutManager(layoutManager);
mSubjectsList.setHasFixedSize(true);
Bundle bundle = this.getArguments();
if (bundle != null) {
courseName = bundle.getString( "CourseName");
subjectName = bundle.getString( "SubjectName");
}
My login activity needs LoginSuccess where my fragments are loaded there.
LoginActivity.java:
Intent intent = new Intent(LoginActivity.this,LoginSuccess.class);
Bundle bundle = new Bundle()
bundle.putString("first_name",jsonObject.getString("first_name"));
bundle.putString("last_name",jsonObject.getString("last_name"));
bundle.putString("username",jsonObject.getString("username"));
bundle.putString("email",jsonObject.getString("email"));
bundle.putString("mobile",jsonObject.getString("mobile"));
bundle.putString("appointments",jsonObject.getString("appointments"));
intent.putExtras(bundle);
startActivity(intent);
How can I fetch the bundle "appointments" in a fragment? Thanks in advance.
AppointmentsFragment.java:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
super.onCreate(savedInstanceState);
Bundle bundle = getActivity().getIntent().getExtras();
View v = inflater.inflate(R.layout.fragment_appointments, container, false);
String [] datasource = {"appointments", bundle.getString("appointments")};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), R.layout.rowlayout, R.id.txtitem, datasource);
setListAdapter(adapter);
setRetainInstance(true);
Log.d("appointments", bundle.getString("appointments"));
View appointment_date = v.findViewById(R.id.appointment_date);
((TextView)appointment_date).setText(bundle.getString("appointment_date"));
return v;
}
Here's the code for LoginSuccess.java
`public class LoginSuccess extends AppCompatActivity {
Toolbar toolbar;
TabLayout tabLayout;
ViewPager viewPager;
ViewPagerAdapter viewPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_success);
toolbar = (Toolbar)findViewById(R.id.toolBar);
setSupportActionBar(toolbar);
tabLayout = (TabLayout)findViewById(R.id.tabLayout);
viewPager = (ViewPager)findViewById(R.id.viewPager);
viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPagerAdapter.addFragments(new ProfileFragment(), "Profile");
viewPagerAdapter.addFragments(new AppointmentsFragment(), "Appointments");
viewPager.setAdapter(viewPagerAdapter);
tabLayout.setupWithViewPager(viewPager);
}
}`
First open the Fragment by doing this inside your LoginActivity
LoginActivity.class
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import com.example.vostro.myapplication.fragments.FragmentDemo;
public class LoginActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_main);
Bundle bundle = new Bundle();
bundle.putString("first_name",jsonObject.getString("first_name"));
bundle.putString("last_name",jsonObject.getString("last_name"));
bundle.putString("username",jsonObject.getString("username"));
bundle.putString("email",jsonObject.getString("email"));
bundle.putString("mobile",jsonObject.getString("mobile"));
bundle.putString("appointments",jsonObject.getString("appointments"));
FragmentDemo fragment = new FragmentDemo();
fragment.setArguments(bundle);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.navigation_container, fragment);
fragmentTransaction.commit();
}
}
Then inside your new Fragment get the data by doing this
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.vostro.myapplication.R;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class FragmentDemo extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_demo, null);
String jsonArrayAppointments = getArguments().getString("appointments");
try {
JSONArray jsonArray = new JSONArray(jsonArrayAppointments);
for (int i=0; i<jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String yourRequiredField = jsonObject.getString("yourRequiredField");
}
} catch (JSONException e) {
e.printStackTrace();
}
return rootView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
login_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#2196F3"
android:minHeight="?attr/actionBarSize"></android.support.v7.widget.Toolbar>
<TextView
android:id="#+id/tv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:textSize="20sp"
android:gravity="center"
android:text="#string/text"/>
<!-- This will hold your Fragment -->
<LinearLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"></LinearLayout>
</LinearLayout>
If you want to sent data from activity to fragment then you have to use this code:
Bundle bundle = new Bundle()
bundle.putString("first_name",jsonObject.getString("first_name"));
bundle.putString("last_name",jsonObject.getString("last_name"));
bundle.putString("username",jsonObject.getString("username"));
bundle.putString("email",jsonObject.getString("email"));
bundle.putString("mobile",jsonObject.getString("mobile"));
bundle.putString("appointments",jsonObject.getString("appointments"));
YourFragmentClass yfc = new YourFragmentClass();
yfc.setArguments(bundle);
Fetch value from onCreateView() method in your "YourFragmentClass" like this:
String strappointments = getArguments().getString("appointments");
While adding the fragment follow this
I hope you are adding the fragment in LoginSuccess Activity.So in that activity get the arguments like
Bundle args = getIntent().getExtras();
While instantiating a fragment, follow this
Fragment mainFragment = new MyFragment();
mainFragment.setArguments(args)
getFragmentManager().beginTransaction().add(R.id.fragment_holder,mainFragment,"my_fragment").commit();
In your fragment get your arguments using getArguments() method
In your fragment use the following snippet to get the object of json.
Bundle args = getArguments();
String appointments = args.getString("appointments");
JSONParser parser = new JSONParser();
try{
Object obj = parser.parse(appointments);
JSONArray array = (JSONArray)obj;
for(Object appointment : array)
{
appObject = (JSONObject) appointment;
/* for getting data here like appointment status use,*/
String status = appObject.get("appointment_status");
}
I have a recyclerview in fragment. When I run the app i get the following message.
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setHasFixedSize(boolean)' on a null object reference
I have searched and found people with similar problems, but it hasn't helped me. The recyclerview is null in the fragment. Here is my code:
I call the fragment from the main activity here on the onCreate:
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
trans.add(R.id.recycle_view_container, recyclerViewFragment, RECYCLER_FRAGMENT);
trans.commit();
trans.show(recyclerViewFragment);
Here is my recyclerfragment:
public class RecyclerViewFragment extends Fragment
private RecyclerView recyclerView;
private LinearLayoutManager layoutManager;
static SQLiteDatabase db;
ArrayList<MyMarker> markerArrayList;
private MyAdapter adapter;
private String TAG = "recyclerview fragment";
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_recycler_view, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view_in_fragment);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
adapter = new MyAdapter(markerArrayList, this);
recyclerView.setAdapter(adapter);
return view;
Here is my xml for the recyclerview Fragment:
<RelativeLayout 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"
tools:context=".RecyclerView.RecyclerViewFragment"
android:background="#a6ffffff">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view_in_fragment"
android:scrollbars="vertical"
android:layout_below="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
Thanks very much if you can help.
You should use onViewCreated() to access the views
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view_in_fragment);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
adapter = new MyAdapter(markerArrayList, this);
recyclerView.setAdapter(adapter);
}
Hi i am using view pager indicator with three fragments and in one of the i have a list view that show the content of my SQLite Database but when a add data to my table the list view doesn't show he new data that i have added here is my code:
public class caleryhistory extends SherlockListFragment {
List<calery_lagari> Calery_lagari;
calery_lagari_SQLiteData data;
ArrayAdapter<calery_lagari> adapter;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.calery_history, null);
data = new calery_lagari_SQLiteData(getActivity());
data.open();
Calery_lagari = data.findall();
adapter = new ArrayAdapter<calery_lagari>(getActivity(),
R.layout.listback_layout, Calery_lagari);
adapter.notifyDataSetChanged();
setListAdapter(adapter);
adapter.notifyDataSetChanged();
return v;
}
so any help?
Thanks in advance! :)
Update
import java.util.List;
import mr.chag.va.lagar.R;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.actionbarsherlock.app.SherlockListFragment;
public class caleryhistory extends SherlockListFragment {
List<calery_lagari> Calery_lagari;
calery_lagari_SQLiteData data;
ArrayAdapter<calery_lagari> adapter;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.calery_history, null);
return v;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
data = new calery_lagari_SQLiteData(getActivity());
data.open();
Calery_lagari = data.findall();
adapter = new ArrayAdapter<calery_lagari>(getActivity(),
R.layout.listback_layout, Calery_lagari);
adapter.notifyDataSetChanged();
ListView listView = (ListView)view.findViewById(android.R.id.list);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
super.onViewCreated(view, savedInstanceState);
}
}
my layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="clear"
android:text="clear all" />
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
The best way when extending SherlockListFragments is to have onCreateView return the the inflated view, then override onViewCreated. And put your code that changes your view in there.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle b){
return inflater.inflate(R.layout.calery_history, null);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
data = new calery_lagari_SQLiteData(getActivity());
data.open();
Calery_lagari = data.findall();
adapter = new ArrayAdapter<calery_lagari>(getActivity(), view.R.layout.listback_layout, Calery_lagari);
adapter.notifyDataSetChanged();
setListAdapter(adapter);
adapter.notifyDataSetChanged();
}
First problem is that you set adapter in onCreateView. In onCreateView list view is not created yet. Second you need to set adapter to correct list view. Because you override oncreateview you can't use setListAdapter because it's referring to list view from default viet. Try this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
return inflater.inflate(R.layout.calery_history, null);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
data = new calery_lagari_SQLiteData(getActivity());
data.open();
Calery_lagari = data.findall();
adapter = new ArrayAdapter<calery_lagari>(getActivity(),
view.R.layout.listback_layout, Calery_lagari);
ListView listView = (ListView)view.findViewById(R.id.YOUR_LISTVIEW_ID);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
You cannot call setListAdapter at this point, as the view is not yet set.
You need to wait until onViewCreated.