Communicative Between Fragments on Android - android

I am attempting to build an Android application that has two tabs, one for a textField/button and TreeMenu (where each element has a checkbox associated with it) and another for a list. I am also using an ActionBarSherlock. I have already successfully written the program in a single main activity, but am having difficulty figuring out how to divide this original activity to correspond with the two new fragment instances I need to create for each tab. Moreover, each time an item is added in the first tab (whether it is from being checked off or added to the textField), the list in the second window ought to recognize the update.
To build the action bar I can do this...
ActionBar actionbar = getSupportActionBar();
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionbar.setTitle("AppName");
To create the tabs..
ActionBar.Tab Frag1Tab = actionbar.newTab().setText("InputTab");
ActionBar.Tab Frag2Tab = actionbar.newTab().setText("ListTab");
To create the fragments and its listeners underlying each tab...
Fragment Fragment1 = new Fragment_1();
Fragment Fragment2 = new Fragment_2();
Frag1Tab.setTabListener(new MyTabsListener(Fragment1));
Frag2Tab.setTabListener(new MyTabsListener(Fragment2));
To add them to the action bar...
actionbar.addTab(Frag1Tab);
actionbar.addTab(Frag2Tab);
All of this appears within my MainActivity. I want, for example, an ArrayList variable to be accessible to both Fragments so, like I said, I can update the list. I would love to hear any help you can provide. I would be interested to see how the Otto API could work for something like this, but I am not picky!

In some of the answers there's a suggestion to put the ArrayList in a singleton, but that doesn't really solve your problem does it? Sure, you'll be able to access it from where ever you like, but it doesn't help you keeping two different fragments, both using the arraylist, in sync.
Start by putting the ArrayList in a singleton as suggested or in your MainActivity. Once that is done you have at least two options for keeping the fragments in sync with the content of the ArrayList:
Make the ArrayList Observable (check ObservableArrayList) and let the Fragments Observe the ArrayList for changes.
Make use of an event bus (like Otto) and let the singleton or MainActivity (depending on where you put the ArrayList) post update events on the bus when the arraylist changes and have the Fragments subscribe to the events.

A singleton class could help solve your problem.
public class GlobalApp {
private static GlobalApp instance = new GlobalApp();
private GlobalApp() {}
public static GlobalApp getInstance() {
return instance;
}
public ArrayList < ClassName > varName = new ArrayList < ClassName > ();
}
Then use in your class like this..
GlobalApp.getInstance().varName

I had the same issue a little time ago with an ArrayList and other data. In the end I decided to create a class that extends application and that holds all the global data and can be accessed everywhere from the app. Do you want and example?

As John said, when you want to access data in several activities, just create a class that extends Application:
import android.app.Application;
/**
* Application class used to share data between activities.
* #author Longeanie Christophe
*
*/
public class MyApplication extends Application {
//Put your class members here
#Override
public void onCreate() {
//initialize what's needed here
}
//Getters and setters...
}
In all your activities, you can access this class and its data through this instruction:
MyApplication myApp = (MyApplication) getApplication();

Here you go:
first be sure you declare it in your AndroidManifest:
<application
android:name="com.example.main.ApplicationClass"
etc..>
<!-- other activities, services etc: -->
</application>
and your class:
public class ApplicationClass extends Application {
private static ApplicationClass THIS = null;
ArrayList<String> list = new ArrayList<String>();
public void onCreate() {
super.onCreate();
THIS = this;
}
public static ApplicationClass getThisInstance() {
return THIS;
}
}

Related

How to get same childfragments(having recyclerview) instance in all the fragments of viewpager?

