Notify RecyclerView adapter database changed - android

My MainActivity calls a fragment,
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, PlaceholderFragment.newInstance(position + 1),
"placeHolderFragmentTag")
.commit();
}
placeholderFragment that fills a RecyclerView with an adapter,
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dbHelper = new DatabaseHelper(getActivity().getApplicationContext());
dbHelper.getWritableDatabase();
dbHelper.openDataBase();
adapterUpcomingGames = new AdapterUpcomingGames(retrieveGames(dbHelper.getUpcomingGames()));
}
adapterUpcomingGames. The adapter gets data from a database that the user has entered, being a list of upcoming sporting events.
#Override // still placeholderFragment
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
switch(getArguments().getInt(ARG_SECTION_NUMBER))
{
case 1: // This will be upcoming games
mRecyclerView.setAdapter(adapterUpcomingGames);
break;
case 2: // This will be past games
AdapterPastGames adapterPastGames;
adapterPastGames = new AdapterPastGames(retrieveGames(dbHelper.getPastGames()));
mRecyclerView.setAdapter(adapterPastGames);
break;
default: // Default is, well, anything that will work.
adapterUpcomingGames1 = new AdapterUpcomingGames(retrieveGames(dbHelper.getGames()));
mRecyclerView.setAdapter(adapterUpcomingGames1);
}
newGame.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0){
Intent createGame = new Intent(getActivity(),
ActivityCreateGame.class);
startActivity(createGame);
adapterUpcomingGames.notifyDataSetChanged();
}
});
setRetainInstance(true);
}
With this view, there is an button to add games i.e. modify the database. I am achieving this by calling a new activity, activityCreateGame, that hosts a fragment,
#Override // activityCreateGame
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_game);
fragmentCreateGame = new FragmentCreateGame();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.attach(fragmentCreateGame)
.replace(R.id.newGameContainer, fragmentCreateGame)
.commit();
restoreActionBar();
}
fragmentCreateGame, that allows the user to enter in the desired information, and then append that to the database. The user saves this information using an option on the navbar within that activity.
#Override // activityCreateGame
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case android.R.id.home:
finish();
break;
case R.id.action_save:
// check if an error has occured
if (fragmentCreateGame.CreateNewGame())
{
Toast toast = Toast.makeText(this, R.string.toast_success_game_create,
Toast.LENGTH_SHORT);
toast.show();
finish();
}
else{
Toast toast = Toast.makeText(this, R.string.toast_failed_game_create,
Toast.LENGTH_SHORT);
toast.show();
}
break;
}
return super.onOptionsItemSelected(item);
}
That action finishes the activityCreateGame. Now, how do I go about notify the adapter, back in placeholderFragment that the database has been updated and thus update the RecyclerView to update itself?

From looking at your code, I can think of three solutions for you. In order of (my opinion) quality of the solution from least to best.
Move your fragment fragmentCreateGame to be hosted by you first activity
Start Activity For Result
Use Otto Event Bus. I would recommend otto. Especially if you may have multiple objects listening to an event.
First add Otto to your project. In your build.gradle, add this to your dependancies.
dependencies {
....
compile 'com.squareup:otto:1.3.6'
....
}
In your activity that needs notified, add this at the beginning of your onCreate:
Bus bus = new Bus();
bus.register(this);
Then, create an "event" class. It is just an object you pass to notify subscribers. You can add info to these too, to pass more info.
public class SomeCoolEvent{
private String yourWisdom;
public SomeCoolEvent(String yourWisdom){
this.yourWisdom = yourWisdom;
}
public String getWisdom(){
return yourWisdom;
}
}
Then, in your class that is doing something to notify other classes, do this:
Bus bus = new Bus();
bus.post(new SomeCoolEvent(yourWisdomStringFromThisClass));
Now, back to your first activity, add a method that is annotated with #Subscribe
#Subscribe
public void onAnyMethodNameYouWantCauseItDoesntMatter(SomeCoolEvent event){
//this will be called when ANY class calls bus.post(SomeCoolEvent)
String boomYouAreNotified = event.getWisdom();
}
On your #Subscribe method, few things to note.
* The method name does not matter, so give it something that makes sense to you. I like to prefix it with "on" because its like a callback.
* The method must be public and return void.
* You are not explicitly calling this methods, so some IDE's may appear that it is unused. Android studio will let you fix that with "ALT + ENTER" then select "_ignore warnings for methods annotated with Subscribe".
* You should call bus.unregister(this) on destroy.
* You can have multiple classes listening to one post.
Now things can get more complicated if you start running on different threads. If you do, there are solutions to this at the bottom of the Otto page I provided.

