Fragment with ViewPager issue - android

I want to create soemthing like this:
The ViewPager is attached to an adapter which has 2 fragments. One to list the upcoming orders and the other to list the past orders.
So the image shown above has a main fragment which hosts the ViewPager, and the adapter creates 2 fragments as children of the main fragment.
For sake of simplicity I'll call the main fragment as "Parent fragment" and the two fragments supplied by the adapter as "children fragments".
Once the parent fragment is created or resumed it has to fetch a list of data from the server and pass it to the two children fragment(The children fragments will process the list of data and display the necessary data). Both the children fragments have a listView, and each listView row item is clickable.
Now, the data fetched by the parent fragment has to be passed to the children fragments before the ViewPager is attached to the adapter. So I do not attach the adapter to the ViewPager in the onCreate method of the parent fragment, but rather once the list of data is fetched, I attach the adapter to the ViewPager in the onPostExecute method of the async task after the data is fetched.
This works fine the first time, but once I click on a listView row item of the child fragment and then press the back button, the getItem() method of the adapter is not called, but the onResume methods of the children fragments are called even before the data is fetched from the server.
So I guess the android framework remembers that the children fragment have already been created, and does not recreate them again.
How do I ensure that the children fragments are created/called only after the data is fetched from the server in the parent fragment?
I am adding some code for clarity.
BookingHistory.java(Parent Fragment)
public class BookingHistory extends android.support.v4.app.Fragment {
ViewPager mPager;
SlidingTabLayout mTabs;
Toolbar toolBar;
View view;
private ProgressDialog progress;
private OrderTask mOrderTask = null;
UserFunctions userFunctions = null;
OrderFunctions orderFunctions = null;
private BookingHistoryListener mListener;
private List<Order> mOrderList;
PlacedOrders upcomingOrders;
PlacedOrders pastOrders;
public BookingHistory() {
// Required empty public constructor
}
#Override
public void onResume() {
super.onResume();
mOrderList = null;
mPager = null;
mTabs = null;
upcomingOrders = null;
pastOrders = null;
progress = new ProgressDialog(getActivity());
fetchOrders();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_booking_history, container, false);
toolBar = (Toolbar) view.findViewById(R.id.toolbar_s);
if (toolBar != null) {
TextView tv = (TextView) view.findViewById(R.id.toolbar_title);
toolBar.setTitle("");
tv.setText("History");
}
return view;
}
class MyPagerAdapter extends FragmentPagerAdapter {
String tabs[] = {"Upcoming", "Past"};
public MyPagerAdapter(android.support.v4.app.FragmentManager fm) {
super(fm);
}
#Override
public android.support.v4.app.Fragment getItem(int position) {
if (position == 0) {
upcomingOrders = PlacedOrders.newInstance(Constants.DATE_TODAY_FUTURE);
upcomingOrders.getOrderList(mOrderList);
return upcomingOrders;
} else {
pastOrders = PlacedOrders.newInstance(Constants.DATE_PAST);
pastOrders.getOrderList(mOrderList);
return pastOrders;
}
}
#Override
public CharSequence getPageTitle(int position) {
return tabs[position];
}
#Override
public int getCount() {
return 2;
}
}
public void fetchOrders() {
if (mOrderTask != null) {
return;
}
progress.show();
mOrderTask = new OrderTask(getActivity());
mOrderTask.execute((Void) null);
}
public class OrderTask extends AsyncTask<Void, Void, Boolean> {
private final Activity mActivity;
OrderTask(Activity activity) {
mActivity = activity;
}
#Override
protected Boolean doInBackground(Void... params) {
userFunctions = new UserFunctions();
orderFunctions = new OrderFunctions();
return orderFunctions.getList(userFunctions.getToken(mActivity));
}
#Override
protected void onPostExecute(final Boolean success) {
mOrderTask = null;
progress.dismiss();
if (success) {
mOrderList = UserProfile.getOrders();
//attaching the view pager to adapter here!
mPager = (ViewPager) view.findViewById(R.id.pager);
mTabs = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs);
mTabs.setDistributeEvenly(true);
mTabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
#Override
public int getIndicatorColor(int position) {
return getResources().getColor(R.color.white);
}
});
mPager.setAdapter(new MyPagerAdapter(getChildFragmentManager()));
mTabs.setViewPager(mPager);
} else {
//Error handling stuff
}
}
}
}
PlacedOrders.java(Children Fragments)
public class PlacedOrders extends android.support.v4.app.Fragment {
private static String flag;
private int dateFlag;
private PlacedOrdersListener mListener;
UserFunctions userFunctions = null;
OrderFunctions orderFunctions = null;
private PlacedOrdersAdapter ordersAdapter;
private ProgressDialog progress;
private List<Order> mOrderList;
private List<Order> mPendingOrderList;
private List<Order> mCompletedOrderList;
public static PlacedOrders newInstance(int date) {
PlacedOrders fragment = new PlacedOrders();
Bundle args = new Bundle();
args.putInt(flag, date);
fragment.setArguments(args);
return fragment;
}
public void getOrderList(List<Order> orderList) {
this.mOrderList = orderList;
}
public PlacedOrders() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
dateFlag = getArguments().getInt(flag);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mPendingOrderList = new ArrayList<Order>();
mCompletedOrderList = new ArrayList<Order>();
return inflater.inflate(R.layout.fragment_placed_orders, container, false);
}
#Override
public void onResume() {
super.onResume();
displayOrders();
}
private void displayOrders() {
if (isVisible() && (mOrderList != null)) {
mPendingOrderList.clear();
mCompletedOrderList.clear();
ListView listViewOrder = (ListView) getView().findViewById(R.id.orderList);
if(dateFlag == Constants.DATE_TODAY_FUTURE) {
for(int i = 0; i < mOrderList.size(); i++) {
String status = mOrderList.get(i).status;
if(status.equals("PENDING") || status.equals("PROCESSING")) {
mPendingOrderList.add(mOrderList.get(i));
ordersAdapter = new PlacedOrdersAdapter(mPendingOrderList, getActivity().getLayoutInflater());
listViewOrder.setAdapter(ordersAdapter);
}
}
}
else if(dateFlag == Constants.DATE_PAST) {
for(int i = 0; i < mOrderList.size(); i++) {
String status = mOrderList.get(i).status;
if(status.equals("COMPLETE")) {
mCompletedOrderList.add(mOrderList.get(i));
ordersAdapter = new PlacedOrdersAdapter(mCompletedOrderList, getActivity().getLayoutInflater());
listViewOrder.setAdapter(ordersAdapter);
}
}
}
listViewOrder.setOnItemClickListener(new AdapterView.OnItemClickListener() {
//Display a new fragment on clicking
});
}
}
}

