📜 ⬆️ ⬇️

History in each tab or multiple backstack



Problem


With the release of android 3.0 (Api Level 11), fragments appeared in android, and so it was with google developers that only one backstack was supported for them. Designers and customers do not always want to take this feature into account. And sometimes they just want a complete copy of an already existing ios application.

Let's say we need to make a similarity to the Tab Bar on android, including keeping the history in each tab. But we have one backstack, and what do we do? The task seems impossible.

Study


“If you do not ask, you will never know. If you know, you just need to ask. ”

On the one hand, this contradicts the official guide (see Behavior), which clearly states that navigation through the bottom should reset the state.
But who cares when it comes to user convenience? In all honesty, you admit that it is more convenient, as recommended?
')
And how can we still do what would seem impossible due to the limitation of the platform? Several options come to mind: one is more complicated than the other, and a search on google produces even more awful crutch solutions.

But why guess if you can peek at how Instagram is done? By the way, Instagram didn’t always work that way, there were times when the Instagram design was tabbed, and the story was reset when switching.

We decompile apk Instagram with apktool and see what is there. The main activity of the application is com.instagram.android.activity.MainTabActivity, we look at what it inherits from - from the class com / instagram / base / activity / tabactivity / a, which in turn inherits from android / app / ActivityGroup. Then you can not dig.

Classes such as ActivityGroup , TabActivity , LocalActivityManager - deprecated from 13 Api Level, that is, almost immediately, as fragments appeared. On developer.android.com for these classes, the following is written:
This class was deprecated in API level 13.
Use the new Fragment and FragmentManager APIs instead; these are also available on older platforms through the Android compatibility package.

Everyone knows that using deprecated in a new development is not good. Everyone rushed to write on the fragments and the classes were consigned to oblivion.

Decision?


Perhaps this is the only working solution. It works out of the box, no crutches (deprecated, after all, does not count). Personally, I just forgot about LocalActivityManager, although I started developing for android back in the days when there were more phones with 8 Api Level than the rest, but they were actively supplanted.

Everywhere it is so stubbornly arguing that our fragments are everything, and the development trend of a single activity application is so immutable that those who joined the development on android after 2011, most likely simply did not hear about LocalActivityManager.

This is a simple solution, it is silly not to use it. In each tab, we will have our own activity with its life cycle, and most importantly with its backstack!

Some code


Using TabHost is easy. If you know what to look for, you can find many ancient tutorials on how to use it. The Internet remembers.

Layout for our main activity:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TabHost android:id="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/bottom_bar" android:layout_below="@+id/top"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TabWidget android:id="@android:id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content"></TabWidget> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="match_parent" android:layout_height="match_parent"></FrameLayout> </LinearLayout> </TabHost> </FrameLayout> 

Actually code:

 //     TabActivity (  deprecated), //    deprecated ,    ? public class MainActivity extends android.app.ActivityGroup { TabHost mTabHost; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTabHost = (TabHost)findViewById(android.R.id.tabhost); mTabHost.setup(getLocalActivityManager()); TabHost.TabSpec tabSpec; tabSpec = mTabHost.newTabSpec("tag1"); tabSpec.setIndicator(" 1");//use getString //TabActivity    AndroidManifest tabSpec.setContent(new Intent(this, TabActivity.class)); mTabHost.addTab(tabSpec); tabSpec = mTabHost.newTabSpec("tag2"); tabSpec.setIndicator(" 2");//use getString //TabActivity    AndroidManifest tabSpec.setContent(new Intent(this, TabActivity.class)); mTabHost.addTab(tabSpec); } } 

PS


It is a pity that we have to use the deprecated classes, but until google makes another decision - this is the only adequate option. You can build a convenient navigation with one backstack, there are other reasonable limitations of the platform that must be considered and which are reasonable, but in this case it seems that google simply missed this opportunity when designing the Fragment API.

So it turns out that in this moment, android turned out to be definitely not better than the iphone ...

Source: https://habr.com/ru/post/317760/


All Articles