Related

Pass data from A and B fragments to C fragements

I have created three fragments A, B and C. In fragment A I'm having First Name and Last Name. In fragment B I'm having Age, City, Area and Address. In C I'm having Profession and Experience. In frag C I'm also having a button which sends all the info to the server. Now how can I have the info from fragment A and B in fragment C. I have used Bundle to send the info but it's a tedious task. Any simple method available?
E.g.:
Bundle args = new Bundle ();
args.putString ("first_name", strFirstName);
args.putString ("last_name", strLastName);
Instead of passing data from fragment A and B to C, pass them to the Activity via callback, and then pass the "send to server" action callback so that the Activity handles it:
class Fragment A {
// fragment definition
public interface OnUserInformationTypedListener {
public void onUserInformationTyped(String name, String lastName);
}
}
class FragmentB {
// fragment definition
public interface OnUserExtraInformationTypedListener {
public void onUserExtraInformationTyped(int age, String address);
}
}
class FragmentC {
// fragment definition
public interface OnUserCareerInformationTypedListener {
public void onUserCareerTyped(String profession, String experience);
public void onSendToServer();
}
}
Then make the Activity implements all interfaces:
class MyActivity extends Activity implements OnUserInformationTypedListener,
OnUserExtraInformationTypedListener, OnUserCareerInformationTypedListener {
#Override
public void onUserInformationTypedListener(String name, String lastName) {
// Probably pass local variable to private attributes
}
// Override the rest of the interface's methods
#Override
public void onSendToServer() {
// Send information to the server logic
}
}
And finally, make the FragmentA, FragmentB and FragmentC each one an instance of their respective callback, i.e:
// Inside FragmentA
private OnUserInformationTypedListener listener = null;
And then you pass the listener reference to it, Either by calling Fragment#onAttach(Activity) or via public method:
// Inside FragmentA
#Override
public void onAttach(Activity activity) {
listener = (OnUserInformationTypedListener) activity;
}
// if you prefer public setter then create the setter and call it from the Activity:
// Inside Activity#onCreate or wherever you instantiate the fragment
FragmentA fa = new FragmentA();
fa.setOnUserInformationTypedListener(this);
For more information on how to communicate Fragments via the host Activity (this is the right way to do it), read this http://developer.android.com/training/basics/fragments/communicating.html
The Fragment documentation says:
Often you will want one Fragment to communicate with another, for example to change the content based on a user event. All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly.
So, its not a good idea to pass message from one fragment to another. Check the basics fragment training docs
Any simple method available?
You can save the data in a common class, and access the same from the other fragments..
use this i want to pass data on button click like this
btn_camera.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
// set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);
}
});
and get data oncreate method of fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strtext = getArguments().getString("edttext");
return inflater.inflate(R.layout.fragment, container, false);
}

Why is onLoadFinished called again after fragment resumed?

