In my RSS Reader app, I call up a new feed in a fragment (RssItemListFragment) when the user selects Feed A. When they select feed B, a new fragment is created and the feed loads. When they go back to Feed A, I want the original fragment to be called instead of creating a new fragment. That's not working with this code at all - when I go back to a previous feed, the spinner goes for about half a second, so while it may be going back to the old fragment, it's not fetching the feed at all. Well, I am not quite sure what's going on. Here's my method for when the user clicks a feed from the navigation drawer:
@Override
public void onFeedClicked(final RssItemListFragment rssItemListFragment, final RssFeed rssFeed) {
BloclyApplication.getSharedDataSource().fetchNewFeed(rssFeed.getFeedUrl(), new DataSource.Callback<RssFeed>() {
@Override
public void onSuccess(RssFeed rssFeed) {
RssItemListFragment newFragment = RssItemListFragment.fragmentForRssFeed(rssFeed);
FragmentManager fragManager = getFragmentManager();
Fragment feedFragment = fragManager.findFragmentByTag(rssFeed.getFeedUrl());
if (feedFragment != null) {
//first check the fragmanager to see if the fragment for this feed url already exists
fragManager.beginTransaction()
.add(R.id.fl_activity_blocly,rssItemListFragment,rssFeed.getFeedUrl())
.commit();
}
fragManager.beginTransaction()
//replacing the framelayout
.replace(R.id.fl_activity_blocly, newFragment)
.addToBackStack(rssFeed.getFeedUrl())
.commit();
}
@Override
public void onError(String errorMessage) {
}
});
}
Where the method is called(in the same activity):
@Override
public void didSelectFeed(NavigationDrawerAdapter adapter, RssFeed rssFeed) {
drawerLayout.closeDrawers();
RssItemListFragment feedFragment = new RssItemListFragment();
this.onFeedClicked(feedFragment, rssFeed);
}
And just in case of course, the fragment class:
public class RssItemListFragment extends Fragment implements ItemAdapter.DataSource, ItemAdapter.Delegate,
NavigationDrawerAdapter.NavigationDrawerAdapterDelegate{
// #10 - stores and retrieves RSS feed's identifier from the bundle
private static final String BUNDLE_EXTRA_RSS_FEED = RssItemListFragment.class.getCanonicalName().concat(".EXTRA_RSS_FEED");
// #11
public static RssItemListFragment fragmentForRssFeed(RssFeed rssFeed) {
Bundle arguments = new Bundle();
arguments.putLong(BUNDLE_EXTRA_RSS_FEED, rssFeed.getRowId());
RssItemListFragment rssItemListFragment = new RssItemListFragment();
rssItemListFragment.setArguments(arguments);
return rssItemListFragment;
}
// #4
public static interface Delegate {
public void onItemExpanded(RssItemListFragment rssItemListFragment, RssItem rssItem);
public void onItemContracted(RssItemListFragment rssItemListFragment, RssItem rssItem);
public void onItemVisitClicked(RssItemListFragment rssItemListFragment, RssItem rssItem);
public void onFeedClicked(RssItemListFragment rssItemListFragment, RssFeed rssFeed);
}
// #5
private SwipeRefreshLayout swipeRefreshLayout;
private RecyclerView recyclerView;
private ItemAdapter itemAdapter;
private RssFeed currentFeed;
private List<RssItem> currentItems = new ArrayList<RssItem>();
private WeakReference<Delegate> delegate;
@Override
//notifies the fragment of its new owner
public void onAttach(Activity activity) {
super.onAttach(activity);
// #6 - assign this activity as our delegate reference
delegate = new WeakReference<Delegate>((Delegate) activity);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
itemAdapter = new ItemAdapter();
itemAdapter.setDataSource(this);
itemAdapter.setDelegate(this);
// #12
Bundle arguments = getArguments();
if (arguments == null) {
return;
}
long feedRowId = arguments.getLong(BUNDLE_EXTRA_RSS_FEED);
BloclyApplication.getSharedDataSource().fetchFeedWithId(feedRowId, new DataSource.Callback<RssFeed>() {
@Override
public void onSuccess(RssFeed rssFeed) {
currentFeed = rssFeed;
}
@Override
public void onError(String errorMessage) {
}
});
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View inflate = inflater.inflate(R.layout.fragment_rss_list, container, false);
swipeRefreshLayout = (SwipeRefreshLayout) inflate.findViewById(R.id.srl_fragment_rss_list);
recyclerView = (RecyclerView) inflate.findViewById(R.id.rv_fragment_rss_list);
return inflate;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
swipeRefreshLayout.setColorSchemeColors(getResources().getColor(R.color.primary));
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
// #7
BloclyApplication.getSharedDataSource().fetchNewItemsForFeed(currentFeed,
new DataSource.Callback<List<RssItem>>() {
@Override
public void onSuccess(List<RssItem> rssItems) {
if (getActivity() == null) {
return;
}
// #8
if (!rssItems.isEmpty()) {
currentItems.addAll(0, rssItems);
itemAdapter.notifyItemRangeInserted(0, rssItems.size());
}
swipeRefreshLayout.setRefreshing(false);
}
@Override
public void onError(String errorMessage) {
swipeRefreshLayout.setRefreshing(false);
}
});
}
});
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(itemAdapter);
}
/*
* ItemAdapter.DataSource
*/
@Override
public RssItem getRssItem(ItemAdapter itemAdapter, int position) {
return currentItems.get(position);
}
@Override
public RssFeed getRssFeed(ItemAdapter itemAdapter, int position) {
return currentFeed;
}
@Override
public int getItemCount(ItemAdapter itemAdapter) {
return currentItems.size();
}
/*
* ItemAdapter.Delegate
*/
@Override
public void onItemClicked(ItemAdapter itemAdapter, RssItem rssItem) {
int positionToExpand = -1;
int positionToContract = -1;
if (itemAdapter.getExpandedItem() != null) {
positionToContract = currentItems.indexOf(itemAdapter.getExpandedItem());
View viewToContract = recyclerView.getLayoutManager().findViewByPosition(positionToContract);
if (viewToContract == null) {
positionToContract = -1;
}
}
if (itemAdapter.getExpandedItem() != rssItem) {
positionToExpand = currentItems.indexOf(rssItem);
itemAdapter.setExpandedItem(rssItem);
} else {
itemAdapter.setExpandedItem(null);
}
if (positionToContract > -1) {
itemAdapter.notifyItemChanged(positionToContract);
}
if (positionToExpand > -1) {
itemAdapter.notifyItemChanged(positionToExpand);
// #9a
delegate.get().onItemExpanded(this, itemAdapter.getExpandedItem());
} else {
// #9b
delegate.get().onItemContracted(this, rssItem);
return;
}
View viewToExpand = recyclerView.getLayoutManager().findViewByPosition(positionToExpand);
int lessToScroll = 0;
if (positionToContract > -1 && positionToContract < positionToExpand) {
lessToScroll = itemAdapter.getExpandedItemHeight() - itemAdapter.getCollapsedItemHeight();
}
recyclerView.smoothScrollBy(0, viewToExpand.getTop() - lessToScroll);
}
@Override
public void onVisitClicked(ItemAdapter itemAdapter, RssItem rssItem) {
// #9c
delegate.get().onItemVisitClicked(this, rssItem);
}
//NavigationDrawerAdapterDelegate
@Override
public void didSelectFeed(NavigationDrawerAdapter adapter, RssFeed rssFeed){
delegate.get().onFeedClicked(this, rssFeed);
}
@Override
public void didSelectNavigationOption(NavigationDrawerAdapter adapter, NavigationDrawerAdapter.NavigationOption navigationOption){
}
}
Many thanks in advance to anyone who can help!
when you go back to previous feed you just need to remove the current fragment...
for example
FragmentTransaction fragmentTransaction = getFragmentManager()
.beginTransaction();
CurrentFragment fragment = (CurrentFragment) getFragmentManager()
.findFragmentByTag("CurrentFragment");
fragmentTransaction.remove(fragment);
fragmentTransaction.commit();
getFragmentManager().popBackStack();
hope this will help u..