My app have many fragments, many of them extends from ListFragment and have Adapters for read database (SQLite). My app have only one Activity (for now) and have a Service is binded when the Activity start.
My problem is how to notify to a fragment when are changes in the database from the service or other fragment.
Example of architecture of my application
MainActivity
tabhost
fragment
listfragment
listfragment
fragment
fragment
gridfragment
fragment
MainService
comunication_server
send_data
receive_data
As you can see my application has several fragments, and I want to inform the fragments that the data has changed. or at least launch an internal broadcast can hear by fragments like iNotifyPropertyChange .NET C#/WPF
Think about implementing CursorLoaders. They'll give you the ability to load your lists asynchronously and they will monitor the source of your data for changes and update lists automatically. They're super easy to implement.
Lars Vogal has a neat little tutorial on them.
Related
I have a fragment that communicates to an activity via an interface. This is cool and all but, is it possible to have the fragment communicate with an activity that did not launch it?
The reason why is I don't want one activity to be a million lines long of code implementing all interface methods for the fragments when I could just create "helper" activities to implement all the interfaces.
Currently I am using the Google Navigation drawer template so, maybe I could create new activities and group fragments around them. Im not sure if it will break my navigation drawer if I try to launch new activites.
Because of the activity lifecycle parameters of an activity are usually separated of the activity. You can store them in the savedInstancestate and retrieve them back. This way you make sure that your activity has the right information when it is restored.
If content changes somewhere during the app lifecycle it is good to store that content somewhere permanently (SharedPreferences, Database, File).
If you want to notify several parts of your app of an event a good way to go is a Local Broadcast.
Having said that it seems strange to me that another activity than the currently running one (and the one containing your fragment) should be notified of an event. When it is resumed it would collect the necessary information and update itself.
You're breaking android development practices. Fragments are encapsulated within an Activity. And an Activity is encapsulated within itself. An Activity should not communicate with another Activity via references.
Activities are communicating via references here, so I totally would not recommend doing this. But here's how you can do what you're asking.
class HelperActivity { // implement here
public static HelperActivity context = this;
public MyFragment myFragment = new MyFragment(this); // cast to implementation
}
class NormalActivity {
void onCreate {
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_attach, HelperActivity.myFragment)
.commit();
}
}
First I explain the structure of my app. To be precise MainActivity of my app contains Viewpager with two fragments. Each fragment contains a listview. The data inside listview is being populated from web service call.
This web service call is actually done in activity not in the fragments through AsyncTaskLoader which loads data for both listviews and saves the response in two Application variables (Lists of data for both listviews). On finish of loader , i just do viewpager.notifydatasetchanged() (which reloads the fragments , thus sets the data in listview).
As the fragments in viewpager are initialiased by viewpager's adapter no by the activity directly, I found this approach better.
Options I had, but rejected (pls correct me If I could utilise them)
Asynctask to call webservice (headache if handling rotations)
IntentService (updation of UI)
Is there any other approach to load data and handles the fragments?
I have an activity with 3 fragments and I need to update fragExchangeHistory listView from DB when I add an object to database in fragCurrencyExchange. How could I do it?
Code: GitHub
Use an EventBus like https://github.com/greenrobot/EventBus to communicate between fragments and other components. So when Fragment A update something in the database, you can fire an event to inform the other fragments about the changes.
Implement an Observer pattern between the activity and the fragments so you can notify when you add some new data up to the activity and from activity to fragments. In this way the notification flow is:
Fragment A adds data to the database.
Fragment A notifies to its Activity Observer that the data has been updated.
The Activity notifies all the other fragments that the data has been updated.
As you can see this couples quite a while your activity with the fragments so I usually use some kind of Event bus library like this or this that makes your code quite decoupled and easy to understand.
Maybe you should use CursorLoader.A CursorLoader automatically re-runs the query when data associated with the query changes.
You should check this from the Android Developer official site.
I have one FragmentActivity that holds ViewPager in which I trough custom FragmentPagerAdapter create 4 child Fragments. Fragments contain ListView in which I show data. I make a call to the web API in FragmentActivity when the response is finished; I want to notify all fragments that data is ready and fill the adapter with that data. Note that data is not available at the time of Fragment initialization.
I could save a reference to fragment when creating it and call “myFragment.hereIsYourData(Object data)”, but the reference get changed after recreating Activity when killing app for low memory. (If I’m not mistaking + I read that keeping a reference to fragment in Activity is a bad thing)
Just for clarification I can’t use “findFragmentById(id)” because ViewPager does’t expose that. I could use the “getFragmentTag” hack explained here https://stackoverflow.com/a/9744146/1025364 but I don’t want to : D.
Then I have tried to ask for data from Fragment onResume method trough interface to Activity (like explained in Developer guide), but the data is not reedy at that moment. Should I ask for data in some sort of a loop until its ready?
What is the best approach in situation like that?
I have an activity that stores NFC reads into my apps database. I have a fragment that has a ListView with data bound by a cursor adapter to that same database.
The activity handles the intent in the foreground but when I swipe to the fragment, the listview has not been updated with the databases latest data.
What is the best way to tell the fragment to update the listview when my activity adds the NFC read to the database?
The fragment is being managed in the activity by a viewpager, so I can't get access to the fragment with getFragmentById() because I don't have an ID. I've read some weird android:switcher hack to access the ID or Tag of the fragment but that doesn't seem like a good idea.
3 possible ways:
Send a broadcast from enclosing activity and have your fragment
listen and act on that broadcast
Implement a callback mechanism
e.g. http://www.javaworld.com/javatips/jw-javatip10.html
Provide a public method in your Fragment that can be called by the enclosing
activity