I had same issue and this was my solution :
In container fragment (fragment that contains tabs) in onViewCreated() method I created startFetch() method:
#Override
public void onViewCreated(View v, Bundle savedInstanceState) {
super.onViewCreated(v, savedInstanceState);
mViewPager = (ViewPager) v.findViewById(R.id.home_tab_pager);
mTabsHost= (TabLayout) getActivity().findViewById(R.id.appTabs);
startFetch();
}
Then in startFetch method i use Volley request and in onResponse method i update data and then add tabs :
public void startFetch(){
//Create volley request
String url = BuildConfig.API_GET_CATEGORIES;
final RequestQueue queue = VolleyService.getInstance(this.getContext()).getRequestQueue();
StringRequest request = new StringRequest(url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// we got the response, now our job is to handle it
try {
updateCategoryData(response);
} catch (RemoteException | OperationApplicationException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//something happened, treat the error.
Log.e("ErrorFETCH", error.networkResponse.toString());
}
});
queue.add(request);
}
My udpateCategory() method :
public void updateCategoryData(final String stream) throws RemoteException, OperationApplicationException {
//Update the data to SQLITE
setupTabs();
}
My setupTabs() method :
public void setUpTabs(){
ArrayList<Category> categories = new ArrayList<>();
Cursor data = getActivity().getContentResolver().query(
Category.Entry.CONTENT_URI, // URI
Category.PROJECTION, // Projection
Category.Entry.COLUMN_NAME_PARENT_ID + " = ?", // Selection
new String[]{"0"}, // Selection args
null);
if (data != null) {
while(data.moveToNext()){
categories.add(new Category(data));
}
}
TabsPagerAdapter mAdapter = new TabsPagerAdapter(getActivity().getSupportFragmentManager(), this.getActivity(), categories);
mViewPager.setAdapter(mAdapter);
mTabsHost.setupWithViewPager(mViewPager);
}

Related

Using only one Fragment with RecyclerView for multiple TabLayout , not updating data correctly on tabs change

