de.elanev.studip.android.app.frontend.courses.CourseViewActivity.java Source code

Java tutorial

Introduction

Here is the source code for de.elanev.studip.android.app.frontend.courses.CourseViewActivity.java

Source

/*
 * Copyright (c) 2015 ELAN e.V.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 */
package de.elanev.studip.android.app.frontend.courses;

import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.NavUtils;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.MenuItem;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import de.elanev.studip.android.app.R;
import de.elanev.studip.android.app.backend.datamodel.Course;
import de.elanev.studip.android.app.backend.db.CoursesContract;
import de.elanev.studip.android.app.frontend.forums.ForumCategoriesListFragment;
import de.elanev.studip.android.app.util.Prefs;
import de.elanev.studip.android.app.widget.SlidingTabLayout;

/**
 * Activity for displaying a ViewPager with tabs for course overview,
 * schedule, participants and documents.
 */
public class CourseViewActivity extends AppCompatActivity {
    private static final String INTENT_EXTRAS = "intent_extras";
    static Bundle sExtras;
    static String sTitle;
    private ViewPager mPager;
    private TabLayout mTabLayout;
    private FragmentsAdapter mPagerAdapter;
    private Course.Modules mModules = new Course.Modules();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pager);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setHomeButtonEnabled(true);
            actionBar.setDisplayHomeAsUpEnabled(true);
        }

        mPager = (ViewPager) findViewById(R.id.pager);
        mTabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
        mTabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);

        // Get intent data
        if (savedInstanceState != null) {
            sExtras = savedInstanceState.getBundle(INTENT_EXTRAS);
        } else {
            Bundle intentExtras = getIntent().getExtras();
            if (intentExtras != null) {
                sExtras = intentExtras;
            }
        }

        if (sExtras != null) {
            sTitle = sExtras.getString(CoursesContract.Columns.Courses.COURSE_TITLE);
            setTitle(sTitle);

            String modulesJson = sExtras.getString(CoursesContract.Columns.Courses.COURSE_MODULES);
            if (!TextUtils.isEmpty(modulesJson)) {
                mModules = Course.Modules.fromJson(modulesJson);
            }
        } else {
            finish();
            return;
        }

        mPagerAdapter = new FragmentsAdapter(getSupportFragmentManager(), getTabs());
        mPager.setAdapter(mPagerAdapter);
        mTabLayout.setupWithViewPager(mPager);
    }

    private ArrayList<Tab> getTabs() {
        ArrayList<Tab> tabs = new ArrayList<>();
        // Add the tabs to the PagerAdapter, if activated.
        tabs.add(new Tab(getString(R.string.Overview), CourseOverviewFragment.class, sExtras));

        if (mModules.schedule) {
            tabs.add(new Tab(getString(R.string.Schedule), CourseScheduleFragment.class, sExtras));
        }
        if (mModules.participants) {
            tabs.add(new Tab(getString(R.string.attendees), CourseAttendeesFragment.class, sExtras));
        }
        if (mModules.forum && Prefs.getInstance(this).isForumActivated()) {
            tabs.add(new Tab(getString(R.string.forum), ForumCategoriesListFragment.class, sExtras));
        }
        if (mModules.documents) {
            tabs.add(new Tab(getString(R.string.Documents), CourseDocumentsFragment.class, sExtras));
        }
        if (mModules.recordings) {
            tabs.add(new Tab(getString(R.string.Recordings), CourseRecordingsFragment.class, sExtras));
        }
        if (mModules.unizensus) {
            tabs.add(new Tab(getString(R.string.unizensus), CourseUnizensusFragment.class, sExtras));
        }

        return tabs;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        outState.putBundle(INTENT_EXTRAS, sExtras);
        super.onSaveInstanceState(outState);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        // Respond to the action bar's Up/Home button
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
        if (!returnBackStackImmediate(getSupportFragmentManager())) {
            super.onBackPressed();
        }
    }

    // HACK: propagate back button press to child fragments.
    // (http://android.joao.jp/2013/09/back-stack-with-nested-fragments-back.html)
    // FIXME: Fix with either a better hack, or an official solution
    private boolean returnBackStackImmediate(FragmentManager fm) {
        List<Fragment> fList = fm.getFragments();
        Fragment fActive = mPagerAdapter.getItem(mPager.getCurrentItem());
        if (fActive instanceof CourseDocumentsFragment) {
            if (fList != null && fList.size() > 0) {
                for (Fragment f : fList) {
                    if (f.getChildFragmentManager().getBackStackEntryCount() > 0) {
                        return f.getChildFragmentManager().popBackStackImmediate()
                                || returnBackStackImmediate(f.getChildFragmentManager());
                    }
                }
            }
        }
        return false;
    }

    public static class FragmentsAdapter extends FragmentPagerAdapter {

        private ArrayList<Tab> mTabs = new ArrayList<Tab>();

        public FragmentsAdapter(FragmentManager fm) {
            super(fm);
        }

        public FragmentsAdapter(FragmentManager fm, ArrayList<Tab> tabs) {
            super(fm);
            mTabs = tabs;
        }

        public void addTab(Tab tab) {
            mTabs.add(tab);
        }

        @Override
        public Fragment getItem(int position) {
            Tab tab = mTabs.get(position);

            try {
                Method m = tab.clss.getMethod("newInstance", Bundle.class);

                return (Fragment) m.invoke(null, tab.args);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

            return CourseOverviewFragment.newInstance(tab.args);
        }

        @Override
        public int getCount() {
            return mTabs.size();
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return mTabs.get(position).title;
        }
    }

    static final class Tab {
        CharSequence title;
        Class<?> clss;
        Bundle args;

        public Tab(CharSequence title, Class clss, Bundle args) {
            this.title = title;
            this.clss = clss;
            this.args = args;
        }
    }

}