Android Tabs Content for better User Experience - android

I have an Activity which has 3 tabs which are Fragments.
Featured
Up Coming
Favorites
Right now my implement when i click a particular tab it downloads the content from the internet and displays it.
When i was browsing through the Google Play App. I found that when i went into the App section All the content across the tabs Featured - Top Free - Top Paid etc was already there and only the images was lazy loading.
I am trying figure out how this can be implemented.

In my app i have a Activity wich has 4 Tabs wich are Fragments..
I solved your explained Problem by Using a Singleton. I load all relevant information from sqlite database and pass it into an ArrayList in the Singletion..
So i can access the content from every Fragment...
public class Singleton {
private static Singleton instance = null;
public ArrayList<MyObject> myObjectList;
protected Singleton() {
// Exists only to defeat instantiation.
}
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
myObjectList = new ArrayList<MyObject>();
}
return instance;
}
}

This is a feature of ViewPager

Related

BrowseSupportFragment in Leanback android Tv makes Server calls when I move from one menu to another and back

I have implemented the BrowseSupportFragment from the Leanback library. It has a left navigation bar with rowItems and headerIcons. Each time I move from one row in the navigation drawer the fragments are reloaded. This is not good since it keeps making server calls and therefore my image caching doest work. This is how I call each fragment in my BrowseSupportFragment,
using same idea as here:
https://www.javatips.net/api/platform_frameworks_support-master/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseSupportFragment.java
private static class PageRowFragmentFactory extends BrowseSupportFragment.FragmentFactory {
private final BackgroundManager mBackgroundManager;
PageRowFragmentFactory(BackgroundManager backgroundManager) {
this.mBackgroundManager = backgroundManager;
}
// new fragment is registered and called from here
#Override
public Fragment createFragment(Object rowObj) {
Row row = (Row) rowObj;
mBackgroundManager.setDrawable(null);
if (row.getHeaderItem().getId() == HEADER_ID_1) {
return new MovieGalleryFragment();
} else if (row.getHeaderItem().getId() == HEADER_ID_2) {
return new SeriesGalleryFragment();
} else if (row.getHeaderItem().
getId() == HEADER_ID_3) {
return new SortByGenreFragment();
} else if (row.getHeaderItem().
getId() == HEADER_ID_4) {
return new SortByCountryFragment();
} else if (row.getHeaderItem().
getId() == HEADER_ID_5) {
return new WebViewFragment();
}
throw new
IllegalArgumentException(String.format("Invalid row %s", rowObj));
}
}
public static class PageFragmentAdapterImpl extends MainFragmentAdapter<MovieGalleryFragment> {
public PageFragmentAdapterImpl(MovieGalleryFragment fragment) {
super(fragment);
}
}
and in my fragments i extend
public class MovieGalleryFragment extends VerticalGridSupportFragment implements BrowseSupportFragment.MainFragmentAdapterProvider{
final MainActivityFragment.PageFragmentAdapterImpl mMainFragmentAdapter = new MainActivityFragment.PageFragmentAdapterImpl(this);
..........
}
so when i move from MovieGalleryFragment() to SeriesGalleryFragment and back to MovieGalleryFragment(), it is reloaded and images recalled from server. How do I prevent this ??
thank you.
Your image cache shouldn't be live in one of these fragments, so the fragment being destroyed and recreated should not cause another fetch. For example, MovieGalleryFragment should request an image from an app-wide cache before attempting to fetch from the server. Since you want to maintain an in-memory cache, a disk cache, and cleanup rules, it can be very complicated to get this right. I'd recommend relying on something like Picasso, Coil, Glide, etc. In general, you want to heavily rely on cache this way anyway since the user might close the app and reopen it shortly after.

Is it necessary to declare Singleton to access a single object in my all activities?

I am building a menu from which the user can select items. They can edit their selections whenever necessary. The singleton would be a class containing the list of all selectable items. Whenever new activities are opened, the singleton would have the correct state of all items.
The reason I am asking this is because implementing Serializable creates a new instance (albeit almost identical) of the item.
Yes you could use a singleton for this. It would be something like:
public class MenuData {
private static MenuData instance;
private boolean isItemASelected;
public static MenuData getInstance() {
if (instance == null) {
instance = new MenuData();
}
return instance;
}
public boolean isItemASelected() {
return isItemASelected;
}
public void setItemASelected(boolean itemASelected) {
isItemASelected = itemASelected;
}
}
However I wouldn't recommend this. This data will only be around for as long as your Application is in memory. As soon as your app gets killed by Android all the variables will be cleared and the state will have been lost.
If your menu items are constant then I'd recommend using SharedPreferences to store the state. If they are dynamic then use the SQL database. This way the options are persisted even if your app gets killed.

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 new activity can't load singleton

I am trying to use a Singleton to share a large data object between Activities. But when I open the new Activity, the singleton comes up as empty. It seems to me that the Singleton should be the same no matter where in the Application I call if from.
It seems like the Scope of the Singleton is being limited to the individual Activity. Working around this is making my App very complicated. I must be doing something wrong. I even tried instantiating them in an extended Application class... Google says I should not have to use that though...
Can someone please point out where I am going wrong? i.e. Why does this singletom not contain the same data in each Activity?
I call it from an Activity with...
DataLog dataLog = DataLog.getInstance(this);
I have...
public class DataLog extends ArrayList<String> implements Serializable {
private static final long serialVersionUID = 0L;
private static DataLog sInstance;
private static Context mContext;
public static DataLog getInstance(Context context) {
mContext = context.getApplicationContext();
prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
if (sInstance == null) {
sInstance = new DataLog();
}
return sInstance;
}
private DataLog() {
}
public boolean add(String entry) {
super.add(entry);
return true;
}
public void add(int index, String entry) {
if (index > 0)
super.add(index, entry);
else
super.add(entry);
}
public void clear() {
super.clear();
}
...
}
Its highly advisable to avoid singleton for sharing large data sets in android.
Singletons are used for short life-cycle objects.
Switch to SharedPrefferences, SQLite DB's or file storing. You are not the only to have experienced this behavior, and the reason lies in the nature of android Activities and the system itself(managing activities and its data).
Here is an example why singleton is bad for your case:
You stored important data in it. The user knows that he can close the app on home button to call someone or whatever)maybe someone called him when he was in your app), and that when he opens your app he will come back at the same place with everything in order. (this is expected behavior from users and android apps). The system can easily kill your process and all static variables in it for memory maintenance, app inactivity etc...result=data lost. Thus its not safe to use it.

Communicative Between Fragments on 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;
}
}

Categories

Resources