There is a question similar to me, but that solution didn't work for my case.
The question I have referred is
this
I have a fragment named "HomeFragment" which consists of a VieWPager and TabLayout. I am adding tabs dynamically from the backend. So I am using another Fragment named "SecondFragment" for all tabs since all tabs contain a RecyclerView only. I am populating the RecyclerView onCreate() of the SecondFragment. My issue comes here that when I swipe or change the tab, the RecyclerView not updating correctly. On continuing swiping, the data changes but it does not correspond to the selected tab. I have logged the flow and I am getting correct data from backend on swiping, but it does not updating the RrecyclerView.
My HomeFragment class is
public class HomeFragment extends Fragment implements HTTPCallback {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private OnFragmentInteractionListener mListener;
private RecyclerView recyclerView;
private CardView cardview;
private boolean isShow;
View rootview;
private Toolbar toolbar;
private ImageView imageView, tabBg;
private CollapsingToolbarLayout collapsingToolbar;
private TabLayout mTabLayout;
Context context;
private ViewPager mViewPager, mViewPager1;
AppBarLayout appBarLayout;
Integer url_size;
int i;
boolean stopSliding = false;
String url, url2;
String message, version;
private ArrayList<HomeModel> planList;
JSONObject jsonObject, jsonObject2;
JSONArray jsonArray, jsonArray2;
ViewPagerAdapter adapter;
List<Product> products;
int numTab = 0;
private SharedPreferences sharedPreferences;
private SharedPreferences.Editor editor;
public HomeFragment() {
}
public static HomeFragment newInstance(String param1, String param2) {
HomeFragment fragment = new HomeFragment();
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) {
rootview = inflater.inflate(R.layout.fragment_home, container, false);
appBarLayout = (AppBarLayout) rootview.findViewById(R.id.appbar);
mViewPager1 = (ViewPager) rootview.findViewById(R.id.view_pager);
collapsingToolbar = (CollapsingToolbarLayout) rootview.findViewById(R.id.collapsing_toolbar);
sharedPreferences = getContext().getSharedPreferences("spade", Context.MODE_PRIVATE);
editor = sharedPreferences.edit();
mViewPager = (ViewPager) rootview.findViewById(R.id.viewpager);
mTabLayout = (TabLayout) rootview.findViewById(R.id.tabs);
mTabLayout.setSelectedTabIndicatorColor(Color.parseColor("#FF0000"));
mTabLayout.setSelectedTabIndicatorHeight((int) (5 * getResources().getDisplayMetrics().density));
mTabLayout.setTabTextColors(Color.parseColor("#727272"), Color.parseColor("#FF0000"));
new HTTPRequest(getContext(), null, null, HTTPRequest.METHOD.GET, this).execute(url2);
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if (position == 0) {
appBarLayout.setExpanded(true);
} else {
appBarLayout.setExpanded(false);
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
try {
} catch (Exception e) {
e.printStackTrace();
}
mTabLayout.setOnTabSelectedListener(
new TabLayout.ViewPagerOnTabSelectedListener(mViewPager) {
#Override
public void onTabSelected(TabLayout.Tab tab) {
super.onTabSelected(tab);
mViewPager.setCurrentItem(tab.getPosition());
numTab = tab.getPosition();
HomeModel browsePlan = planList.get(numTab);
editor.putString("tab", browsePlan.getName()).commit();
}
});
return rootview;
}
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onConnectionStarted() {
}
#Override
public void onConnectionFailed() {
}
#Override
public void onCompleted(JSONObject resultData) {
HomeModel model;
planList = new ArrayList<>();
adapter = new ViewPagerAdapter(getChildFragmentManager());
try {
jsonArray = resultData.getJSONArray("details");
editor.putString("tab", jsonArray.getJSONObject(0).getString("name"));
editor.commit();
for (int i = 0; i < jsonArray.length(); i++) {
jsonObject2 = jsonArray.getJSONObject(i);
model = new HomeModel();
model.setCatid(jsonObject2.getString("id"));
model.setImage(jsonObject2.getString("image"));
model.setName(jsonObject2.getString("name"));
planList.add(model);
setupViewPager(mViewPager, jsonObject2.getString("name"));
}
setAdapter();
} catch (JSONException e) {
e.printStackTrace();
}
}
private void setAdapter() {
appBarLayout.setExpanded(false);
mViewPager.setAdapter(adapter);
mTabLayout.setupWithViewPager(mViewPager);
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
private void setupViewPager(ViewPager mViewPager, String name) {
adapter.addFragment(new SecondFragment(), name);
mViewPager.setOffscreenPageLimit(1);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
SecondFragment class is
public class SecondFragment extends Fragment implements HTTPCallback {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
String mParam1;
String mParam2;
Button solo, grp;
View rootview;
Fragment fragment;
String url;
JSONObject jsonObject, jsonObject2;
JSONArray jsonArray, jsonArray2;
private ArrayList<Spaceship> planList;
RecyclerView rv;
private RecyclerHomeAdapter adapter = new RecyclerHomeAdapter(getContext(), planList);
;
private SharedPreferences sharedPreferences;
String tab_name;
private OnFragmentInteractionListener mListener;
public SecondFragment() {
}
public static SecondFragment newInstance(String s, String s1) {
SecondFragment fragment = new SecondFragment();
Bundle args = new Bundle();
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) {
rootview = inflater.inflate(R.layout.fragment_second, container, false);
sharedPreferences = getContext().getSharedPreferences("spade", Context.MODE_PRIVATE);
tab_name = sharedPreferences.getString("tab", "onnumilla");
rv = (RecyclerView) rootview.findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(getContext()));
url = "My_url_here";
HashMap<String, String> data = new HashMap<String, String>();
data.put("name", tab_name);
new HTTPRequest2(getContext(), data, null, HTTPRequest2.METHOD.POST, this).execute(url);
return rootview;
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
adapter.notifyDataSetChanged();
// getFragmentManager().beginTransaction().detach(this).attach(this).commit();
}
}
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onConnectionStarted() {
}
#Override
public void onConnectionFailed() {
}
#Override
public void onCompleted(JSONObject resultData) {
Spaceship model;
planList = new ArrayList<>();
planList.clear();
try {
jsonArray = resultData.getJSONArray("products");
for (int i = 0; i < jsonArray.length(); i++) {
jsonObject2 = jsonArray.getJSONObject(i);
model = new Spaceship();
model.setName(jsonObject2.getString("package_name"));
model.setImage(jsonObject2.getString("images"));
planList.add(model);
}
setAdapter();
} catch (JSONException e) {
e.printStackTrace();
}
}
private void setAdapter() {
adapter = new RecyclerHomeAdapter(getContext(), planList);
adapter.notifyDataSetChanged();
rv.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
This doesn't work for me. But in the setUserVisibleHint(boolean isVisibleToUser) method when i add getFragmentManager().beginTransaction().detach(this).attach(this).commit();
instead of adapter.notifyDataSetChanged(); it works but it takes some time to hide previous data on swiping tab.
Anyone, please suggest me a solution. I have referred many questions but nothing works for me. All your response is appreciated.
This seems to be ViewPager page cashing issue. pls call below code from onCreateView()
of HomeFragment.
mViewPager.setOffscreenPageLimit(1);

How to use the instance of a same Fragment with different data across pages of a viewPager?

I am using different instance of the same fragment in a viewPager.Because every page does the same thing but only differ by data.But the problem is viewPager shows same data in all pages.Creating new instance in the adapter does not change the data.All what i want is when the user swipes to new page it shows a new instance of the same fragment as shown in the adapter respective to the position.
Here is the adapter :
public class FragmentPageAdapter extends FragmentPagerAdapter {
public FragmentPageAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
if (position == 0) {
ListViewFragment f = ListViewFragment.newInstance("https://newsapi.org/v1/articles?source=al-jazeera-english&sortBy=top&apiKey=6cde");
return f;
}
else if (position == 1){
return ListViewFragment.newInstance("https://newsapi.org/v1/articles?source=abc-news-au&sortBy=top&apiKey=6cde");
}
else
{
return ListViewFragment.newInstance("https://newsapi.org/v1/articles?source=bbc-news&sortBy=top&apiKey=6cde");
}
}
#Override
public int getCount() {
return 3;
}
}
And this activity holds the viewPager:
public class WorldNews extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_world_news);
// Find the view pager that will allow the user to swipe between fragments
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
// Create an adapter that knows which fragment should be shown on each page
FragmentPageAdapter adapter = new FragmentPageAdapter(getSupportFragmentManager());
// Set the adapter onto the view pager
viewPager.setAdapter(adapter);
}
}
Here is the code for the Fragment(Just a normal fragment which implements loader):
public class ListViewFragment extends Fragment implements LoaderManager.LoaderCallbacks<List<GameNews>> {
public static ListViewFragment newInstance(String url) {
Log.d("ListViewFragment","newInstance created");
ListViewFragment f = new ListViewFragment();
// Supply url input as an argument.
Bundle args = new Bundle();
args.putString("url", url);
f.setArguments(args);
return f;
}
private AdView mAdView;
AdRequest adRequest;
ListAdapter adapter ;
private View progressBar;
final private int game_loader = 0;
ArrayList<String> urls = new ArrayList<>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_list_view, container, false);
//Log.d("ListViewFragment","" + getArguments().getString("url"));
mAdView = (AdView) rootView.findViewById(R.id.adView);
adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
final LinearLayout emptyView = (LinearLayout) rootView.findViewById(R.id.no_internet_view);
emptyView.setVisibility(View.INVISIBLE);
//Getting listView
final ListView gameListView = (ListView) rootView.findViewById(R.id.listView);
//progress bar finding
progressBar = rootView.findViewById(R.id.progress_bar);
ArrayList<GameNews> gameList = new ArrayList<>();
Button retryButton = (Button) rootView.findViewById(R.id.retry_button);
//Making a new arrayAdapter
adapter = new ListAdapter(getActivity(),gameList);
//Connecting ArrayAdapter to ListView
gameListView.setAdapter(adapter);
urls.add(getArguments().getString("url"));
Log.d("ListViewFragment","" + urls.get(0));
if(isConnected())
{
getActivity().getLoaderManager().initLoader(game_loader, null, this);
}
else
{
emptyView.setVisibility(View.VISIBLE);
gameListView.setVisibility(View.INVISIBLE);
}
//ListView item click listner
gameListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
GameNews currentEarthquake = adapter.getItem(i);
String url = currentEarthquake.getUrl();
final Intent intent = new Intent(getContext(), browser.class);
intent.putExtra("Url", url);
startActivity(intent);
}
});
retryButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(isConnected())
{
mAdView.loadAd(adRequest);
getActivity().getLoaderManager().restartLoader(game_loader, null, ListViewFragment.this);
emptyView.setVisibility(View.INVISIBLE);
gameListView.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.VISIBLE);
Log.d("General news","retry clicked");
}
}
});
return rootView;
}
public boolean isConnected() {
ConnectivityManager manager = (ConnectivityManager)getActivity().getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo info = manager.getActiveNetworkInfo();
if (info != null && info.isConnected()) {
return true;
} else {
return false;
}
}
#Override
public Loader<List<GameNews>> onCreateLoader(int i, Bundle bundle) {
AdManager manager = new AdManager(getActivity());
return new GameLoader(getActivity(),urls,1000);
}
#Override
public void onLoadFinished(Loader<List<GameNews>> loader, List<GameNews> games) {
progressBar.setVisibility(View.INVISIBLE);
adapter.clear();
if(games == null)
{
return;
}
adapter.addAll(games);
}
#Override
public void onLoaderReset(Loader<List<GameNews>> loader) {
adapter.clear();
}
public void setUrl(String url)
{
this.urls.add(url);
}
}
Try to use FragmentStatePagerAdapter https://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter instead of FragmentPagerAdapter. Difference between them: here for example.