I am stuck in a situation where I have recyclerview with item data in it and I need to fetch same instance in all the fragments (three) of viewpager to operate on the same recyclerview.
What I have done :
I have made one separate fragment names as ItemListFragment with common buttons and option in the list and now trying to add it as child fragment to my viewpager fragments. I can add them as child fragment but at this point I have to create 3 different ItemListFragment for all the PrentFragments.
Kindly help me to overcome this situation or suggest any other way for using common recyclerlist in all the 3 fragments. I have searched stackoverflow but nothing is of any help.
Here is the image to get an idea about the situation:
You can try using global static reference technique in this case.
Declare your childview in Application class ( a class which extends Application class of Android).
public class AppController extends Application{
public static final String LOG_TAG = ApplicationController.class
.getSimpleName();
// Application Instance
private static ApplicationController applicationController = null;
public static ListView childview;
public static ChildAdapter childAdapter;
#Override
public void onCreate() {
super.onCreate();
applicationController = this;
}
}
Now in any of your Fragment suppose Fragment A,check global object of childFragment whether its null or not,if its null initilize it normally like other chilfragments,since its reference is global the varibale in AppController now contains the instance of childfragment.
Now in Fragment B check whether global reference null or not,since you initialized it in Fragment A you will not get null,now attach childFragment to Fragment B like normal childfragments

Android: How to access from activity to update private variable of another activity

I am trying to do something like that , Firstly , there is a MainActivity which stores courses in ArrayList and these courses are showed by listview.After that , I pass to another activity which is called as ShowDetailActivity with startActivity() to show course details when I click list view element.Then, I pass to another activity which is called EditCourseActivity to edit course which is shown by ShowDetailActivity. The problem is that When I want to edit course , I have to access MainActivity 's Arraylist (private) but I cannot pass with startActivity() because MainActivity did restart (reinstalled) that's why there is no courses on arraylist. The question is How can access from EditCourseActivity to MainActivity 's arraylist to show updated courses ?
Store the course information in a singleton class
public class CourseHolder{
public static CourseHolder instance=null;
public static CourseHolder getInstance(){
if(instance==null){
instance=new CourseHolder();
}
return instance;
}
private Course courses[];
private CourseHolder(){
courses=new Course[10];
}
public void setCourse(int index, Course course){
courses[index]=course;
}
public Course[] getCourses(){
return courses;
}
}
In the EditCourseActivity, after editing, store the updated course information in the copy of CourseHolder
In MainActivity.onResume(), call listView.setAdapter(null), then refresh it with the data inside the CourseHolder
As a generic answer: detach the data from its representation. You can achieve this in many ways:
Singleton wrapper for your array list
To be android specific: wrap your array in a ContentProvider
Use Android SDK SQL database support

How can Main Activity call another Activity A and send its context to it?