I have a peculiar issue with Loaders. Currently I am unsure if this is a bug in my code or I misunderstand loaders.
The app
The issue arises with conversations (imagine something similar to Whatsapp).
The loaders I use are implemented based on the AsyncTaskLoader example. I am using the support library.
In OnCreate, I start a loader to retrieve cached messages.
When the CachedMessageLoader finishes, it starts a RefreshLoader to retrieve (online) the newest messages.
Each loader type as a distinct ID (say, offline:1 online:2)
This works very well, with the following exception.
Problem
When I open another fragment (and add the transaction to the backstack) and then use the Back-Key to go back to the conversationFragment, onLoadFinished is called again with both results from before.
This call happens before the fragment has had any chance to start a loader again...
This delivering of "old" results that I obtained before results in duplicated messages.
Question
Why are those results delivered again?
Do I use these loaders wrong?
Can I "invalidate" the results to ensure that I only get them delivered once or do I have to eliminate duplicates myself?
Stack trace of call
MyFragment.onLoadFinished(Loader, Result) line: 369
MyFragment.onLoadFinished(Loader, Object) line: 1
LoaderManagerImpl$LoaderInfo.callOnLoadFinished(Loader, Object) line: 427
LoaderManagerImpl$LoaderInfo.reportStart() line: 307
LoaderManagerImpl.doReportStart() line: 768
MyFragment(Fragment).performStart() line: 1511
FragmentManagerImpl.moveToState(Fragment, int, int, int, boolean) line: 957
FragmentManagerImpl.moveToState(int, int, int, boolean) line: 1104
BackStackRecord.popFromBackStack(boolean) line: 764
...
Update 1
The loaders mentioned here are initiated by the conversation fragment:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
Bundle args = getArguments();
m_profileId = args.getString(ArgumentConstants.ARG_USERID);
m_adapter = new MessageAdapter(this);
if (savedInstanceState != null) {
restoreInstanceState(savedInstanceState);
}
if (m_adapter.isEmpty()) {
Bundle bundle = new Bundle();
bundle.putString(ArgumentConstants.ARG_USERID, m_profileId);
getLoaderManager().restartLoader(R.id.loader_message_initial, bundle, this);
} else {
// Omitted: Some arguments passed in Bundle
Bundle b = new Bundle().
getLoaderManager().restartLoader(R.id.loader_message_refresh, b, this);
}
}
#Override
public void onResume() {
super.onResume();
// Omitted: setting up UI state / initiating other loaders that work fine
}
#Override
public AbstractMessageLoader onCreateLoader(final int type, final Bundle bundle) {
final SherlockFragmentActivity context = getSherlockActivity();
context.setProgressBarIndeterminateVisibility(true);
switch (type) {
case R.id.loader_message_empty:
return new EmptyOnlineLoader(context, bundle);
case R.id.loader_message_initial:
return new InitialDBMessageLoader(context, bundle);
case R.id.loader_message_moreoldDB:
return new OlderMessageDBLoader(context, bundle);
case R.id.loader_message_moreoldOnline:
return new OlderMessageOnlineLoader(context, bundle);
case R.id.loader_message_send:
sendPreActions();
return new SendMessageLoader(context, bundle);
case R.id.loader_message_refresh:
return new RefreshMessageLoader(context, bundle);
default:
throw new UnsupportedOperationException("Unknown loader");
}
}
#Override
public void onLoadFinished(Loader<Holder<MessageResult>> loader, Holder<MessageResult> holder) {
if (getSherlockActivity() != null) {
getSherlockActivity().setProgressBarIndeterminateVisibility(false);
}
// Omitted: Error handling of result (can contain exception)
List<PrivateMessage> unreadMessages = res.getUnreadMessages();
switch (type) {
case R.id.loader_message_moreoldDB: {
// Omitted error handling (no data)
if (unreadMessages.isEmpty()) {
m_hasNoMoreCached = true;
// Launch an online loader
Bundle b = new Bundle();
// Arguments omitted
getLoaderManager().restartLoader(R.id.loader_message_moreoldOnline, b, ConversationFragment.this);
}
// Omitted: Inserting results into adapter
}
case R.id.loader_message_empty: { // Online load when nothing in DB
// Omitted: error/result handling handling
break;
}
case R.id.loader_message_initial: { // Latest from DB, when opening
// Omitted: Error/result handling
// If we found nothing, request online
if (unreadMessages.isEmpty()) {
Bundle b = new Bundle();
// Omitted: arguments
getLoaderManager().restartLoader(R.id.loader_message_empty, b, this);
} else {
// Just get new stuff
Bundle b = new Bundle();
// Omitted: Arguments
getLoaderManager().restartLoader(R.id.loader_message_refresh, b, this);
}
break;
}
// Omitted: Loaders that do not start other loaders, but only add returned data to the adapter
default:
throw new IllegalArgumentException("Unknown loader type " + type);
}
// Omitted: Refreshing UI elements
}
#Override
public void onLoaderReset(Loader<Holder<MessageResult>> arg0) { }
Update 2
My MainActivity (which ultimatively hosts all fragments) subclasses SherlockFragmentActivity and basically launches fragments like this:
Fragment f = new ConversationFragment(); // Setup omitted
f.setRetainInstance(false);
// Omitted: Code related to navigation drawer
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.fragment_container_frame, f).commit();
The conversation fragment starts the "display profile" fragment like this:
DisplayProfileFragment f = new DisplayProfileFragment();
// Arguments omitted
FragmentManager manager = getSherlockActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.fragment_container_frame, f).addToBackStack(null).commit();
There are other similar questions such as Android: LoaderCallbacks.OnLoadFinished called twice However the behavior of the loader manager hooks are what they are. You can either destroy the loader after getting the first set of results
public abstract void destroyLoader (int id)
or you can handle the onLoaderReset and tie your UI data more closely to the loader data
public abstract void onLoaderReset (Loader<D> loader)
Called when a previously created loader is being reset, and thus
making its data unavailable. The application should at this point
remove any references it has to the Loader's data.
Personally, I would use a ContentProvider and a CursorLoader for this (each row of data would need to have a unique _ID but for messages that should not be a problem).
use following this in onResume()
#Override
public void onResume() {
super.onResume();
getLoaderManager().initLoader(0, null, this);
}
i solved my problem from this
this is same type Q

