I put a listView in a fragment and a fragment in activiti_main.xml and got a json file from the volley library and then parsed that json file and displayed it with listView and the following code works fine.
MainActivity.java
public class MainActivity extends AppCompatActivity {
public ListView listView;
private RequestQueue queue;
private ArrayList<Category> categories;
public CategoryAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
queue = Volley.newRequestQueue(MainActivity.this);
String url = "***";
StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
CategoriesJsonParser jsonParser = new CategoriesJsonParser();
try {
categories = jsonParser.parseJson(response);
adapter = new CategoryAdapter(getApplicationContext(), categories, R.layout.category_item);
listView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(request);
}
}
But when I write the same code inside the fragment
What should I do when the program closes?
BlankFragment.java
public class BlankFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
public ListView listView;
private RequestQueue queue;
private ArrayList<Category> categories;
public CategoryAdapter adapter;
public BlankFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment BlankFragment.
*/
// TODO: Rename and change types and number of parameters
public static BlankFragment newInstance(String param1, String param2) {
BlankFragment fragment = new BlankFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
listView = getActivity().findViewById(R.id.listview);
queue = Volley.newRequestQueue(getActivity());
String url = "https://dikushop.ir/android/category/getCategories.php";
StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
CategoriesJsonParser jsonParser = new CategoriesJsonParser();
try {
categories = jsonParser.parseJson(response);
adapter = new CategoryAdapter(getContext(), categories, R.layout.category_item);
// listView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(request);
listView.setAdapter(adapter);
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank, container, false);
}
firstly,delete below unnecessary part from fragment code
`
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment BlankFragment.
*/
// TODO: Rename and change types and number of parameters
public static BlankFragment newInstance(String param1, String param2) {
BlankFragment fragment = new BlankFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
`
and add this in onCreateView
View view = inflater.inflate(your xml which contain list view eg. R.layout.list, container, false);
and atlast
//return view which you inflated
return view;
Related
I'm new to android coding, I've tried all the possible solution here and on YouTube but still struggling. I just want how to match the data from a dialog of a fragment to another fragment upon pressing the button. we're working on a simple project. :)
Here is what we want to do.Kindly watch this link:
https://imgur.com/tGdWcfq
We want to change the name that will match the dialog upon clicking the "set parameters' button
here's what we found online the difference is we have a dialog button
https://www.youtube.com/watch?v=ZXoGG2XTjzU
https://www.youtube.com/watch?v=69C1ljfDvl0
Here are the codes
RecyclerViewAdapter.java
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {
Context mContext;
List<specieList> mData;
Dialog myDialog;
public RecyclerViewAdapter(Context mContext, List<specieList> mData) {
this.mContext = mContext;
this.mData = mData;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
Button b;
v = LayoutInflater.from(mContext).inflate(R.layout.row,parent,false);
final MyViewHolder vHolder = new MyViewHolder(v);
myDialog = new Dialog(mContext);
myDialog.setContentView(R.layout.fishpop);
myDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
b = myDialog.findViewById(R.id.toasted);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
TextView toastfish = (TextView) myDialog.findViewById(R.id.dialog_fish_id);
Toast.makeText(mContext,"Parameters are now set for " + toastfish.getText().toString(), Toast.LENGTH_SHORT).show();
// here upon clicking this button click we want to match the details in this dialog to another tab. Kindly watch the link above :)
}
});
vHolder.fish_choices.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
TextView dialog_fish = (TextView) myDialog.findViewById(R.id.dialog_fish_id);
TextView dialog_sciname = (TextView) myDialog.findViewById(R.id.dialog_sciname_id);
ImageView dialog_image = (ImageView) myDialog.findViewById(R.id.dialog_image_id);
dialog_fish.setText(mData.get(vHolder.getAdapterPosition()).getFish());
dialog_sciname.setText(mData.get(vHolder.getAdapterPosition()).getSciname());
dialog_image.setImageResource(mData.get(vHolder.getAdapterPosition()).getImage());
myDialog.show();
}
});
return vHolder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.tv_fish.setText(mData.get(position).getFish());
holder.tv_sciname.setText(mData.get(position).getSciname());
holder.img.setImageResource(mData.get(position).getImage());
}
#Override
public int getItemCount() {
return mData.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
private LinearLayout fish_choices;
private TextView tv_fish;
private TextView tv_sciname;
private ImageView img;
public MyViewHolder(View itemView) {
super(itemView);
fish_choices = (LinearLayout) itemView.findViewById(R.id.choices);
tv_fish = (TextView) itemView.findViewById(R.id.textView1);
tv_sciname = (TextView) itemView.findViewById(R.id.textView2);
img = (ImageView) itemView.findViewById(R.id.image);
}
}
}
Code for overview tab(This tab we want to match the content)
public class overview extends Fragment {
View v2;
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public overview() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment overview.
*/
// TODO: Rename and change types and number of parameters
public static overview newInstance(String param1, String param2) {
overview fragment = new overview();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
v2 = inflater.inflate(R.layout.fragment_overview, container, false);
Calendar calendar = Calendar.getInstance();
SimpleDateFormat time = new SimpleDateFormat("HH:mm:ss");
String currentDate = DateFormat.getDateInstance(DateFormat.FULL).format(calendar.getTime());
String currentTime = time.format(calendar.getTime());
TextView textViewDate =(TextView) v2.findViewById(R.id.date_id);
textViewDate.setText(currentDate);
TextView textViewTime =(TextView) v2.findViewById(R.id.time_id);
textViewTime.setText(currentTime);
return v2;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
Code for Specie tab (this tab we want to refer)
public class specie extends Fragment {
View v;
private RecyclerView myrecyclerview;
private List<specieList> lstspecie;
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public specie() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment specie.
*/
// TODO: Rename and change types and number of parameters
public static specie newInstance(String param1, String param2) {
specie fragment = new specie();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lstspecie = new ArrayList<>();
lstspecie.add(new specieList("Nile Tilapia", "Oreochromis niloticus", R.drawable.tilapia));
lstspecie.add(new specieList("Ayungin (Silver Perch)", "Bidyanus bidyanus", R.drawable.ayungin));
lstspecie.add(new specieList("Sugpo (Tiger Prawn)", "Penaeus monodon", R.drawable.hipon));
lstspecie.add(new specieList("Hito (Catfish)", "Siluriformes", R.drawable.hito));
lstspecie.add(new specieList("Giant Gourami", "Osphronemus goramy", R.drawable.giant));
lstspecie.add(new specieList("Bangus (Milkfish)", "Chanos chanos", R.drawable.bangus));
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
v = inflater.inflate(R.layout.fragment_specie, container, false);
myrecyclerview = (RecyclerView)v.findViewById(R.id.specie_recycleview);
RecyclerViewAdapter recyclerAdapter = new RecyclerViewAdapter(getContext(), lstspecie);
myrecyclerview.setLayoutManager(new LinearLayoutManager(getActivity()));
myrecyclerview.setAdapter(recyclerAdapter);
return v;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
Thank you!
Using object oriented Approach
You can write a function in your activity and you can call a fragment's method from it, as you have your Fragment's reference in your Activity when you initialized it like
In Your Activity
class yourActivity ... {
// your other methods
public void callFragmentMethod(String params) {
// here call your fragment's method
fragment.method(params);
}
}
In your Fragment now
class yourFragment ... {
// your other methods
public void method(String params) {
// here call your fragment's method
here do whatever you want to do it with params
}
}
Now you can call your Activity's method either from another fragment or from Adapter, whatever you want
From Fragment you can call like
((yourActivity)getActivity()).callFragmentMethod(params);
From Adapter
((yourActivity)context).callFragmentMethod(params);
Call below method on your button click..
public void replaceFragment(Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction =
fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frameContainer, fragment);
fragmentTransaction.addToBackStack(fragment.toString());
fragmentTransaction.commit();
}
pass frameContainer in constructor of your Adapter like..
new RecyclerViewAdapter(context, list, R.id.frameContainer);
I have read several threads on approaches to save the position of a RecyclerView. I have implemented the below, however it does not appear to be saving the position on either screen rotation or back navigation, it simply loads back to the top of the RecyclerView:
public class FeedFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private static final String POLL_QUESTION = "POLL_QUESTION";
private static final String POLL_IMAGE_URL = "POLL_IMAGE_URL";
private static final String FILTER_ACTION = "UPDATE_WIDGET";
private static final String POLL_ID = "POLL_ID";
private static final String RECYCLERVIEW_STATE = "Recyclerview_State";
private Parcelable mRecyclerViewState;
private static Bundle mRecyclerViewBundle;
private MyReceiver myReceiver;
#BindView(R.id.list)
RecyclerView mRecyclerview;
private SharedPreferences mPrefs;
private SharedPreferences.Editor editor;
private DatabaseReference mBaseRef;
private DatabaseReference mPollsRef;
private LinearLayoutManager mLayoutManager;
private FirebaseRecyclerAdapter<Poll, PollHolder> mFireAdapter;
private OnFragmentInteractionListener mListener;
public FeedFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment FeedFragment.
*/
// TODO: Rename and change types and number of parameters
public static FeedFragment newInstance(String param1, String param2) {
FeedFragment fragment = new FeedFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_poll_feed, container, false);
ButterKnife.bind(this, v);
mPrefs = getActivity().getSharedPreferences("MyPrefs", Context.MODE_PRIVATE);
editor = mPrefs.edit();
if (savedInstanceState != null) {
mRecyclerViewState = savedInstanceState.getParcelable(RECYCLERVIEW_STATE);
}
mRecyclerview.getItemAnimator().setChangeDuration(0);
mLayoutManager = new LinearLayoutManager(getContext());
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mLayoutManager.setReverseLayout(true);
mLayoutManager.setStackFromEnd(true);
mRecyclerview.setSaveEnabled(true);
mRecyclerview.setLayoutManager(mLayoutManager);
setReceiver();
return v;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
// #Override
// public void onSaveInstanceState(#NonNull Bundle outState) {
// super.onSaveInstanceState(outState);
// mRecyclerViewState = mLayoutManager.onSaveInstanceState();
// outState.putParcelable(RECYCLERVIEW_STATE, mRecyclerViewState);
// }
//
//
// #Override
// public void onViewStateRestored(#Nullable Bundle savedInstanceState) {
// super.onViewStateRestored(savedInstanceState);
// if (savedInstanceState != null){
// mRecyclerViewState = savedInstanceState.getParcelable(RECYCLERVIEW_STATE);
// }
// }
#Override
public void onSaveInstanceState(#NonNull Bundle outState) {
super.onSaveInstanceState(outState);
mRecyclerViewState = mLayoutManager.onSaveInstanceState();
outState.putParcelable(RECYCLERVIEW_STATE, mRecyclerViewState);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null){
mRecyclerViewState = savedInstanceState.getParcelable(RECYCLERVIEW_STATE);
}
}
#Override
public void onResume() {
super.onResume();
if (mRecyclerViewState != null){
mLayoutManager.onRestoreInstanceState(mRecyclerViewState);
}
}
#Override
public void onStart() {
super.onStart();
Query query = FirebaseDatabase.getInstance()
.getReference()
.child("Polls");
FirebaseRecyclerOptions<Poll> options = new FirebaseRecyclerOptions.Builder<Poll>()
.setQuery(query, Poll.class)
.build();
mFireAdapter = new FirebaseRecyclerAdapter<Poll, PollHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull final PollHolder holder, int position, #NonNull Poll model) {
holder.mPollQuestion.setText(model.getQuestion());
String voteCount = String.valueOf(model.getVote_count());
//Update shared prefs with latest question
editor.putString(POLL_QUESTION, model.getQuestion());
editor.putString(POLL_IMAGE_URL, model.getImage_URL());
editor.apply();
//TODO: Investigate formatting of vote count for thousands
holder.mVoteCount.setText(voteCount);
Picasso.get()
.load(model.getImage_URL())
.fit()
.into(holder.mPollImage);
//TODO: Cannot understand how to utilize IntentService to update widget
//TODO: Followed this tutorial: https://www.journaldev.com/20735/android-intentservice-broadcastreceiver
Intent intent = new Intent(getContext(), MyService.class);
intent.putExtra(POLL_QUESTION, model.getQuestion());
intent.putExtra(POLL_IMAGE_URL, model.getImage_URL());
getActivity().startService(intent);
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String pollID = mFireAdapter.getRef(holder.getAdapterPosition()).getKey();
if (getActivity().findViewById(R.id.two_pane_constraint_layout) != null & getActivity().getApplication().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
FragmentManager fm = getActivity().getSupportFragmentManager();
PollFragment pollFragment = PollFragment.newInstance(pollID);
fm.beginTransaction()
.replace(R.id.poll_fragment, pollFragment)
.commit();
} else {
Intent i = new Intent(getActivity().getApplicationContext(), PollHostActivity.class);
i.putExtra(POLL_ID, pollID);
startActivity(i);
}
}
});
}
#Override
public PollHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.latest_item, parent, false);
return new PollHolder(v);
}
};
mRecyclerview.setAdapter(mFireAdapter);
scrollToPosition();
mFireAdapter.startListening();
}
public static class PollHolder extends RecyclerView.ViewHolder {
TextView mPollQuestion;
TextView mVoteCount;
ImageView mPollImage;
View mView;
String mTag;
public PollHolder(View itemView) {
super(itemView);
mPollQuestion = itemView.findViewById(R.id.latest_item_question);
mPollImage = itemView.findViewById(R.id.pollThumbNailImage);
mVoteCount = itemView.findViewById(R.id.latest_item_poll_count);
this.mView = itemView;
}
public void setTag(String tag) {
this.mTag = tag;
}
public View getViewByTag(String tag) {
return mView;
}
}
private void setReceiver() {
myReceiver = new MyReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(FILTER_ACTION);
// LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, intentFilter);
}
private void scrollToPosition() {
mFireAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
int pollCount = mFireAdapter.getItemCount();
int lastVisiblePosition = mLayoutManager.findLastCompletelyVisibleItemPosition();
// If the recycler view is initially being loaded or the user is at the bottom of the list, scroll
// to the bottom of the list to show the newly added message.
if (lastVisiblePosition == -1 ||
(positionStart >= (pollCount - 1) && lastVisiblePosition == (positionStart - 1))) {
mRecyclerview.scrollToPosition(positionStart);
}
}
});
}
private class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String poll_Question = intent.getStringExtra("broadcastMessage");
//TODO: Update Widget - used answer from https://stackoverflow.com/questions/3455123/programmatically-update-widget-from-activity-service-receiver
int[] ids = AppWidgetManager.getInstance(getContext()).getAppWidgetIds(new ComponentName(getContext(), PollWidgetProvider.class));
PollWidgetProvider pollWidgetProvider = new PollWidgetProvider();
pollWidgetProvider.onUpdate(getContext(), AppWidgetManager.getInstance(getContext()), ids);
}
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
EDIT:
I am trying to save within a Fragment, that is attached to a host Activity. I have some RecyclerView functionality coded to on.Start(), which may be overriding the methods below.
I also feel I need to make a call to onPause() somewhere since the RecyclerView is located inside a Fragment.
Full code available:https://github.com/troy21688/LiveVotingUdacity
I have an activity which has three tabs. One fragment for each tabs. In the xml of the fragment layout I have a listview. I need to initialize this list view and populate it with data from the firebase. How can I do that?
My activity code is
public class AccountActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_account);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(AccountActivity.this,AddLeaveActivity.class));
}
});
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
public PlaceholderFragment() {
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if(getArguments().getInt(ARG_SECTION_NUMBER) == 1){
View rootView = inflater.inflate(R.layout.fragment_today, container, false);
return rootView;
} else if(getArguments().getInt(ARG_SECTION_NUMBER) == 2){
View rootView = inflater.inflate(R.layout.fragment_tomorrow, container, false);
return rootView;
} else {
View rootView = inflater.inflate(R.layout.fragment_dayafter, container, false);
return rootView;
}
//View rootView = inflater.inflate(R.layout.activity_account, container, false);
//TextView textView = (TextView) rootView.findViewById(R.id.section_label);
//textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
//return rootView;
}
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
return PlaceholderFragment.newInstance(position + 1);
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "TODAY";
case 1:
return "TOMORROW";
case 2:
return "DAY AFTER";
}
return null;
}
}
}
and my fragment.java is
public class TodayFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public TodayFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment TodayFragment.
*/
// TODO: Rename and change types and number of parameters
public static TodayFragment newInstance(String param1, String param2) {
TodayFragment fragment = new TodayFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference databaseReference = firebaseDatabase.getReference();
DatabaseReference childRef;
ListView listView;
TextView textView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
textView = (TextView) getView().findViewById(R.id.todayfragmentheader);
textView.setText("Inside onCreate Fragment1");
listView = (ListView) getView().findViewById(R.id.listview);
displaylistview("20170130");
}
private void displaylistview(String str){
childRef = databaseReference.child(str);
// //databaseReference = firebaseDatabase.getReferenceFromUrl(leavedate);
FirebaseListAdapter<Leave> firebaseListAdapter = new FirebaseListAdapter<Leave>(
getActivity(),
Leave.class,
R.layout.leavelistview,
childRef
) {
#Override
protected void populateView(View v, Leave model, int position) {
((TextView)v.findViewById(R.id.lv_staffname)).setText(model.getName());
((TextView)v.findViewById(R.id.lv_type)).setText(model.getType());
((TextView)v.findViewById(R.id.lv_duration)).setText(model.getDuration());
}
};
listView.setAdapter(firebaseListAdapter);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_today, container, false);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
Here the problem is not only the data is populating but also its not setting the text of the textview. But the data is populating and listing if I am using an activity. So I guess the data retrieving code is correct.
So where can is initialize the listview inside a fragment?
I have an odd situation, I have an Activity hosting a TabLayout/Viewpager that populates data based on changes to a Firebase Database. Unfortunately, the RecyclerView is not being populated, and I am receiving the error below in my logcat. I believe the fragment is being loaded even when it is not on screen, which is causing an error in the population of the RecyclerView. It is also weird as the RecyclerView does populate when I rotate the screen:
12-13 21:31:40.013 12490-12490/com.troychuinard.fanpolls E/RecyclerView: No adapter attached; skipping layout
Here is the ViewPager Adapter I have in my host Activity:
public class SectionPagerAdapter extends FragmentPagerAdapter {
public SectionPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new TrendingFragment();
case 1:
return new FollowingFragment();
case 2:
return new LiveFragment();
default:
return new TrendingFragment();
}
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getResources().getString(R.string.trending_text);
case 1:
return getResources().getString(R.string.following_text);
case 2:
return getResources().getString(R.string.new_text);
default:
return getResources().getString(R.string.trending_text);
}
}
}
Here is the complete fragment where I initialize the RecyclerView inside onCreateView() function in my LiveFragment, which is tab 3 in the TabLayout:
public class LiveFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private RecyclerView mRecyclerview;
private DatabaseReference mBaseRef;
private DatabaseReference mPollsRef;
private LinearLayoutManager mLayoutManager;
private FirebaseRecyclerAdapter <Poll, PollHolder> mFireAdapter;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public LiveFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment LiveFragment.
*/
// TODO: Rename and change types and number of parameters
public static LiveFragment newInstance(String param1, String param2) {
LiveFragment fragment = new LiveFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBaseRef = FirebaseDatabase.getInstance().getReference();
mPollsRef = mBaseRef.child("Polls");
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View v = inflater.inflate(R.layout.fragment_new, container, false);
Log.v("TAG", "ON CREATE CALLED FROM NEW");
mLayoutManager = new LinearLayoutManager(getActivity());
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerview = (RecyclerView)v.findViewById(R.id.new_RecyclerView);
if (mRecyclerview != null){
mRecyclerview.setHasFixedSize(true);
}
if (mRecyclerview == null){
Log.v("TAG", "RECYCLERVIEW NULL");
} else if (mLayoutManager == null){
Log.v("TAG", "LAYOUTMANAGER NULL");
} else if (mFireAdapter == null) {
Log.v("TAG", "mFIREADAPTER NULL");
}
return v;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onStop() {
super.onStop();
if (mFireAdapter != null){
mFireAdapter.cleanup();
}
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mRecyclerview.setLayoutManager(mLayoutManager);
mFireAdapter = new FirebaseRecyclerAdapter<Poll, PollHolder>(Poll.class, R.layout.latest_item, PollHolder.class, mPollsRef) {
#Override
protected void populateViewHolder(PollHolder viewHolder, Poll model, int position) {
viewHolder.mPollQuestion.setText(model.getQuestion());
Picasso.with(getActivity().getApplicationContext())
.load(model.getImage_URL())
.fit()
.into(viewHolder.mPollImage);
Log.v("QUESTION", model.getQuestion());
Log.v("IMAGE", model.getImage_URL());
}
};
mRecyclerview.setAdapter(mFireAdapter);
mPollsRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot x : dataSnapshot.getChildren()){
mFireAdapter.notifyItemInserted(0);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public static class PollHolder extends RecyclerView.ViewHolder {
TextView mPollQuestion;
ImageView mPollImage;
public PollHolder(View itemView) {
super(itemView);
mPollQuestion = (TextView) itemView.findViewById(R.id.latest_item_question);
mPollImage = (ImageView) itemView.findViewById(R.id.pollThumbNailImage);
}
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
Move your Adapter from onCreateView to onActivityCreated method after you have read data from firebase.
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//read Poll data from firebase mPollsRef for example
//.... database reference to firebase
//Query mPollsRef = databaseReference.child("pools").limitToFirst(200);
mRecyclerview.setLayoutManager(mLayoutManager);
mFireAdapter = new FirebaseRecyclerAdapter<Poll, PollHolder>(Poll.class, R.layout.latest_item, PollHolder.class, mPollsRef) {
#Override
protected void populateViewHolder(PollHolder viewHolder, Poll model, int position) {
viewHolder.mPollQuestion.setText(model.getQuestion());
Picasso.with(getActivity().getApplicationContext())
.load(model.getImage_URL())
.fit()
.into(viewHolder.mPollImage);
Log.v("QUESTION", model.getQuestion());
Log.v("IMAGE", model.getImage_URL());
}
};
mRecyclerview.setAdapter(mFireAdapter);
}
My code for initialize Pager at HostActivity.java
private FragmentPagerAdapter mPagerAdapter;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_absence);
// Create the adapter that will return a fragment for each section
mPagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
private final Fragment[] mFragments = new Fragment[] {
new MyAbsenceFragment(),
new MyAttendanceFragment(),
new AbsTypesFragment(),
new LiveFragment(),
};
private final String[] mFragmentNames = new String[] {
"Absences",
"Attendances",
"AbsTypes",
"Live"
};
#Override
public Fragment getItem(int position) {
return mFragments[position];
}
#Override
public int getCount() {
return mFragments.length;
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentNames[position];
}
};
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mPagerAdapter);
I'm trying to use an ArrayList to store an array of objects and then pass them to my adapter.
public ArrayList<Song> arrayOfSongs;
public SongsAdapter adapter;
I initially just declare my arrayofSongs. Then I initialize inside onCreateView() in my fragment
arrayOfSongs = new ArrayList<>();
adapter = new SongsAdapter(getContext(), arrayOfSongs);
The problem is that variable is initally null, and that gave me a lot of problems when I tried to use the adapter to populate the views initially. So I had to override my adapter's getView to return 0 if the array was null as suggested. Some comments told me that it was better just to "initialize an empty ArrayList to put into the adapter instead of using a null check inside of the adapter". How would I do this because I'm getting a null pointer exception when I call adapter.clear()
here is my SearchFragment
public class SearchFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public SearchFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment SearchFragment.
*/
// TODO: Rename and change types and number of parameters
public static SearchFragment newInstance(String param1, String param2) {
SearchFragment fragment = new SearchFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public EditText editText;
public ImageButton searchButton;
public ProgressBar pb;
public ListView lv;
public ArrayList<Song> arrayOfSongs;
public SongsAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_search, container, false);
arrayOfSongs = new ArrayList<>();
adapter = new SongsAdapter(getContext(), arrayOfSongs);
editText = (EditText) rootView.findViewById(R.id.edit_message);
searchButton = (ImageButton) rootView.findViewById(R.id.search_button);
lv = (ListView) rootView.findViewById(R.id.listView);
lv.setAdapter(adapter);
pb = (ProgressBar) rootView.findViewById(R.id.progressBar);
pb.setIndeterminate(true);
pb.setVisibility(ProgressBar.INVISIBLE);
searchButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String searchWords = editText.getText().toString();
if (!searchWords.matches(""))
hitItunes(searchWords);
}
});
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
String searchWords = editText.getText().toString();
if (!searchWords.matches("")) {
hitItunes(searchWords);
handled = true;
}
}
return handled;
}
});
return rootView;
}
public void hitItunes(String searchWords) {
pb.setVisibility(ProgressBar.VISIBLE);
try {
String url = "https://itunes.apple.com/search?term=" + URLEncoder.encode(searchWords, "UTF-8") + "&country=US&media=music&limit=100";
JsonObjectRequest req = new JsonObjectRequest(url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
VolleyLog.v("Response:%n %s", response.toString(4));
Log.d("volley_success", response.toString());
pb.setVisibility(ProgressBar.INVISIBLE);
JSONArray songsJSON = response.getJSONArray("results");
ArrayList<Song> songs = Song.fromJSON(songsJSON);
adapter.clear();
adapter.addAll(songs);
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
Log.d("volley_error", error.getMessage());
}
});
/*
RequestQueue reqQueue = Volley.newRequestQueue(getActivity().getApplicationContext());
reqQueue.add(req);
*/
try {
// add the request object to the queue to be executed
ApplicationController.getInstance().addToRequestQueue(req);
} catch (NullPointerException npe) {
npe.printStackTrace();
}
} catch (UnsupportedEncodingException uee) {
throw new AssertionError("UTF-8 is unknown");
}
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
/*
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
*/
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
and here is my logcat
03-23 12:12:08.678 2574-2574/com.loomius.loomius E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.loomius.loomius, PID: 2574
java.lang.NullPointerException
at android.widget.ArrayAdapter.clear(ArrayAdapter.java:258)
at com.loomius.loomius.SearchFragment$3.onResponse(SearchFragment.java:159)
at com.loomius.loomius.SearchFragment$3.onResponse(SearchFragment.java:148)
at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:65)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5113)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
at dalvik.system.NativeStart.main(Native Method)
here is the SongsAdapter
public class SongsAdapter extends ArrayAdapter<Song> {
ArrayList<Song> mList;
Context mContext;
public SongsAdapter(Context context, ArrayList<Song> songs) {
super(context, 0, songs);
mList = songs;
mContext = context;
}
#Override
public int getCount() {
if(mList==null) {
return 0;
}
else {
return mList.size();
}
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Song song = getItem(position);
if (convertView == null)
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_song, parent, false);
TextView artistName = (TextView) convertView.findViewById(R.id.artistName);
TextView trackName = (TextView) convertView.findViewById(R.id.trackName);
artistName.setText(song.getArtist());
trackName.setText(song.getTitle());
return convertView;
}
}
You can solve this by
before calling adapter.clear() check it contains data or not using adapter.getCount()
if(adapter.getCount()>0)
adapter.clear()