I need to call fragment from DataAdapter android - android

Here, My class is like this
public class TicketAdapter extends ArrayAdapter<Ticket> {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
TicketHolder holder = null;
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new TicketHolder();
holder.ticket = items.get(position);
holder.removeTicketButton = (ImageButton)row.findViewById(R.id.ticket_remove);
holder.removeTicketButton.setTag(holder.ticket);
holder.settingTicketButton=(ImageButton)row.findViewById(R.id.ticket_setting);
holder.settingTicketButton.setTag(holder.ticket);
holder.settingTicketButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
holder.name = (TextView)row.findViewById(R.id.ticket_name);
setNameTextChangeListener(holder);
// holder.value = (TextView)row.findViewById(R.id.atomPay_value);
// setValueTextListeners(holder);
row.setTag(holder);
setupItem(holder);
return row;
}
}
And my another java file is like this
public class FreeFragment extends Fragment
{
}
Here, I want to call FreeFragment class from TicketAdapter class. While clicking on (R.id.settingTicketButton) this button, FreeFragment need to be called. How to call this Fragment from DataAdapter? Is it possible? Please Help.

The best method would be passing the FreeFragment instance an a variable in the constructor of the TicketAdapterand store it inside the adapter.
If this is not feasible you can use the following approch.
Fragment fragment = ((Activity)context).getfragmentmanager.findfragmentById(R.id.your_fragment_container_id);
Add this code in the contructor

I wouldn't access FreeFragment directly from TicketAdapter because you don't know if the fragment is added and visible. I would define a method in owner activity that would be called from adapter. In this method check first if the fragment is not-null and then call whatever method from fragment. Something like (in parent Activity):
public void callFragmentMethod() {
FragmentManager fm = getFragmentManager();
Fragment fragment = fm.findFragmentByTag("SOME_TAG");
if(fragment != null) {
FreeFragment ff = (FreeFragment) fragment;
ff.callSomeMethod();
}
}
Pass the reference of the activity to the adapter and call above method from adapter. Or, to make the code more beautiful and easier to maintain and extend, define and interface with above method, have the activity extending the interface and send the interface as reference to adapter.

easy step to handle this condition
1)create one Interface give any name
2) define method inside as per ewquirement example MyCommumicator
example i want to refreshData so i define method inside my interface like
public void refreshData();
now take reference of interface in adater like
MyCommumicator myCommumicator;
3)implement that interface into your Fragment and implement method.
4)create Constractor of Adapter like
public TicketAdapter(other params...,MyCommumicator MyCommumicator){
this.myCommumicator = myCommumicator;
}
6) Time of calling just call like this
myCommumicator.refreshData();
now enjoy
ANOTHER WAY
Use LocalBroadCast.

so if your adapter have access to FragmentActivity, you must call FragmentManager and further call fragment
FragmentManager fragmentManager = yourFragmentActivity.getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// Create new fragment and transaction
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, yourFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();

I found my solution. I have written the following code in TicketAdapter.java file..
holder.settingTicketButton=(ImageButton)row.findViewById(R.id.ticket_setting);
holder.settingTicketButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
Fragment freeFragment = new FreeFragment();
if (freeFragment != null)
switchFragment(freeFragment);
Log.e("adapter_click_setting","adapter_click_setting");
}
});
}
private void switchFragment(Fragment newFragment)
{
if (context == null)
{
Log.e("null_context","nulllll");
return;
}
if (context instanceof AddNewTicket) {
Log.e("meth_calling","method_calling");
AddNewTicket feeds = (AddNewTicket) context;
feeds.switchContent(newFragment);
}
}
And I have written the following method in AddNewTicket.java file..
public void switchContent(android.support.v4.app.Fragment newFragment) {
// TODO Auto-generated method stub
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, newFragment).commit();
}
Here, the R.id.fragment_container is the id of my ticket_listview.xml file. I have declared FragmentLayout in my that Xml file....

Related