Fragment onResume() isn't called when using FragmentPagerAdapter

I need my fragments to always call a certain function when they are the active fragment, so I put it in onResume(), but it isn't being called.
Fragment A
#Override
public void onResume(){
super.onResume();
Log.d("clear state", " "+clear);
if(clear == true)
{
restart();
clear = false;
calculate();
}
}
I use a FragmentPagerAdapter with a ViewPager to switch fragments
public class ScoutingFragSingle extends FragmentPagerAdapter{
#Override
public Fragment getItem(int index) {
Bundle data = new Bundle();
switch(index){
case 0:
TeamsFragment teamsFragment = new TeamsFragment();
data.putInt("current_page", index+1);
teamsFragment.setArguments(data);
return teamsFragment;
case 1:
data.putInt("current_page", index+1);
data.putInt("matchId", matchNum);
aFragment.setArguments(data);
return aFragment;
So how would I make the fragments call their onResume()?
I had the same problem while ago.
Create a new interface and implement it by both of your Fragments:
public interface OnPageSelectedListener {
void onPageSelected();
}
In parent activity implement android.support.v4.view.ViewPager.OnPageChangeListener and call Fragment method like this:
#Override
public void onPageSelected(int i) {
OnPageSelectedListener fragment = (OnPageSelectedListener ((PlaceListPagerAdapter)pager.getAdapter()).getFragment(i);
fragment.onPageSelected();
}
PS: Name of the new interface and its method is a bit confusing, so be careful or change it.
Override Fragment.setUserVisibleHint. When setUserVisibleHint is true call same logic you use for onResume.
You can see when FragmentPagerAdapter calls setUserVisibleHint in instantiateItem and setPrimaryItem. Applicable to android since 4.2.1 and support-v4.

deep copy of Fragment

I am using a Fragment class.
I add it using
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Search fragment = new Search(maincontrolActivity.this);
fragmentTransaction.add(R.id.mainLayout,fragment , "MY_FRAG");
fragmentTransaction.commit();
this.FragmentObject = fragment
when I do refresh the control,I recall this code but by passing this.FragmentObject but I think it be garbage collected because the = refere to the same object , and when say add, it free the old fragement which is the same
so do I need a deep copy or any way to refresh ?
any idea
Ok. So what I would do is have an Interface defined and have each Fragment register with the Activity for a callback when the refresh button is clicked. Then in the fragment itself have it refresh its data. If that means getting new data, switch to a ProgressBar, get the data from the server, and repopulate the Views. Here is an entire article on creating Interfaces in Activities and calling Fragments from them.
Here is roughly what your code will look like...
The Activity:
public class RefreshActivity extends Activity implements View.OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
findViewById(R.id.refresh_button).setOnClickListener(this);
}
public interface OnRefreshPressedListener {
public void onRefreshPressed();
}
#Override
public void onClick(View v) {
((OnRefreshPressedListener)this.FragmentObject).onRefreshPressed();
}
}
The Fragment:
public class Search extends Fragment implements OnRefreshPressedListener {
#Override
public void onRefreshPressed() {
//TODO: Refresh your data!
}
}

ViewPager Activity to notify a Fragment of a specific event

I have a ViewPager and it is using a FragmentAdapter in order to display several fragments of the same kind. Although these Fragments are basically instantiated from the same class, they are using a ListView to display different information. (Obviously the ListView is being poulated by an ArrayAdapter.)
A background service is also running and is constantly receiving data from the Internet. I want to be able to update a specific Fragment in the ViewPager when my background service has notified me of a specific event.
How can I do that?
A code snippet would be hugely appreciated!
(By the way, I have saw this similar question but I have no idea how to use their suggestion!)
To make it all more simple:
My activity with the ViewPager:
[Fragment 0] [Fragment 1] [Fragment 2]
The background service tells me (via a broadcast) to update the ListView in Fragment 1.
EDIT:
Here are sample codes:
public class ChatWindowPager extends FragmentActivity
{
private ViewPager mViewPager = null;
private ChatFragmentAdapter mAdapter = null;
#Override
protected void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.chat_window_pager);
this.mViewPager = (ViewPager) findViewById(R.id.chatPager);
this.mAdapter = new ChatFragmentAdapter(getSupportFragmentManager());
this.mViewPager.setAdapter(this.mAdapter);
.
.
.
}
class ChatFragmentAdapter extends FragmentPagerAdapter implements ViewProvider
{
public ChatFragmentAdapter(final FragmentManager fm)
{
super(fm);
}
#Override
public Fragment getItem(final int arg0)
{
String friendId = ..... // Some initializations
ChatWindowFragment f = ChatWindowFragment.newInstance(friendId);
return f;
}
#Override
public int getCount()
{
...
}
#Override
public View getView(final int position)
{
View v = getLayoutInflater().inflate(R.layout.tab_holder, null);
.
.
.
return v;
}
}
}
Now the fragments is defined like this:
public class ChatWindowFragment extends Fragment
{
public String friendId;
private ListView lv;
public static ChatWindowFragment newInstance(final String friendId)
{
ChatWindowFragment chatWindowFragment = new ChatWindowFragment();
Bundle bundle = new Bundle();
bundle.putString("friendId", friendId);
chatWindowFragment.setArguments(bundle);
return chatWindowFragment;
}
#Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.friendId = getArguments().getString("friendId");
}
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.chat_window, container, false);
this.friendId = getArguments().getString("friendId");
.
.
.
return v;
}
//The rest of the class
}
As I am using a FragmentPagerAdapter I don't see how I can set the tag of each fragment!
(Obviously, I am not using transactions to add the Fragments!)
EDIT 2:
I would like to know whether what I'm doing, is the correct way to handle what I want to do... Any other solution is also welcome!
Try this,
Register a broadcast receiver in all your fragments... like this
create a class which extends a broadcast receiver in all the classes, for eg:
public class FragmentReceiver1 extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
}
}
and register this receiver in you fragment's onCreate ...
for eg. getActivity().registerReceiver(new FragmentReceiver1(), new IntentFilter("fragmentupdater"));
Now assign a unique id to each of you fragment like 1 for Fragment1, 2 for Fragment2 and likewise
now whenever you want to pass any data and update any of the fragment just send a broadcast with the data in intent and "fragmentupdater" as the intent-filter...
For eg:
Intent data = new Intent("fragmentupdater");
data.putString("key","data");
data.putInt("fragmentno",1); // Pass the unique id of fragment we talked abt earlier
activity.sendBroadcast(data);
Now each of your fragment will receive the data but you can verify if the data if for the same fragment by the unique id we passed in it in the onReceive function..., the intent which you get, is the intent we passed above
Have you tried FragmentManager.findFragmentByTag()
FragmentManager manager = getSupportedFragmentManager();
//with support package, else
//FragmentManager manager = getFragmentManager()
Fragment fragment = manager.findFragmentByTag("Tag You Created the Fragment");
if (fragment instanceof Fragment1){
Fragment1 fr = (Fragment1)fragment
fr.updateData(DATA)
//or any method of your choice
}
EDIT: I read carefully! The instanceOf will cast a Fragment into your Fragment class. It was you, who suggested Fragment1 as a name for simpicity. Also, you didn't provide any source to help us. It is true, that you cannot set a Fragment's tag, but why do you think you are able to get its tag?
Usually a Fragment is added through FragmentManagers like
FragmentManager manager = getSupportedFragmnentManager()
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(int containerViewId, Fragment fragment, String tag);
// or transaction.add(Fragment fragment, String tag)
// ...other transactions
transaction.commit()
EDIT2: it's very easy though. according to your code you could just call
Fragment fragment = mAdapter.getItem(0) // 0||1||2
You should consider reading the docs (i.e about FragmenPagerAdapter) and post your source code so we don't have to guess what you need.
I had the same issue but fixed it with a localBroadcastReceiver like this:
Create a receiver in your activity and register it:
/**
* ******************************
* Receiver to process the message
* *******************************
*/
private BroadcastReceiver onNotice = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//You can send any extra data if you need like this
final int type = intent.getIntExtra("fragment.data", -1);
Log.d(tag, "main class: " + type);
//also refresh your fragment like this
mViewPager.getViewPager().getAdapter().notifyDataSetChanged();
}
};
#Override
protected void onResume() {
super.onResume();
//Register a localbroadCast with the your filter
IntentFilter thinaireFilter = new IntentFilter("your.filter");
LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, thinaireFilter);
}
Remember to remove LocalBroadCast
//remove the LocalBroadCast when no need it
#Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(onNotice);
}
#Override
protected void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(onNotice);
}
Send your broadcast from anywhere you want Adapters, services, etc.
Intent sendBroadCastData = new Intent("your.filter");
sendBroadCastData.putExtra("fragment.data", myData);
LocalBroadcastManager.getInstance(context).sendBroadcast(sendBroadCastData);
Hope it helps others.
I don't know enough of what you are doing, but it sounds like you need to use an Observer pattern, Callbacks, or Listeners. Can't your fragment just do somthing like:
myservice.addMyEventListener(myFragInstance);
and then you can be "notified of a specific event."
Just look at this answer https://stackoverflow.com/a/16388650
He has used yourAdapter.notifyDataSetChanged() which is a predefined method.
Check the link to see how its done
Edit:
When your AsyncTask is done, you should do something like this onPostExecute method:
ResultFragment resultFrag = (ResultFragment) getSupportFragmentManager()
.findFragmentByTag("FragToRefresh");
if (resultFrag != null) {
resultFrag.refreshData(refreshedArray);
}
And in your ResultFragment you need to have refreshData method, which is something like this:
public void refreshData(ArrayList<YourObject> data) {
yourArray = new ArrayList<YourObject>(data);
yourAdapter.notifyDataSetChanged();
}
Had to use event bus to make everything simple https://github.com/greenrobot/EventBus
I am not sure this is the right way of doing it
1. Create a public function in fragment you would call to receive the data.
public void refreshList(List<String> yourData) {
//referesh your fragment views here
}
2. Create the fragment object global
YourFragment frag = new YourFragment();
3. Pass it to the view pager in the containing activity
4. Add on page change listener to the view pager
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
switch (position) {
case 0:
break;
case 1:
break;
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Here case 0: would be invoked when first fragment is selected and case 1: when second and so on..
5. Call your function corresponding to its position in the view pager
case 0: frag.refreshList(yourList);

Categories

Resources