My MainActivity calls another Activity A which needs to access some members of MainActivity.
What is the best way to send a reference to Main Activity (or its context) to Activity A without resorting to complicated methods like parcelables etc?
There are some heavyweight android wrestling matches here but I am not sure that it is relevant to my problem.
details
I have Alert and Alerted objects in a one-to-many relationship (Alerted represents the various times an Alert was rung).
AlertsListActivity extends ListActivity which displays a list of Alert objects from a SQLite database table (primary key: alertId). It has an AlertsListAdapter.
AlertedsListActivity has a ListFragment which displays a list of Alerted objects from Alerted table (foreign key is alertId from Alert table).
It has an AlertedsListAdapter.
AlertsListActivity needs to call AlertedsListActivity to display the list of Alerted objects. I used startActivityForResult().
Inside AlertedsListAdapter
public View getView(int position, View convertView, ViewGroup parent) {
final Alert alertItem = (Alert) mainActivity.alertsListAdapter.getItem(position);
final Alerted alertedItem = (Alerted) getItem(position);
...
I do need the Alert objects also, in order to display some identifying information from them with each Alerted list item. Hence I need the reference to mainActivity.alertsListAdapter
How can AlertedsListActivity access AlertsListActivity?
Update: Since I did not get any solutions, I implemented a workaround. The data that I needed to access from Main Activity, I modified. So the Alert object was made a parcelable, and the SQLOpenHelper was made a singleton.
This allows the data to be accessed from Activity A.
Here's the simple, common way to do it:
singletons typically have variables like the below example, "useThisContext" or "mainFeedIsHere".
public class Cloud
{
private static Cloud ourInstance = new Cloud();
private Cloud() { Utils.Log("cloud singleton launched"); }
public synchronized static Cloud getInstance()
{
return ourInstance;
}
/////////////////////////////////////////////////
public Context useThisContext;
another example ...
public class Feed
{
private static Feed ourInstance = new Feed();
private Feed()
{
Utils.Log("feed singleton launched");
freshestPostsForDisplay = new ArrayList<ParseObject>();
}
public synchronized static Feed getInstance()
{
return ourInstance;
}
public List<ParseObject> freshestPosts;
public MainActivity mainFeedIsHere;
Quite simply when everything launches (or when it changes), those "things" need to set those variables in the singleton. In other words, those things "tell the singleton, where they are." It's that simple.
So, in the MainActivity perhaps, in onCreate, it might say something like...
CLOUD.useThisContext = this;
FEED.mainFeedIsHere = this;
Then for example inside Feed.java you may have say
mainFeedIsHere.feedReload();
It goes without saying you have to check that they are not null (but how else could it be?) and you have to keep them up-to-date as it were. (i.e., for whatever reason you may want to change "useThisContext" -- again how else could it be?)
{Sometimes you'll have one "centralised" singleton .. perhaps "State" .. to sort of combine all these together - so that anyone can "get to" any of those "exposed" things as needed. This is, really, how game engines go; so that you can say more or less SoundEffects.Booms() or Tanks.Faster() or AI.FindVillains() at any time anywhere.}
Cheers!
Since I did not get any solutions, I implemented a workaround. The data that I needed to access from Main Activity, I modified. So the Alert object was made a parcelable, and the SQLOpenHelper was made a singleton.
This allows the data to be accessed from Activity A.

android - using a global cache for bitmaps

I'm developing an android application that deals with bitmaps. Right now I'm using an LRUCache to store these bitmaps, but there are going to be multiple fragments that require access to this cache. What's the best way to handle to handle a global application cache? Should I use a singleton? Should I create a new cache for each activity/fragment that requires access to it?
To avoid Singletons in Android Development, like in your question I would suggest anybody using Fragments to store real global Objects in the MainActivity. It should look like this:
MainActivity:
public class MainActivity extends FragmentActivity{
//eg a ArrayList
private ArrayList<MyObjects> mObjectContainer = new ArrayList<MyObject>();
//Do something with the list and fill it
public ArrayList<MyObjects> getObjectContainer(){
return mObjectContainer;
]
public void addObject(MyObject object){
if(!mObjectContainer.contains(object)){
mObjectContainer.add(object);
}
}
}
Fragment:
public class MyFirstFragment extends Fragment{
onCreateView(...){
//make typical Fragment init like create View
ArrayList<MyObjects> list = ((MainActivity)getActivity()).getObjectContainer();
//add a new Object
((MainActivity)getActivity).addObject(new MyObject("any data"));
}
}

How to save List<UserDefinedClass> of between Activity switching?

How to save List<UserDefinedClass> of between Activity switching ? I get data in onClickView function. Does UserDefinedClass need to implements some interface ?
I believe the best way would be to keep the list in the Application context.
In any of your activitys call yourApp using:
((yourApp)getApplication()).//any public function
public yourApp extends Application{
private List<UserDefinedClass> yourList;
//create functions to manipulate the list example:
public void add(UserDefinedClass a){
//add this to list
}
//finally function to access list
public List<UserDefinedClass> getList(){
return yourList;
}
}
//example:
List<UserDefinedClass> aList = ((yourApp)getApplication()).getList();
It is best to only pass an identifier to the next Activity instead of passing your entire list.
UserDefinedClass should not implement some interface, rather UserDefinedClass should be the class type of the List. In other words, every item in your list should be of UserDefinedClass. That can be a String or even a custom class.
Yes you can pass it if it implements Parcelable. However if its a large amount of data a database or file may work out better for you.

Categories

Resources