Fragment Not open inside RecyclerView.Adapter (show error in getFragmentManager() while calling fragment)

Here I want to open fragment inside RecycleView but its show error but when I open activity its work here. When try to open a fragment with here of fragment manager the Recycler view class can not resolve to getFragmentManager() method inside it. Kindly provide a solution for it
public class AdapterMudra extends RecyclerView.Adapter<AdapterMudra.ReyclerViewHolder> {
private LayoutInflater layoutInflater;
private Context context;
private ArrayList<ItemMudra> items;
public AdapterMudra(Context context, ArrayList<ItemMudra> items) {
this.layoutInflater = LayoutInflater.from(context);
this.context = context;
this.items = items;
}
#Override
public ReyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View item = layoutInflater.inflate(R.layout.item_recycler_view, parent, false);
return new ReyclerViewHolder(item);
}
#Override
public void onBindViewHolder(final ReyclerViewHolder holder, int position) {
ItemMudra item = items.get(position);
holder.image.setImageResource(item.getDrawableMudra());
holder.appName.setText(item.getNameMudra());
}
#Override
public int getItemCount() {
return items.size();
}
class ReyclerViewHolder extends RecyclerView.ViewHolder {
private ImageView image;
private TextView appName;
private ReyclerViewHolder(final View v) {
super(v);
image = (ImageView) v.findViewById(R.id.image);
MyName = (TextView) v.findViewById(R.id.my_name);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(MyName.getText().toString()=="XYZ")
{
***//Fragment Not open here show error////
***
Here I want to call Fragment but its show error in GetFragment Manager***
Fragment fragment= new XYZ();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, fragment);
transaction.addToBackStack(null); // this will manage backstack
transaction.commit();
}
if(MyName.getText().toString()=="ABC")
{
*** //Here Its Work When I open activity inside it***
Intent intent=new Intent(v.getContext(),ExtraActivityFormTesting.class);
context.startActivity(intent);
}
}
});
}
}
}
I assume your context is an Activity so you can do something like
((Activity) context).getFragmentManager()
First make sure the other fragmented class has the necessary implementations and constructors to be fragmented. Meaning, the class XYZ could be preventing your fragment transaction for missing out few essentials.
The following imports for instance
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
Now if thats in order. then Firstly I want you to reform
Fragment fragment= new XYZ();
to
XYZ fragment= new XYZ();
Second your fragment manager is badly constructed
reform this
Fragment fragment= new XYZ();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
to
XYZ fragment= new XYZ();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
*And for future references, you need to bring in the error log from the terminal
if your problem is using getFragmentManaget to implement do like below:
create
FragmentManager fm = getFragmentManager();
in your Fragment and passed it to your RecyclerView and again passed it to your ViewHolder and use it. so easy.
note: passed means send it as argumant to constructor
Fragment fragment= new FirstFragment();
FragmentManager manager = (MainActivityForRecy)context).getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.fragment_container, fragment);
transaction.addToBackStack(null); // this will manage backstack
transaction.commit();
Toast.makeText(context, "you press clicked",Toast.LENGTH_SHORT).show();

Android how to open fragment from listview element

