Skip to content

Instantly share code, notes, and snippets.

@iammart
Forked from kshivang/BaseActivity.java
Created June 15, 2018 11:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iammart/0f473a27015e45fe2b5a236d4efac651 to your computer and use it in GitHub Desktop.
Save iammart/0f473a27015e45fe2b5a236d4efac651 to your computer and use it in GitHub Desktop.
Instagram like ViewPager implementation with bottom tab layout, without recreating fragments in fragment manager on tab select or back click. Implementation is prescribed for ViewPager inside fragment(more complex case) similar thing could be achieved for ViewPager in activity as well.
public abstract class BaseActivity extends AppCompatActivity {
public void moveBack() {
super.onBackPressed();
}
public abstract void onBackWhenNoFragment();
@Override
public void onBackPressed() {
BaseFragment currentFragment = (BaseFragment) getSupportFragmentManager()
.findFragmentById(R.id.fragment);
if (currentFragment != null) {
if (!currentFragment.onBackPressed()) {
onBackWhenNoFragment();
}
} else {
moveBack();
}
}
}
public abstract class BaseFragment extends Fragment {
private BaseActivity activity = null;
public abstract boolean onBackPressed();
public View.OnClickListener onBackClick = view -> activity().onBackPressed();
// Retrieve activity
public BaseActivity activity(){
if (activity == null) {
activity = (BaseActivity) getActivity();
}
return activity;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity();
}
}
public class HolderActivity extends BaseActivity{
private static final String KEY_HOLDER_FRAGMENT = "holder_fragment";
private Fragment holderFragment;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
holderFragment = getSupportFragmentManager()
.getFragment(savedInstanceState, KEY_HOLDER_FRAGMENT);
}
replaceFragment(holderFragment);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
FragmentManager fragmentManager = getSupportFragmentManager();
if (holderFragment != null && holderFragment.isAdded()) {
fragmentManager.putFragment(outState, KEY_HOLDER_FRAGMENT, holderFragment);
}
}
@Override
public void onBackWhenNoFragment() {
moveTaskToBack(true);
}
public void replaceFragment(Fragment fragment) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment, fragment)
.commitAllowingStateLoss();
}
}
public class HolderFragment extends BaseFragment implements TabLayout.OnTabSelectedListener {
public static final int HOME_POSITION = 0;
public static final int FEED_POSITION = 1;
public static final int CHANNEL_POSITION = 2;
public static final int PROFILE_POSITION = 3;
private static final String KEY_HOME_FRAGMENT = "home_fragment";
private static final String KEY_FEED_FRAGMENT = "feed_fragment";
private static final String KEY_CHANNEL_FRAGMENT = "channel_fragment";
private static final String KEY_PROFILE_FRAGMENT = "profile_fragment";
private static final String KEY_STACK = "my_stack";
public List<TabLayout.Tab> tabs = new ArrayList<>();
public static HolderFragment newInstance() {
Bundle args = new Bundle();
HolderFragment fragment = new HolderFragment();
fragment.setArguments(args);
return fragment;
}
private LinkedHashSet<Integer> stack = new LinkedHashSet<>();
private TabLayout tabLayout;
private ArrayList<BaseFragment> fragments = new ArrayList<>();
private String getKey(int position) {
switch (position) {
case HOME_POSITION: return KEY_HOME_FRAGMENT;
case FEED_POSITION: return KEY_FEED_FRAGMENT;
case CHANNEL_POSITION: return KEY_CHANNEL_FRAGMENT;
case PROFILE_POSITION: return KEY_PROFILE_FRAGMENT;
}
return KEY_HOME_FRAGMENT;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
FragmentManager fragmentManager = getChildFragmentManager();
List<Integer> stackList = savedInstanceState.getIntegerArrayList(KEY_STACK);
if (stackList != null && !stackList.isEmpty()) {
stack.clear();
stack.addAll(stackList);
}
fragments.clear();
fragments.add((BaseFragment) fragmentManager.getFragment(savedInstanceState,
KEY_HOME_FRAGMENT));
fragments.add((BaseFragment) fragmentManager.getFragment(savedInstanceState,
KEY_FEED_FRAGMENT));
fragments.add((BaseFragment) fragmentManager.getFragment(savedInstanceState,
KEY_CHANNEL_FRAGMENT));
fragments.add((BaseFragment) fragmentManager.getFragment(savedInstanceState,
KEY_PROFILE_FRAGMENT));
}
if (fragments.isEmpty()) {
fragments.add(HomeFragment.newInstance());
fragments.add(FeedFragment.newInstance());
fragments.add(ChannelsHolderFragment.newInstance());
fragments.add(ProfileFragment.newInstance());
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putIntegerArrayList(KEY_STACK, new ArrayList<>(stack));
FragmentManager fragmentManager = getChildFragmentManager();
for (int i = 0; i < fragments.size(); i++) {
if (fragments.get(i).isAdded()) {
fragmentManager.putFragment(outState, getKey(i), fragments.get(i));
}
}
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View rootView = inflater.inflate(R.layout.fragment_holder, container, false);
tabLayout = rootView.findViewById(R.id.tabLayout);
setTabLayout();
initFragments();
return rootView;
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (tabLayout != null) {
tabLayout.removeOnTabSelectedListener(this);
}
}
@Override
public boolean onBackPressed() {
try {
if (stack.isEmpty()) {
return false;
} else {
Integer lastElement = (Integer) stack.toArray()[stack.size() - 1];
if (fragments.get(lastElement).onBackPressed()) {
return true;
}
if (stack.size() == 1) {
return false;
}
stack.remove(lastElement);
lastElement = (Integer) stack.toArray()[stack.size() - 1];
tabs.get(lastElement).select();
return true;
}
} catch (Exception e) {
return false;
}
}
private boolean set = false;
private void initFragments() {
if (!set) {
set = true;
FragmentManager fragmentManager = getChildFragmentManager();
if (fragmentManager.getFragments().isEmpty()) {
for (BaseFragment fragment : fragments) {
fragmentManager.beginTransaction()
.add(R.id.frameLayout, fragment)
.commit();
}
showFragment();
}
}
}
private void showFragment() {
if (stack.isEmpty()){
showFragment(HOME_POSITION);
} else {
showFragment((int) stack.toArray()[stack.size() - 1]);
}
}
private void showFragment(int position) {
stack.remove(position);
stack.add(position);
FragmentManager fragmentManager = getChildFragmentManager();
for (int i = 0; i < fragments.size(); i++) {
if (i == position) {
fragmentManager.beginTransaction().show(fragments.get(i)).commit();
} else {
fragmentManager.beginTransaction().hide(fragments.get(i)).commit();
}
}
}
private View initTab(@DrawableRes int drawable) {
View tabView = getLayoutInflater().inflate(R.layout.layout_tab, null);
((AppCompatImageView) tabView.findViewById(R.id.icon)).setImageResource(drawable);
return tabView;
}
private void setTabLayout() {
if (!tabs.isEmpty()) {
tabs.clear();
}
TabLayout.Tab homeTab = tabLayout.newTab();
tabLayout.addTab(homeTab.setCustomView(initTab(R.drawable.ic_home)));
tabs.add(homeTab);
TabLayout.Tab feedTab = tabLayout.newTab();
tabLayout.addTab(feedTab.setCustomView(initTab(R.drawable.ic_feed)));
tabs.add(feedTab);
TabLayout.Tab channelTab = tabLayout.newTab();
tabLayout.addTab(channelTab.setCustomView(initTab(R.drawable.ic_channel)));
tabs.add(channelTab);
TabLayout.Tab profileTab = tabLayout.newTab();
tabLayout.addTab(profileTab.setCustomView(initTab(R.drawable.ic_account_box)));
tabs.add(profileTab);
if (!stack.isEmpty()) {
tabs.get((int) stack.toArray()[stack.size() - 1]).select();
}
tabLayout.addOnTabSelectedListener(this);
}
@Override
public void onTabSelected(TabLayout.Tab tab) {
showFragment(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment