Get Fragment page title that is determined at Runtime - android

I am using FragmentPagerAdapter that contains two Fragments. Two Fragments extends from AbstractFragment which extends Fragment. I am not able to get the page title of the fragment when its created because the title is pass as an argument to the fragment:
FragmentActivity's inner Class:
ArrayList<AbstractFragment> fragments = new ArrayList<AbstractFragment >();
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return fragments.get(position).getTitle();
}
}
AbstractFragment :
protected Bundle data;
protected String title;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
data=this.getArguments();
numberSetData=data.getParcelableArrayList(KEY_CHART_DATA);
title=data.getString(KEY_CHART_TITLE);
//Title should is determined here.
}
public abstract String getTitle();
ConcreteFragment:
#Override
public String getTitle(){
return title;
}
The problem solves if I swipe to the next fragment , title will appear but not when its created. Any advice?

You are calling getTitle at a point where onCreate has not yet been called for that Fragment. A known workaround for this would be to check if onCreate has been called, and if not then return data.getString(KEY_CHART_TITLE).
public String getTitle()
{
if( title == null )
{
title = getArguments().getString(KEY_CHART_TITLE);
}
return title;
}

Related

Nested Child Fragment with Viewpager

Currently, I am trying to create a nested view pager using a fragment, how can I access top parent function to refresh the View?
Let's say I have:
public class ParentFragment extends Fragment {
...{
...
viewPagerAdapter = new ViewPagerParentAdapter(getChildFragmentManager(), listOfItem);
viewPager.setAdapter(viewPagerAdapter);
}
public void refreshView(){
loadData();
}
private class ViewPagerParentAdapter extends FragmentStatePagerAdapter{
private List<String> tabTitle;
private List<Item> listOfItem;
public ViewPagerParentAdapter(FragmentManager fm, #NonNull List<Item> listOfItem) {
super(fm);
this.tabTitle = new ArrayList<>();
this.listOfItem = new ArrayList<>();
if (listOfItem.size() > 0) {
this.listOfItem = listOfItem;
for (Item item : this.listOfItem) {
tabTitle.add(Item.getCLASSIFICATION());
}
}
notifyDataSetChanged();
}
#Override
public Fragment getItem(int position) {
return DetailFragment.newInstance(getItemAtPosition(position).getDETAILS());
}
public Item getItemAtPosition(int position) {
return listOfItem != null ? listOfItem.get(position) : null;
}
}
}
and here my object
public class Item{
//POJO
private String CLASSIFICATION;
private Details details;
}
detail fragment
public class DetailFragment extends Fragment{
...{
...
Details details = getArguments().getParcelable("details");
viewPagerAdapter = new DetailViewPagerAdapter(getChildFragmentManager(), details);
viewPagerDetails.setAdapter(viewPagerAdapter);
}
public void refreshParentView(){
((ParentFragment) getParentFragment()).refreshView(); //getting Null
}
public class DetailViewPagerAdapter extends FragmentStatePagerAdapter {
String[] tabTitle = {"Components", "Materials", "Descriptions"};
Details details;
public DetailViewPagerAdapter(FragmentManager fm, #NonNull Details details) {
super(fm);
this.details = details;
notifyDataSetChanged();
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return DetailsChildFragment.newInstance(details.getCOMPONENT());
case 1:
return DetailsChildFragment.newInstance(details.getMATERIAL());
case 2:
return DetailsChildFragment.newInstance(details.getDESC());
}
return null;
}
#Override
public int getCount() {
return tabTitle.length;
}
}
}
last child fragment
public class DetailsChildFragment extends Fragment implements View.OnClickListener{
...{
...
...
Button buttonRefresh = (Button)getView().findViewById(R.id.button_refresh);
buttonRefresh.setOnClickListener(this);
}
#Override
public void onClick(View view){
switch(view.getId()){
case R.id.button_refresh:
((DetailFragment)getParentFragment()).refreshParentView();
break;
}
}
}
Currently I am getting Null on the detail fragment refreshParentView
Any suggestions? Thanks in advance
You could use an interface as a Listener for events happening in the child
public interface Listener{
void onRefreshButtonClicked();
}
The child fragment needs to have a Listener as a field, and then you could set the Listener when getting an instance of the child fragment.
public class ChildFragment extends Fragment{
private Listener listener;
public void setListener(Listener listener)//setter
...
//now on button click you call the listener
refreshButton.setOnClickListener(new View.OnClickListener(){
#Override onClick(){
if(listener!=null){
listener.onRefreshButtonClicked();
}
}
}
public class ParentFragment extends Fragment{
...
ChildFragment child = ChildFragment.getInstance()
child.setListener(new Listener(){
#Override
void onRefreshButtonClicked(){
// implement your logic
}
}
An advantage of doing it like this is that you don't need to cast the parent from Fragment to ParentFragment which makes your code re-usable should you ever need to
When you add your DetailFragment do it with a tag, so that you can retrieve it's instance when you need it. Example:
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, detailFragment,"detailFragmentTag").commit();
Now, any time you need to access this fragment, you only need to call
DetailFragment parentFragment = (DetailFragment) getActivity().getSupportFragmentManager().findFragmentByTag("detailFragmentTag");
if(detailFragment != null && detailFragment.isAdded()){ //check if it is not null and it is added to the view so you dont end up in some NPE
detailFragment.refreshParentView()

getItem in FragmentStatePagerAdapter never called when instantiating from a Fragment

I'm using a Fragment on my Activity that will have a picture "swiper". I've created a FragmentStatePagerAdapter which I'm trying to call from this Fragment and for some reason my getItem() method is never being called.
I've searched and found that I need to use getChildFragmentManager() when instantiating my FragmentStatePagerAdapter because I'm calling it from a Fragment. I've tried this as well as getSupportFragmentManager() with no luck from either.
Any ideas?
here's my Fragment that I'm using on my MainActivity with the method that shoudl setup the FragmentStatePagerAdapter:
public class PhotoFlipper extends Fragment {
// properties and fields
// primitive types
String currentImage;
int friendShareType = 0;
ImageView share;
ViewPager pager;
PhotoFlipperItemAdapter pagerAdapter;
LatLng itemPosition;
Activity activity;
FragmentActivity fragActivity;
public ArrayList<MarkerModel> picsAndVids;
// end properties and fields
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View photoFlipperFragmentView = inflater.inflate(R.layout.photo_flipper_layout, container, false);
InitializeFragment(photoFlipperFragmentView);
return photoFlipperFragmentView;
}
private void InitializeFragment(View photoFlipperFragmentView) {
activity = getActivity();
fragActivity = (FragmentActivity)activity;
pager = (ViewPager)photoFlipperFragmentView.findViewById(R.id.photoflipper_pager);
share = (ImageView)photoFlipperFragmentView.findViewById(R.id.photoflipper_share);
share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
IPictureFlipper iPictureFlipper = (IPictureFlipper)activity;
iPictureFlipper.ShareVideoOrImage(friendShareType, itemPosition, currentImage);
}
});
}
#Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (hidden) {
pager.setVisibility(View.GONE);
}
}
public void SetTappedPicture(int index) {
pagerAdapter = new PhotoFlipperItemAdapter(getChildFragmentManager(), picsAndVids, picsAndVids.size());
pager.setAdapter(pagerAdapter);
pager.setCurrentItem(index);
pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
}
});
}
}
And here's my FragmentStatePagerAdapter:
public class PhotoFlipperItemAdapter extends FragmentStatePagerAdapter {
ArrayList<MarkerModel> _markers;
int NUM_PAGES;
String TAG = "home";
public PhotoFlipperItemAdapter(FragmentManager fm, ArrayList<MarkerModel> markers, int numpages){
super(fm);
Log.d(TAG,"in adapter in constructor");
_markers = markers;
NUM_PAGES = numpages;
}
#Override
public Fragment getItem(int position) {
Log.d(TAG,"in adapter in get item");
Fragment fragment = PhotoFlipperItemFragment.create(position, _markers);
return fragment;
}
#Override
public int getCount() {
Log.d(TAG,"in adapter in get count: "+NUM_PAGES);
return NUM_PAGES;
}
}
logcat is showing me that NUM_PAGES is > 0 so that's not my issue. I see my log in the constructor and in getCount() but nothing in getItem().
TIA
I got this sorted out. I was hiding my fragment in my InitializeActivity() right after I added it to my FragmentManager so it was never fully building the Fragment with the ViewPager etc.
I'm going to have to come up with a different solution for hiding/showing the fragment but that was my problem.