In MainActivity is FrameLayout MainContainer. I load there a fragment TrainerMyGroups, there is a Listview where I add a few elements (each element has some strings) by use TrainerGroupsAdapter. Actually I want to replace fragment TrainerMyGroups by another (for example TrainersInfo) by click on list's element.
My TrainerGroupsAdapter is:
public class TrainerGroupsAdapter extends ArrayAdapter {
List list = new ArrayList();
public TrainerGroupsAdapter(Context context, int resource) {
super(context, resource);
}
static class Datahandler{
TextView name;
TextView when;
TextView where;
LinearLayout ll;
}
#Override
public void add(Object object) {
super.add(object);
list.add(object);
}
#Override
public int getCount() {
return this.list.size();
}
#Override
public Object getItem(int position) {
return this.list.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row;
row=convertView;
Datahandler handler;
SharedPreferences pref = getContext().getSharedPreferences("pref", Context.MODE_PRIVATE);
if(convertView==null){
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row= inflater.inflate(R.layout.list_mygroups,parent,false);
handler = new Datahandler();
handler.name = (TextView) row.findViewById(R.id.trainermygroupslistname);
handler.where = (TextView) row.findViewById(R.id.trainermygroupslistwhere);
handler.when = (TextView) row.findViewById(R.id.trainermygroupslistwhen);
handler.ll=(LinearLayout) row.findViewById(R.id.trainermygroupslistlayout);
row.setTag(handler);
}
else {
handler = (Datahandler)row.getTag();
}
TrainerGroupsDataProvider dataProvider;
dataProvider = (TrainerGroupsDataProvider)this.getItem(position);
handler.name.setText(dataProvider.getName());
handler.when.setText(dataProvider.getWhen());
handler.where.setText(dataProvider.getWhere());
handler.ll.setBackgroundColor(Color.parseColor(pref.getString(TRANSP_KEY, "#CC") + dataProvider.getColor()));
handler.ll.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getFragmentManager().beginTransaction().replace(R.id.MainContainer, new TrainerInfo()).addToBackStack(null).commit();
}
});
return row;
}
}
It doesn't work but method OnClick is probably good because if I replace getFragmentManager().beginTransaction().replace(R.id.MainContainer, new TrainerInfo()).addToBackStack(null).commit(); to code for change some strings (name, when tc) it works. Problem is in getFragmentMenager(), Android Studio shows message that I have to create Getter and AS's suggestion is to generate in OnClick method:
private FragmentManager fragmentManager;
public FragmentManager getFragmentManager() {
return fragmentManager;
}
then problem is in the second argument in replace, I have error that it has to be Fragment (Im sure that TrainersInfo() is fragment because I use it in other place and it works).
How can I solve this problem or what is the best way to open fragment by click on lise's element in another fragment?
#UPDATE2
Better then replacing the Fragment inside the adapter is to say your activity that it should replace the fragment. This can be done with an interface which you implement inside your Activity:
public class TrainerGroupsAdapter extends ArrayAdapter {
// The interface which you have to implement in your activity
public interface OnChangeFragmentListener {
void changeFragment();
}
List list = new ArrayList();
private OnChangeFragmentListener m_onChangeFragmentListener;
public TrainerGroupsAdapter(Context context, int resource) {
super(context, resource);
m_onChangeFragmentListener = (OnChangeFragmentListener) context;
}
// Your other code
}
The OnClickListener in your getView Method:
handler.ll.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Call the method which change the fragment
m_onChangeFragmentListener.changeFragment();
}
});
The Activity:
public class MainActivity extends AppCompatActivity implements TrainerGroupsAdapter.OnChangeFragmentListener {
//...
// Your Other code
// Implement the method which is called in the adapter and replace the fragment here
#Override
public void changeFragment() {
getFragmentManager().beginTransaction().replace(R.id.MainContainer, new TrainerInfo()).addToBackStack(null).commit();
}
}
#UPDATE1
You need an activity context for getSupportFragmentManager() and getFragmentManager().
You can change the Context parameter of the constructor to Activity and create a member variable in your class for the activity so you can use it later:
public class TrainerGroupsAdapter extends ArrayAdapter {
List list = new ArrayList();
private Activity m_activity;
public TrainerGroupsAdapter(Activity context, int resource) {
super(context, resource);
m_activity = context;
}
// Your other code
}
The OnClickListener in your getView method:
handler.ll.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
m_activity.getFragmentManager().beginTransaction().replace(R.id.MainContainer, new TrainerInfo()).addToBackStack(null).commit();
}
});
Was searching for a similar answer, and got one from a good friend and android dev. I think it's the easiest one to understand and implement. SO I am usually creating a helper class in which I put my two static functions for opening fragments (as replace or dialog):
For example the replace one:
public static void openFragmentReplace(Activity activity, int idOfPlacement, Fragment fragment)
final FragmentManager fm = ((FragmentActivity)activity).getSupportFragmentManager();
final FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(idOfPlacement, fragment);
fragmentTransaction.commit();
}
and the dialog one:
public static void openFragmentAsDialog(Activity activity, DialogFragment fragment) {
final FragmentManager fm = ((FragmentActivity)activity).getSupportFragmentManager();
fragment.show(fm, "tag");
}
Then I just call it from where I want like this:
Helper.openFragmentReplace(getActivity(),R.id.PlaceForFragment,FragmentClass newFrag);
This seems like the best and easiest way to do it!
Hope it helps.