Communicating between 2 fragments in a Viewpager - Updating RecyclerView in Fragment B from Fragment A

I'm building a simple stock display app that allows you to fetch stocks of interest (frag A), store them in a TinyDB, and display them in a recyclerView (frag B).
The framework used to work fine - until I decided to incorporate a viewpager and Tablayout host. I cannot get the RecyclerView in Frag B to display new data live. This is because the activity viewpager initializes both fragments at launch, meaning you can't call the onCreateView code again, I believe.
Communicating between two fragments through an Activity has been touched before on this site, but I found the best example to be this one:
(https://github.com/kylejablonski/InterfaceDemo),
which uses two interfaces, one to communicate from Frag A to Activity, and another one to communicate from Activity to Frag B. But I have a serious problem -
Currently, clicking both the "clear portfolio" and "add stock" to portfolio buttons in Frag A result in an empty screen in Frag B, which means something is being called yet new data is not being displayed/associated with the Adapter
Activity (https://github.com/EXJUSTICE/Investr/blob/master/app/src/main/java/com/xu/investo/ViewHolderActivity.java)
public class ViewHolderActivity extends AppCompatActivity implements CommunicateToActivity,CommunicateToFragment{
//Job of ViewHolderActivity is to allow swiping between list and MainFragment/Fragment
TabLayout tablayout;
ViewPager viewPager;
List<HistoricalQuote> historicaldata;
Bundle bundle;
Adapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_holder);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
viewPager =(ViewPager)findViewById(R.id.viewpager);
tablayout= (TabLayout)findViewById(R.id.tabs);
tablayout.setupWithViewPager(viewPager);
setupViewPager(viewPager);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
//----------------------- Interface code-----------
#Override
public void communicateup(){
communicatedown();
//call communicate down STRAIGHT, since we call it from mainfrag
}
#Override
public void communicatedown(){
//This line works
ListFragment currentFragment =(ListFragment)adapter.instantiateItem(viewPager,1);
currentFragment.refreshUI();
}
private void setupViewPager(ViewPager viewPager) {
adapter = new Adapter(getSupportFragmentManager());
adapter.addFragment(new MainFragment(), "Add Stock");
adapter.addFragment(new ListFragment(), "Portfolio");
viewPager.setAdapter(adapter);
}
static class Adapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public Adapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
Frag A (MainFragment)
(https://github.com/EXJUSTICE/Investr/blob/master/app/src/main/java/com/xu/investo/MainFragment.java)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view =inflater.inflate(R.layout.content_main,container,false);
stocknames = new ArrayList<String>();
stocktickers = new ArrayList<String>();
tinyDB = new TinyDB(getContext());
/*
menu.setDisplayShowHomeEnabled(true);
//menu.setLogo("INSERT LOGO HERE");
menu.setDisplayUseLogoEnabled(true);
menu.setTitle(" Stock Selector");
*/
fetch =(Button) view.findViewById(R.id.fetchBtn);
enterID =(EditText)view.findViewById(R.id.enterID);
display =(TextView)view.findViewById(R.id.display);
mCalendar = Calendar.getInstance();
clear = (Button)view.findViewById(R.id.clearportfolio);
fetch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//TODO all the main page should do is add stocktickers and names to portfolio
//Fetch id and the dates
id =enterID.getText().toString();
/*to = Calendar.getInstance();
from = Calendar.getInstance();
to.setTime(dateto);
from.setTime(datefrom);
*/
FetchXDayData getData = new FetchXDayData();
getData.execute(id);
}
});
clear.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
tinyDB.clear();
recyclerinterface.communicateup();
}
});
return view;
}
//----------------------------INTERFACE CODE
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
recyclerinterface = (CommunicateToActivity) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement RecyclerUpdateInterface");
}
}
///-------End of Oncreate---------------------------------------------------------------
//Called by AsyncTask, moving result to main thread
public void moveResultToUI(Stock result){
this.stock = result;
Toast.makeText(getActivity(),"Stock "+stock.getName()+" successfully added to portofolio",Toast.LENGTH_LONG).show();
//reverse the list of course, stock names and tickrs to portfolio
stocknames.add(stock.getName());
stocktickers.add(stock.getSymbol());
/*DEBUG Test code, Test. 30012017 WORKS
for (int i =0;i<historicaldata.size();i++){
HistoricalQuote current = historicaldata.get(i);
Toast toast = Toast.makeText(this,current.getClose().toString(),Toast.LENGTH_SHORT);
toast.show();
}
*/
//
if (stock != null){
display.setText("Name: "+stock.getName() +"\n"+"Price: "+ stock.getQuote().getPrice()+"\n"+ "Change(%)"+stock.getQuote().getChangeInPercent());
/*SMA = getSMA(10);
decision=checkSimpleCrossover(SMA,stock.getQuote().getPrice().longValue());
decisionView.setText("SMA: " + SMA + "\n"+decision);
*/
tinyDB.putListString("names",stocknames);
tinyDB.putListString("tickers",stocktickers);
//call interface activity comming up to Activity, then down to next fragment
recyclerinterface.communicateup();
}else{
Toast error = Toast.makeText(getActivity(),"Network Problem",Toast.LENGTH_SHORT);
error.show();
}
}
Frag B (ListFragment)
(https://github.com/EXJUSTICE/Investr/blob/master/app/src/main/java/com/xu/investo/ListFragment.java)
public class ListFragment extends Fragment {
private HistoricalQuote[] hisstocks;
private Stock[] stocks;
private RecyclerView recyclerView;
private StockAdapter mAdapter;
public ArrayList<String> stocknames;
public ArrayList<String>stocktickers;
TinyDB tinyDB;
#Override
public void onCreate(Bundle savedInstanceState){
//exists only to set the options menu
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
//fetching arraylists
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.content_list, container, false);
//Convert the arraylist into an array for arrayadapter
stocknames = new ArrayList<String>();
stocktickers = new ArrayList<String>();
tinyDB = new TinyDB(getContext());
stocknames = tinyDB.getListString("names");
stocktickers= tinyDB.getListString("tickers");
if (!stocknames.isEmpty()){
for (int i =0;i<stocknames.size();i++){
Toast toast= Toast.makeText(getActivity(),stocknames.get(i),Toast.LENGTH_SHORT);
toast.show();
}
}
recyclerView = (RecyclerView)view.findViewById(R.id.recylerView);
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.HORIZONTAL));
//http://stackoverflow.com/questions/24618829/how-to-add-dividers-and-spaces-between-items-in-recyclerview
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
//layoutManager necessary because it positions views on screen, in this case linearly
if (stocknames.isEmpty() ||stocknames ==null){
recyclerView.setVisibility(View.GONE);
}else{
updateUI();
}
return view;
}
public void refreshUI(){
stocknames.clear();
stocktickers.clear();
stocknames = tinyDB.getListString("names");
stocktickers= tinyDB.getListString("tickers");
if (mAdapter == null) {
mAdapter = new StockAdapter(stocknames,stocktickers);
recyclerView.setAdapter(mAdapter);
} else {
recyclerView.invalidate();
mAdapter.notifyDataSetChanged();
}
}
public void updateUI() {
//updateUI must be called EXPLICITLY!
stocknames = tinyDB.getListString("names");
stocktickers= tinyDB.getListString("tickers");
if (mAdapter == null) {
mAdapter = new StockAdapter(stocknames,stocktickers);
recyclerView.setAdapter(mAdapter);
} else {
mAdapter.notifyDataSetChanged();
}
}
private class StockAdapter extends RecyclerView.Adapter<StockHolder>{
private ArrayList<String>stocknames;
private ArrayList<String>stocktickers;
public StockAdapter(ArrayList<String>names,ArrayList<String> tickers){
this.stocknames=names;
this.stocktickers=tickers;
}
#Override
public StockHolder onCreateViewHolder(ViewGroup parent, int viewType){
LayoutInflater layoutinflater = LayoutInflater.from(getActivity());
View view= layoutinflater.inflate(R.layout.row,parent,false);
return new StockHolder (view);
}
//Bind datato stockholder depending on position in arraylist
public void onBindViewHolder(StockHolder holder, int position){
String stockname = stocknames.get(position);
String stockticker =stocktickers.get(position);
holder.bindStock(stockname,stockticker);
}
#Override
public int getItemCount (){
return stocknames.size();
}
}
private class StockHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private String stockname;
private String stockticker;
private TextView nametextView;
private TextView tickertextView;
public StockHolder(View itemView){
super(itemView);
itemView.setOnClickListener(this);
nametextView =(TextView)itemView.findViewById(R.id.name);
tickertextView= (TextView)itemView.findViewById(R.id.ticker);
}
#Override
public void onClick(View v){
Intent launchGraph= new Intent(v.getContext(),GraphActivity.class);
launchGraph.putExtra("stockticker",stockticker);
launchGraph.putExtra("stockname",stockname);
startActivity(launchGraph);
//Animations?
}
//Actual binder method, maybe add a current
public void bindStock(String stocknom, String stocktick){
this.stockname=stocknom;
this.stockticker = stocktick;
nametextView.setText(stockname);
tickertextView.setText(stockticker);
}
}
Thanks in advance.
EDIT: Solved issue by creating a new adapter and linking it to new arraylists pulled from the TinyDB, thereby effectively swapping adapters.
Solved the issue by creating a whole new RecyclerView adapter, to which new arraylist data was binded to, and the whole recyclerview was then set to use this new adapter. All of this was done in a single step from FragA, using interfaces shown in the code in the solution.
Method shown below:
public void refreshUI(){
tinyDB = null;
tinyDB = new TinyDB(getContext());
newnames = tinyDB.getListString("names");
newtickers= tinyDB.getListString("tickers");
mAdapter = new StockAdapter(newnames,newtickers);
recyclerView.setAdapter(mAdapter);
}