geArgument return return null after second call in tab layout

In my TabLayout, i tried these tabLayout with only one dynamic fragment. So I used setArguments in getItem Like that.
RecentSubTabAdapter.java :
public class RecentSubTabAdapter extends FragmentStatePagerAdapter{
ArrayList<String> myTitleList = new ArrayList<String>();
ArrayList<Fragment> myFragmentList = new ArrayList<Fragment>();
public void addFragment(Fragment f, String t)
{
myFragmentList.add(f);
myTitleList.add(t);
}
public RecentSubTabAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return myTitleList.size();
}
#Override
public Fragment getItem(int position) {
Bundle b = new Bundle();
b.putString("args", myTitleList.get(position));
myFragmentList.get(position).setArguments(b);
return myFragmentList.get(position);
}
#Override
public CharSequence getPageTitle(int position) {
return myTitleList.get(position);
}
}
And I added getArgument in myFragment like that
Bundle b = getArguments();
myPosition = b.getString("args").toLowerCase();
It was ok for first time calling tab. But when I called multiple tab and re-called first tab. It show NULL POINTER EXCEPTION in getArguments.
PLease Help me

Android - smoothScrollToPosition inside a child Fragment in a ViewPager

I'm having difficulty in setting smooth scroll for Fragments inside ViewPager, nested in another Fragment which acts as their parent.
I set up this method :
public void scrollToTop()
{
this.recyclerView.smoothScrollToPosition(0);
}
For Fragments not in a ViewPager, but I don't know how to get the reference of Fragments inside a ViewPager.
I did
BottomLobiFragment activeLobi = (BottomLobiFragment)getSupportFragmentManager().findFragmentByTag(utilities.lobbyTag);
to get the parent Fragment.
Code for a ViewPager (The rest are almost identical, difference is only at number of item, and constructor)
public class LobbyPagerAdapter extends FragmentStatePagerAdapter {
public LobbyPagerAdapter (FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int pos) {
switch(pos) {
case 0: return Friends.newInstance("Friends, Instance 1");
// case 1: return Photo.newInstance("Photo, Instance 1");
// case 2: return Activities.newInstance("Activities, Instance 1");
default: return Friends.newInstance("Friends, Default");
}
}
#Override
public CharSequence getPageTitle(int position) {
return CONTENT[position % CONTENT.length];
}
#Override
public int getCount() {
//return 3;
return CONTENT.length;
}
private class setAdapterTask extends AsyncTask<Void,Void,Void> {
protected Void doInBackground(Void... params) {
return null;
}
#Override
protected void onPostExecute(Void result) {
}
}
}
Note : Every adapter is located inside the parent Fragment
First modify your Adapter to this
public class LobbyPagerAdapter extends FragmentStatePagerAdapter {
private ArrayList<Fragment> mFragments = new ArrayList<>();
public LobbyPagerAdapter (FragmentManager fm) {
super(fm);
mFragments.add(Friends.newInstance("Friends, Instance 1"));
mFragments.add(Photo.newInstance("Photo, Instance 1"));
mFragments.add(Activities.newInstance("Activities, Instance 1"));
}
#Override
public Fragment getItem(int pos) {
return mFragments.get(pos);
}
#Override
public CharSequence getPageTitle(int position) {
return CONTENT[position % CONTENT.length];
}
#Override
public int getCount() {
//return 3;
return CONTENT.length;
}
private class setAdapterTask extends AsyncTask<Void,Void,Void> {
protected Void doInBackground(Void... params) {
return null;
}
#Override
protected void onPostExecute(Void result) {
}
}
}
Now in your fragment or activity which is holding the ViewPager & the adapter instance, you can simply do like adapter.getItem(1); example :
//Suppose your LobbyPagerAdapter instance looks like this in your code
LobbyPagerAdapter adapter = new LobbyPagerAdapter(getFragmentManager());
// And now you want to get the fragment at second position in your tab
Photo photoFragmentObject = (Photo)adapter.getItem(1);
// And now you want to get the fragment at first position in your tab
Friends friendsFragmentObject = (Friends)adapter.getItem(0);