How to call getFragmentManager on Recycler.Adapter?

I am converting ListView of my app to RecyclerView. On ListView, it was very easy to implement OnClickListener but in RecyclerView, we have to do it in adapter. I want to open a new Fragment when user clicks on a item. To do this I have to call FragmentManager in adapter which I am not able to do.
This is my code of RecyclerAdapter:
public ListItemViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.title);
description = (TextView) itemView.findViewById(R.id.description);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
//Call FragmentManager and add Fragment to it.
}
}
So, how to call FragmentManager and add Fragments in it. Is there any better way than this like sendingBroadcast or any other method.
You just need an activity context passed in your constructor. Be sure to call new Adapter(this,...) from activities and new Adapter(getActivity(),...) from fragments.
private Context context;
#Override
public void onClick(View v) {
FragmentManager manager = ((AppCompatActivity)context).getSupportFragmentManager();
}
To add on to the approved answer: if you still get an error you might need to replace this line;
FragmentManager manager = ((Activity)context).getFragmentManager();
With this
FragmentManager manager = ((AppCompatActivity)context).getSupportFragmentManager();
For me this was because I was using the support.v4.app.FragmentManager instead of the regular fragmentmanager
Still get an error?
As one comment below pointed out, this might throw a java.lang.ClassCastException: and log ... cannot be cast to android.support.v7.app.AppCompatActivity (check comments for details)
Their fix was to use this instead (I haven't tested it but it worked for them):
((AppCompatActivity)activity).getSupportFragmentManager()
Make sure to pass context to the ArrayAdapter or RecyclerViewAdpater,So that we can get it inside Adapter Class.
If your mainActivity is extending Activity then use :
FragmentManager fragmentManager = ((Activity)context).getFragmentManager();
If your mainActivity is extending AppCompatActivity then use :
FragmentManager fragmentManager = ((AppCompatActivity)context).getSupportFragmentManager();
Best option would probably be to have the Fragment that instantiates the RecyclerAdapter to implement and interface like this:
public class MyRecyclerAdapter extends Adapter<RecyclerAdapter.ViewHolder> {
private ItemType[] mItems;
private MRAItemClickedListener mListener;
public MyRecyclerAdapter(Context ctx, MRAItemClickedListener listener){
mListener = listener;
...
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemView.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
mListener.onItemClicked(mItems[position]);
}
});
}
interface MRAItemClickedListener {
void onItemClicked(ItemType item);
}
}
public class MyFragment ... implements MRAItemClickedListener {
public void onItemClicked(ItemType item){
// do stuff with item
}
}
in kotlin you can use this code:
val fm : FragmentManager= (context as AppCompatActivity).supportFragmentManager
You just need an activity context passed in your constructor. Be sure to call new Adapter(this,...) from activities and new Adapter(getActivity(),...) from fragments.
private Context context;
#Override
public void onClick(View v) {
FragmentManager manager = ((Activity) context).getFragmentManager();}
I know this is too late for you but to anyone else who might see this.
So instead of doing m vai did you can pass the context of the fragment when you first initialize your adapter.
So in your constructor for your adapter you can add an argument like this
// variable to hold fragment
private Fragment fragment;
public MyCustomAdapter(Fragment fragment)
{
this.fragment = fragment;
}
and in your fragment you can just initialize if like this
MyCustomAdapter myAdapter = new MyCustomAdapter(this);
finally you can call
Fragment fragment = new myNewFragment();
FragmentManager fragmentManager = context.getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.fragment_container, fragment)
.commit();
so you can start a new fragment
Instantiate the fragmentManager in the activity itself.
MyActivity.java
FragmentManager fragmentManager = getFragmentManager();
adapter = new CustomAdapter(productsList, fragmentManager);
CustomAdapter.java
CustomAdapter implements MyClickListner{
CustomAdapter(Arraylist<MyProduct>productsList, FragmentManager fragmentManager) {
this.productList = productsList;
this.fragmentManager = fragmentManager;
}
#override
clickFunction(){
Fragment myFragment= new MyFilterFragment();
((MyFilterFragment) myFragment).show(this.fragmentManager,"tag");
}
MyClickListener.java
public interface MyClickListener(){
public clickFunction();
}
You could pass FragmentManager reference while creating viewholder so your class for Viewholder could be as follows
class ListItemViewHolder {
FragmentManager manager;
public ListItemViewHolder(View itemView,FragmentManager manager) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.title);
description = (TextView) itemView.findViewById(R.id.description);
itemView.setOnClickListener(this);
this.manager = manager;
}
#Override
public void onClick(View v) {
//Call FragmentManager and add Fragment to it.
manager.beginTransaction...
}
}