RecyclerView Adapter Conflict in a TabLayout

I have a TabLayout with 4 tabs in my Activity and I have made a Fragment per each Tab.
Below is my Activity code:
public class MyActivity extends AppCompatActivity {
private static final String TAG = "RecyclerView";
private Toolbar toolbar;
private static ViewPager viewPager;
private static TabLayout tabLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* Allow activity to show indeterminate progressbar */
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.student_regulations_list);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) findViewById(R.id.viewPager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.setupWithViewPager(viewPager);
tabLayout.setOnTabSelectedListener(onTabSelectedListener(viewPager));
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new Fragment1(), getString(R.string.titleA));
adapter.addFragment(new Fragment2(), getString(R.string.titleB));
adapter.addFragment(new Fragment3(), getString(R.string.titleC));
adapter.addFragment(new Fragment4(), getString(R.string.titleD));
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(3);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
}
private TabLayout.OnTabSelectedListener onTabSelectedListener(final ViewPager viewPager) {
return new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());//setting current selected item over viewpager
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
};
}
//View Pager fragments setting adapter class
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();//fragment arraylist
private final List<String> mFragmentTitleList = new ArrayList<>();//title arraylist
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
//adding fragments and title method
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
I have a RecyclerView in each fragment, and I fetch data from a Web Service using AsyncTask to show in the RecyclerView. Each item in RecyclerView has an ID and I want to When I switch between tabs and click on an item in RecyclerView, a Toast shows it's ID.
Below is a Fragment code:
public class Fragment1 extends Fragment implements ClickListener {
private static final String TAG = "RecyclerView";
private List<FeedItem> feedItemList;
private RecyclerView mRecyclerView;
private FeedsRecyclerAdapter mAdapter;
final String url = "a valid url";
private View rootView;
private ProgressBar progressBar;
public StuRegGeneralListFragment() {
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_student_regulations_list, container, false);
return rootView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
progressBar = (ProgressBar) rootView.findViewById(R.id.progress_bar);
/* Initialize recyclerview */
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
/*Downloading data from below url*/
new AsyncHttpTask().execute(url);
}
#Override
public void itemClicked(View view, int position) {
FeedItem item = feedItemList.get(position);
Intent intent = new Intent(getActivity(), JsonRequestFeedActivity.class);
intent.putExtra("url", Const.URL_JSON_OBJECT_REGS + item.getID());
intent.putExtra("pid", item.getID());
//startActivity(intent);
Toast.makeText(getActivity(), "Item ID: " + item.getID(), Toast.LENGTH_SHORT).show();
}
public class AsyncHttpTask extends AsyncTask<String, Void, Integer> {
#Override
protected void onPreExecute() {
progressBar.setVisibility(View.VISIBLE);
feedItemList = new ArrayList<FeedItem>();
}
#Override
protected Integer doInBackground(String... params) {
InputStream inputStream = null;
Integer result = 0;
HttpURLConnection urlConnection = null;
try {
/* forming th java.net.URL object */
URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
/* for Get request */
urlConnection.setRequestMethod("GET");
int statusCode = urlConnection.getResponseCode();
/* 200 represents HTTP OK */
if (statusCode == 200) {
BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line);
}
parseResult(response.toString());
result = 1; // Successful
} else {
result = 0; //"Failed to fetch data!";
}
} catch (Exception e) {
Log.d(TAG, e.getLocalizedMessage());
}
return result; //"Failed to fetch data!";
}
#Override
protected void onPostExecute(Integer result) {
progressBar.setVisibility(View.GONE);
/* Download complete. Lets update UI */
if (result == 1) {
updateRecyclerView();
} else {
Log.e(TAG, "Failed to fetch data!");
}
}
}
private void parseResult(String result) {
try {
JSONObject response = new JSONObject(result);
JSONArray posts = response.optJSONArray("posts");
/*Initialize array if null*/
if (null == feedItemList) {
feedItemList = new ArrayList<FeedItem>();
}
for (int i = 0; i < posts.length(); i++) {
JSONObject post = posts.optJSONObject(i);
FeedItem item = new FeedItem();
item.setID(post.optString("id"));
item.setDate(post.optString("date"));
item.setTitle(post.optString("title"));
item.setThumbnail(post.optString("thumbnail"));
feedItemList.add(item);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public void updateRecyclerView() {
mAdapter = new FeedsRecyclerAdapter(getActivity(), feedItemList);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setClickListener(this);
}
}
Assuming each fragment has 5 items in RecyclerView (from ID 1 to 5 in fragment1, from ID 6 to 10 in fragment2, ...) I expect when I enter to my Activity and click on an item in fragment1 (for example first item), ID=1 be shown in Toast, but ID=16 is shown!
In fact because of viewPager.setOffscreenPageLimit(3); in my Activity, fragment1 and fagment2 and fragment3 and fragment4 are created and at the end, mAdapter contains item IDs 16-20, although I am in fragment1.
I expect after creating specified fragments by viewPager.setOffscreenPageLimit(int); each fragment has it's own adapter, but it's not happened.
Any help is appreciated.
I found out my mistake!
My Activity and Fragments code are correct, my mistake was in ClickListener of RecyclerView. It's implementation was not suitable in my case.
I had used a static clickListener in it, that was the point!

Android - Sending data from fragment to fragment using swipeview

Could be this is a dupe, but I've been looking for solutions and they always slightly differ from my problem.
So:
I'm currently creating an app that has 2 fragments that are swipeable. TaskGroupFragment shows a list and when you click on an item it wil slide to TasksFragment and show you a sublist. What I have to do now is send the id of the selected item from groups to tasks so I can get the sublist out of SQLite.
I know I'm supposed to communicate through the connected MainActivity and I'm already at the point that I've created an interface in TaskGroupsFragment and implemented this in the activity. Tried and tested and the activity receives the TaskGroupID.
The part where I'm stuck is getting this info in TasksFragment. Especially using swipeview makes this harder.
My code:
MainPagerAdapter:
public class MainPagerAdapter extends FragmentStatePagerAdapter {
public MainPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
switch (i) {
case 0: return TaskGroupFragment.newInstance();
case 1: return TasksFragment.newInstance();
default: return TaskGroupFragment.newInstance();
}
}
#Override
public int getCount() {
return 2;
}
}
TaskGroupActivity (sending fragment):
public class TaskGroupFragment extends ListFragment {
private DoItDataSource dataSource;
private List<TaskGroups> groups;
#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.fragment_task_group, container, false);
dataSource = new DoItDataSource(getActivity());
dataSource.open();
JSONContainer jsonContainer = dataSource.sqliteToContainer();
dataSource.close();
groups = jsonContainer.getTask_groups();
TaskGroupAdapter adapter = new TaskGroupAdapter(getActivity(), groups);
setListAdapter(adapter);
return view;
}
public static TaskGroupFragment newInstance() {
TaskGroupFragment tgf = new TaskGroupFragment();
return tgf;
}
public interface OnTaskGroupSelectedListener {
public void onTaskGroupSelected(String taskGroupId);
}
OnTaskGroupSelectedListener mListener;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnTaskGroupSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " Interface not implemented in activity");
}
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
((MainActivity)getActivity()).setCurrentItem(1, true);
mListener.onTaskGroupSelected(groups.get(position).getId());
}
}
MainActivity:
public class MainActivity extends FragmentActivity implements
TaskGroupFragment.OnTaskGroupSelectedListener{
private SharedPreferences savedValues;
private DoItDataSource dataSource = new DoItDataSource(this);
private String identifier, user, domain;
private JSONContainer containerToday;
private JSONContainer containerTomorrow;
public ViewPager pager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
savedValues = getSharedPreferences("SavedValues", MODE_PRIVATE);
identifier = savedValues.getString("Identifier", "");
pager = (ViewPager) findViewById(R.id.activity_main_pager);
pager.setAdapter(new MainPagerAdapter(getSupportFragmentManager()));
if (identifier == null || identifier.equals("")) {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
intent.putExtra("APP_ID", APP_ID);
startActivity(intent);
}
}
#Override
protected void onResume() {
super.onResume();
identifier = savedValues.getString("Identifier", "");
user = savedValues.getString("User", "");
domain = savedValues.getString("Domain", "");
boolean onBackPressed = savedValues.getBoolean("OnBackPressed", false);
//
// getting lists
//
}
private void resultHandling(String json, String day) {
if (day.equals("today")) {
Gson gson = new Gson();
containerToday = gson.fromJson(json, JSONContainer.class);
jsonToSQLite(containerToday, "Today");
} else if (day.equals("tomorrow")) {
Gson gson = new Gson();
containerTomorrow= gson.fromJson(json, JSONContainer.class);
jsonToSQLite(containerTomorrow, "Tomorrow");
}
}
String taskGroupId = "";
#Override
public void onTaskGroupSelected(String taskGroupId) {
this.taskGroupId = taskGroupId;
// Enter missing link here?
}
}
TaskFragment (receiving fragment):
public class TasksFragment extends ListFragment
implements OnClickListener {
private final static String TAG = "TaskItemFragment logging";
private DoItDataSource dataSource;
private List<Tasks> tasks;
#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.fragment_task_item, container, false);
Button backButton = (Button)
view.findViewById(R.id.fragment_task_item_bar_back_button);
dataSource = new DoItDataSource(getActivity());
dataSource.open();
tasks = dataSource.getTasks("204"); // 204 is a placeholder, TaskGroupId should be here
dataSource.close();
TasksAdapter adapter = new TasksAdapter(getActivity(), tasks);
setListAdapter(adapter);
backButton.setOnClickListener(this);
return view;
}
public static TasksFragment newInstance() {
TasksFragment tif = new TasksFragment();
return tif;
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Toast.makeText(getActivity(), "Clicked item " + position, Toast.LENGTH_LONG).show();
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.fragment_task_item_bar_back_button:
((MainActivity)getActivity()).setCurrentItem(0, true);
break;
}
}
}
Solution
Thanks to Alireza! I had to make several changes to his proposed code, but in the end it helped me in finding the solution!
MainPageAdapter:
public class MainPagerAdapter extends FragmentStatePagerAdapter {
// ADDED
private String taskGroupId;
public MainPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
switch (i) {
case 0: return TaskGroupFragment.newInstance();
// MODIFIED
case 1:
Bundle args = new Bundle();
logcat("before setBundle " + taskGroupId);
args.putString("taskGroupId",taskGroupId);
Fragment fragment = new TasksFragment();
fragment.setArguments(args);
return fragment;
default: return TaskGroupFragment.newInstance();
}
}
// ADDED
public void setTaskGroupId(String id){
this.taskGroupId = id;
}
#Override
public int getCount() {
return 2;
}
}
MainActivity:
public class MainActivity extends FragmentActivity implements
TaskGroupFragment.OnTaskGroupSelectedListener{
private SharedPreferences savedValues;
private DoItDataSource dataSource = new DoItDataSource(this);
private String identifier, user, domain;
private JSONContainer containerToday;
private JSONContainer containerTomorrow;
// ADDED
private MainPagerAdapter adapter;
public ViewPager pager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
savedValues = getSharedPreferences("SavedValues", MODE_PRIVATE);
identifier = savedValues.getString("Identifier", "");
// ADDED
adapter = new MainPagerAdapter(getSupportFragmentManager());
pager = (ViewPager) findViewById(R.id.activity_main_pager);
// MODIFIED
pager.setAdapter(adapter);
if (identifier == null || identifier.equals("")) {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
intent.putExtra("APP_ID", APP_ID);
startActivity(intent);
}
}
#Override
protected void onResume() {
super.onResume();
identifier = savedValues.getString("Identifier", "");
user = savedValues.getString("User", "");
domain = savedValues.getString("Domain", "");
boolean onBackPressed = savedValues.getBoolean("OnBackPressed", false);
//
// Getting lists
//
}
String taskGroupId = "";
#Override
public void onTaskGroupSelected(String taskGroupId) {
this.taskGroupId = taskGroupId;
// ADDED
adapter.setTaskGroupId(taskGroupId);
pager.setAdapter(adapter);
pager.setCurrentItem(1);
}
}
TaskFragment (receiving fragment):
public class TasksFragment extends ListFragment implements OnClickListener {
private final static String TAG = "TaskItemFragment logging";
private DoItDataSource dataSource;
private List<Tasks> tasks;
private String taskGroupId;
#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.fragment_task_item, container, false);
Button backButton = (Button) view.findViewById(R.id.fragment_task_item_bar_back_button);
dataSource = new DoItDataSource(getActivity());
// ADDED
Bundle bundle = getArguments();
taskGroupId = bundle.getString("taskGroupId");
// MODIFIED
dataSource.open();
tasks = dataSource.getTasks(taskGroupId);
dataSource.close();
TasksAdapter adapter = new TasksAdapter(getActivity(), tasks);
setListAdapter(adapter);
backButton.setOnClickListener(this);
return view;
}
// CAN BE REMOVED?
//public static TasksFragment newInstance() {
// TasksFragment tif = new TasksFragment();
// return tif;
//}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Toast.makeText(getActivity(), "Clicked item " + position, Toast.LENGTH_LONG).show();
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.fragment_task_item_bar_back_button:
((MainActivity)getActivity()).setCurrentItem(0, true);
break;
}
}
}
Please note that I'm using taskGroupId as a String, not an int.
First you need to make sure your adapter knows about taskGroupID. just add a variable and a public method to your adapter.
public class MainPagerAdapter extends FragmentStatePagerAdapter {
private int taskGroupId;
public void setTaskGroupId(int id){
this.taskGroupId = id;
}
}
then store a reference to your adapter in your activity. Now simply call this method whenever GroupId changes
#Override
public void onTaskGroupSelected(String taskGroupId) {
this.taskGroupId = taskGroupId;
adapter.setTastGroupId = taskGroupId; //data needed to initialize fragment.
adapter.setCurrentItem(1); //going to TasksFragment page
}
then you need to put some argumants before starting your fragment.
#Override
public Fragment getItem(int i) {
//this code is only for case 1:
Bundle args = new Bundle();
args.putInt("taskGroupId",taskGroupId);
Fragment fragment = new TasksFragment();
fragment.setArguments(args);
return fragment;
}
and lastly use this data in your TaskFragment to show the right content.

Categories

Resources