Pass object from activity to fragment

I am new to Android.Its my first application.I have tried searching on Internet but everyone tried to pass simple data from activity to fragment.I want to pass an whole object from activity to fragment.
I know there is one solution around is just use serialize & de-serialize & put the data in Bundle.
Instead trying serialize & deserialize,I created a non-static method in my activity & trying to getActivity() in fragment & then calling that method but it returns me null.Can anybody help me with what I am doing wrong.
Below is my code:-
BaseDefaultActivity is my own customized class which extends AppCompatActivity.
public class EventDetailActivity extends BaseDefaultActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setBaseContentView(R.layout.activity_event_detail);
ButterKnife.bind(this);
initialiseDataFromIntend();
DummyObject obj=new DummyObj();
setDataObject(obj);
// Get the ViewPager and set it's PagerAdapter so that it can display items
viewPager.setAdapter(new EventDetailFragementAdapter(getSupportFragmentManager(), EventDetailActivity.this));
// Give the TabLayout the ViewPager
tabLayout.setupWithViewPager(viewPager);
}
}
public class BaseDefaultActivity extends AppCompatActivity implements BaseActivity {
private Object dataObj;
public void setDataObject(Object obj) {
this.dataObj = obj;
}
public Object getDataObj() {
return this.dataObj;
}
}
public class EventDetailFragementAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 3;
private String tabTitles[] = new String[]{"Tab1", "Tab2", "Tab3"};
private Context context;
public EventDetailFragementAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
#Override
public CharSequence getPageTitle(int position) {
return tabTitles[position];
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new EventDetailFragement();
break;
case 1:
fragment = new EventBasicInfoFragement();
break;
default:
fragment = new EventDetailFragement();
break;
}
return fragment;
}
#Override
public int getCount() {
return PAGE_COUNT;
}
public class EventDetailFragement extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.event_detail_fragement, container, false);
TextView textView = (TextView) view;
textView.setText("AAAAAAA #" + (SearchEventResponseObject) ((BaseDefaultActivity) getActivity()).getDataObj());
return view;
}
}

Categories

Resources