Getting View after fragmentTransaction.Replace()

I have an activity with two fragments in it (both dynamically created), one of which is a ListFragment. I have implemented an onListItemClick handler in the activity. When an item is clicked, I want to replace both fragments with other fragments, and populate a TextView. However, after replacing the fragments I can't seem to get the View object I need to manipulate the TextView in the new Details fragment -- it returns null. Here is some relevant code (onListItemSelected is the handler that processes onListItemClick in the main activity).
#Override
public void onListItemSelected(int index) {
inflateCheckinFragment();
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
cif = new checkInFragment();
fragmentTransaction.replace(R.id.action_container, cif, "ACTIONS");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit()
FragmentTransaction fragmentTransaction2 = fm.beginTransaction();
gdf = new GeolocDetailsFragment();
fragmentTransaction2.replace(R.id.fragment_container, gdf, "DETAILS");
fragmentTransaction2.addToBackStack(null);
fragmentTransaction2.commit();
View gdfView = gdf.getView();
TextView tv = (TextView) gdfView.findViewById(R.id.textPOI);
tv.setText(printPOI(poiList.get(index)));
}
I ended up just setting up the data in the onListItemSelected method. selectedPOI is a private class member.
public void onListItemSelected(int index) {
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.action_container, cif, TAG_CHECKIN);
fragmentTransaction.replace(R.id.fragment_container, gdf, TAG_DETAILS);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
selectedPOI = poiList.get(index);
}
Then in the GeolocDetailsFragment class, I set up a handler to be called in the Activity in the Fragment's onCreateView method to set the TextView value.
public class GeolocDetailsFragment extends Fragment {
private TextSetter textSetter;
public interface TextSetter {
public String getActivityText();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.geoloc_details_fragment, container, false);
TextView detailsText = (TextView) view.findViewById(R.id.textPOI);
detailsText.setText(textSetter.getActivityText());
return view;
}
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
textSetter = (TextSetter) activity;
}
catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnGetPOIListener");
}
}
}
Finally, I implemented getActivityText() in the main activity to get the string to pass to the TextView.
#Override
public String getActivityText() {
return printPOI(selectedPOI);
}
You should make use of the Fragments in a fashion like this, making the TextView public in your fragment helps the Activity to access it directly, and there fore change the value.
Class GeolocDetailsFragment extends Fragments{
public TextView tv;
onCreateView(){
tv= (TextView) rootView.findViewById(R.id.textPOI);
}
}
//IN YOUR ACTIVITY
#Override
public void onListItemSelected(int index) {
gdf = new GeolocDetailsFragment();
gdf.tv.setText(printPOI(poiList.get(index)));
}

ViewPager onPageSelected for first page

So it appears that when using a ViewPager, the onPageSelected listener does not get called for the first page same issue as this.
I have some logic that populates some more expensive UI elements for the currently selected page and this works when page is changed, but it doesn't work for the first page.
If I set the current item after the listener, the callback gets fired for the first page, but the view has not been initialized yet, so I can't manipulate it:
// Inside PagerAdapter.instantiateItem
ViewHolder vh = new ViewHolder();
cursor.moveToPosition(position);
vh.view = adapter.newView(context, cursor, null);
// Set position as tag so we can retrieve it with findViewByTag
vh.view.setTag(position);
((ViewPager) collection).addView(vh.view,0);
return vh;
// Inside MyActivity.onCreate
pagerAdapter = new SingleMessagePagerAdapter(this, cursor);
pager = (ViewPager)findViewById(R.id.message_pager);
pager.setAdapter(pagerAdapter);
pager.setOnPageSelectedListener(this);
pager.setCurrentItem(selectedItem);
// Inside MyActivity.onPageSelected
// Retrieve tagged view
View view = pager.findViewWithTag(position);
Here view ends up being null because PagerAdapter.instantiateItem has not yet been run. So I guess my question is, at which point in the activity lifecycle can I be certain that the ViewPager has initialized the view? I tried doing this inside Activity.onAttachedToWindow and Activity.onResume but it appears both of these get fired before PagerAdapter.instantiateItem.
I'm wondering why you don't just have the logic you mention in the Fragment itself rather than the hosting Activity. ViewPager buffers a couple of fragments either side of the current one so they're set up in the background and ready to go when the user swipes to them. Putting the logic in onPageSelected would mean bypassing this functionality and not doing the heavy lifting until the user swipes to the page.
Assuming for some reason you can't do the above, why not use an Interface with a callback function. Trigger the callback in the fragment's onCreateView function to let the Activity know it's fully instantiated.
try to use fragments!
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter() {
super(getSupportFragmentManager());
}
#Override
public Fragment getItem(int i) {
Fragment fr = null;
if (i==0)
fr = new sec0frag();
else if (i==1)
fr = new sec1frag();
else if (i==2)
fr = new sec2frag();
return fr;
}
#Override
public int getCount() {
return 3;
}
}
and create 3 fragments classes
e.g. :
public static class sec0frag extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// here is initialize for first time to view pages.!
}
}
My solution was to extend pager adapter and create an interface inside it. Then make the adapter call the interface only once after creating the adapter. Inside interface callback you can call onPageChanged method without having nullpointerexception. Add this class to your project and extend your adapter from it. Dont forget to set listener to adapter before setting adapter to viewpager. Adapter class below:
public abstract class ExtendedPagerAdapter extends FragmentPagerAdapter {
private boolean instantiated;
private AdapterListener adapterListener;
public interface AdapterListener {
void onAdapterInstantiated();
}
public ExtendedPagerAdapter(FragmentManager fragmentManager) {
this(fragmentManager, null);
}
public ExtendedPagerAdapter(FragmentManager fragmentManager, AdapterListener adapterListener) {
super(fragmentManager);
this.adapterListener = adapterListener;
instantiated = false;
}
#Override
public void finishUpdate(ViewGroup container) {
super.finishUpdate(container);
if (!instantiated) {
instantiated = true;
if (adapterListener != null) {
adapterListener.onAdapterInstantiated();
}
}
}
public void setAdapterInstantiatedListener(AdapterListener adapterListener) {
this.adapterListener = adapterListener;
}
}
Activity code:
adapter = new ViewPagerAdapter(getChildFragmentManager());
adapter.setAdapterInstantiatedListener(new ExtendedPagerAdapter.AdapterListener() {
#Override
public void onAdapterInstantiated() {
onPageSelected(viewPager.getCurrentItem());
}
});
viewPager.addOnPageChangeListener(this);
viewPager.setAdapter(adapter);

Categories

Resources