com.nextgis.metroaccess.ui.activity.SelectStationActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.nextgis.metroaccess.ui.activity.SelectStationActivity.java

Source

/**
 * ***************************************************************************
 * Project:  Metro Access
 * Purpose:  Routing in subway for disabled.
 * Author:   Baryshnikov Dmitriy aka Bishop (polimax@mail.ru)
 * Author:   Stanislav Petriakov, becomeglory@gmail.com
 * *****************************************************************************
 * Copyright (C) 2013-2015 NextGIS
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * **************************************************************************
 */
package com.nextgis.metroaccess.ui.activity;

import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Rect;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.TextView;

import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import com.nextgis.metroaccess.ui.fragment.AlphabeticalStationListFragment;
import com.nextgis.metroaccess.ui.fragment.LinesStationListFragment;
import com.nextgis.metroaccess.MetroApp;
import com.nextgis.metroaccess.R;
import com.nextgis.metroaccess.ui.fragment.RecentStationListFragment;
import com.nextgis.metroaccess.ui.fragment.SelectStationListFragment;
import com.nextgis.metroaccess.data.metro.StationItem;
import com.nextgis.metroaccess.util.Constants;

import org.json.JSONArray;
import org.json.JSONException;

import java.util.ArrayList;
import java.util.List;

import static com.nextgis.metroaccess.ui.activity.PreferencesActivity.clearRecent;
import static com.nextgis.metroaccess.util.Constants.ARRIVAL_RESULT;
import static com.nextgis.metroaccess.util.Constants.BUNDLE_CITY_CHANGED;
import static com.nextgis.metroaccess.util.Constants.BUNDLE_ENTRANCE_KEY;
import static com.nextgis.metroaccess.util.Constants.BUNDLE_EVENTSRC_KEY;
import static com.nextgis.metroaccess.util.Constants.BUNDLE_PORTALID_KEY;
import static com.nextgis.metroaccess.util.Constants.BUNDLE_STATIONID_KEY;
import static com.nextgis.metroaccess.util.Constants.DEPARTURE_RESULT;
import static com.nextgis.metroaccess.util.Constants.KEY_PREF_RECENT_ARR_STATIONS;
import static com.nextgis.metroaccess.util.Constants.KEY_PREF_RECENT_DEP_STATIONS;
import static com.nextgis.metroaccess.util.Constants.KEY_PREF_TOOLTIPS;
import static com.nextgis.metroaccess.util.Constants.MAX_RECENT_ITEMS;
import static com.nextgis.metroaccess.util.Constants.PREF_RESULT;
import static com.nextgis.metroaccess.util.Constants.SUBSCREEN_PORTAL_RESULT;
import static com.nextgis.metroaccess.util.Constants.TAG;

public class SelectStationActivity extends AppCompatActivity {
    private static final int NUM_ITEMS = 3;

    private TextView tvNotes;

    private ViewPager mPager;
    private FragmentRollAdapter mAdapter;
    private static AlphabeticalStationListFragment mAlphaStListFragment;
    private static LinesStationListFragment mLinesStListFragment;
    private static RecentStationListFragment mRecentStListFragment;

    private boolean m_bIn, isCityChanged = false;
    private boolean mIsLimitations;
    private int mStationId, mPortalId;
    private Intent resultIntent;

    private SharedPreferences prefs;
    private boolean mIsKeyboardShown = false;
    private int mHeightDifference;
    private String mFilter = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_select_station);
        resultIntent = new Intent();

        // setup action bar for tabs
        final ActionBar actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        //actionBar.setDisplayShowTitleEnabled(false);
        actionBar.setDisplayHomeAsUpEnabled(true);

        prefs = PreferenceManager.getDefaultSharedPreferences(this);

        mIsLimitations = LimitationsActivity.hasLimitations(this);

        mAdapter = new FragmentRollAdapter(getSupportFragmentManager());
        mAdapter.setActionBar(actionBar);
        mPager = (ViewPager) findViewById(R.id.pager);
        mPager.setAdapter(mAdapter);
        mPager.setOnPageChangeListener(new OnPageChangeListener() {

            public void onPageScrollStateChanged(int arg0) {
            }

            public void onPageScrolled(int arg0, float arg1, int arg2) {
            }

            public void onPageSelected(int arg0) {
                Log.d(TAG, "onPageSelected: " + arg0);
                actionBar.getTabAt(arg0).select();
                filter(mPager.getCurrentItem());
            }
        });

        ActionBar.Tab tab = actionBar.newTab().setText(R.string.sSelAlphabeticalTab)
                .setTabListener(new TabListener(0 + "", mPager));
        actionBar.addTab(tab);

        tab = actionBar.newTab().setText(R.string.sSelLinesTab).setTabListener(new TabListener(1 + "", mPager));
        actionBar.addTab(tab);

        tab = actionBar.newTab().setText(R.string.sSelRecentTab).setTabListener(new TabListener(2 + "", mPager));
        actionBar.addTab(tab);

        //get location from calling class
        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            int nType = extras.getInt(BUNDLE_EVENTSRC_KEY);
            m_bIn = extras.getBoolean(BUNDLE_ENTRANCE_KEY);
            mStationId = extras.getInt(BUNDLE_STATIONID_KEY);
            mPortalId = extras.getInt(BUNDLE_PORTALID_KEY);
            int selectedStation = -1;

            Tracker t = ((MetroApp) getApplication()).getTracker();
            t.setScreenName(Constants.SCREEN_SELECT_STATION + " " + getDirection());
            t.send(new HitBuilders.AppViewBuilder().build());

            switch (nType) {
            case DEPARTURE_RESULT:
                setTitle(R.string.sFromStation);
                selectedStation = prefs.getInt("dep_" + BUNDLE_STATIONID_KEY, -1);
                break;
            case ARRIVAL_RESULT:
                setTitle(R.string.sToStation);
                selectedStation = prefs.getInt("arr_" + BUNDLE_STATIONID_KEY, -1);
                break;
            }

            if (selectedStation != -1) {
                final int finalSelectedStation = selectedStation;
                mPager.post(new Runnable() {
                    @Override
                    public void run() {
                        mAlphaStListFragment.expandStation(finalSelectedStation);
                    }
                });
            }
        }

        tvNotes = (TextView) findViewById(R.id.tvNotes);

        // http://stackoverflow.com/a/9108219
        final int softKeyboardHeight = getResources().getDisplayMetrics().heightPixels / 5;
        final View activityRootView = findViewById(R.id.select_station_layout);
        activityRootView.getViewTreeObserver()
                .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        if (!mIsLimitations)
                            return;

                        Rect r = new Rect();
                        //r will be populated with the coordinates of your view
                        // that area still visible.
                        activityRootView.getWindowVisibleDisplayFrame(r);
                        //                        int heightDiff = activityRootView.getRootView().getHeight() - r.height();
                        mHeightDifference = activityRootView.getRootView().getHeight() - r.height();

                        // if more than 1/5 of display, its probably a keyboard...
                        mIsKeyboardShown = mHeightDifference > softKeyboardHeight;

                        if (mIsKeyboardShown)
                            tvNotes.setVisibility(View.GONE);
                        else
                            tvNotes.setVisibility(View.VISIBLE);
                    }
                });
    }

    public boolean isKeyboardShown() {
        return mIsKeyboardShown;
    }

    public int getKeyboardHeight() {
        //        return getResources().getDisplayMetrics().heightPixels / 5;
        return mHeightDifference;
    }

    @Override
    protected void onResume() {
        super.onResume();

        boolean was = mIsLimitations;
        mIsLimitations = LimitationsActivity.hasLimitations(this);

        if (was != mIsLimitations) {
            mAdapter = new FragmentRollAdapter(getSupportFragmentManager());
            mAdapter.setActionBar(getSupportActionBar());

            int current = mPager.getCurrentItem();
            mPager.setAdapter(mAdapter);
            mPager.setCurrentItem(current);

            tvNotes.setVisibility(mIsLimitations ? View.VISIBLE : View.GONE);
        }
    }

    public boolean isIn() {
        return m_bIn;
    }

    public boolean isHintNotShowed() {
        return !prefs.getString(KEY_PREF_TOOLTIPS, "").contains(getClass().getSimpleName());
    }

    public String getHintScreenName() {
        return getClass().getSimpleName();
    }

    public List<StationItem> getStationList() {
        return new ArrayList<>(MetroApp.getGraph().GetStations().values());
    }

    public static class TabListener implements ActionBar.TabListener {
        private final String m_Tag;
        private ViewPager m_Pager;

        public TabListener(String tag, ViewPager pager) {
            m_Tag = tag;
            m_Pager = pager;
        }

        @Override
        public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
            int nTag = Integer.parseInt(m_Tag);
            m_Pager.setCurrentItem(nTag);
        }

        @Override
        public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {

        }

        @Override
        public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {

        }
    }

    public static class FragmentRollAdapter extends FragmentPagerAdapter {
        ActionBar m_ActionBar;

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

        @Override
        public int getCount() {
            return NUM_ITEMS;
        }

        public void setActionBar(ActionBar bar) {
            m_ActionBar = bar;
        }

        @Override
        public SelectStationListFragment getItem(int arg0) {
            switch (arg0) {
            case 0:
                mAlphaStListFragment = new AlphabeticalStationListFragment();
                return mAlphaStListFragment;
            case 1:
                mLinesStListFragment = new LinesStationListFragment();
                return mLinesStListFragment;
            case 2:
                mRecentStListFragment = new RecentStationListFragment();
                return mRecentStListFragment;
            default:
                return null;
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        menu.findItem(R.id.btn_locate).setVisible(false);
        menu.findItem(R.id.btn_report).setVisible(false);
        menu.findItem(R.id.btn_reverse).setVisible(false);

        final SearchView search = (SearchView) MenuItemCompat
                .getActionView(menu.findItem(R.id.search).setVisible(true));
        search.setQueryHint(getString(R.string.stationFilterHintText));
        search.setOnSearchClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                search.requestFocus();
            }
        });

        search.setOnCloseListener(new SearchView.OnCloseListener() {
            @Override
            public boolean onClose() {
                mFilter = null;
                filter(mPager.getCurrentItem());
                return false;
            }
        });

        search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                mFilter = newText.trim();
                filter(mPager.getCurrentItem());
                return true;
            }
        });
        return true;
    }

    private void filter(int fragment) {
        if (mFilter == null)
            return;

        switch (fragment) {
        case 0:
            if (mAlphaStListFragment != null)
                mAlphaStListFragment.filter(mFilter);
        case 1:
            if (mLinesStListFragment != null)
                mLinesStListFragment.filter(mFilter);
        case 2:
            if (mRecentStListFragment != null)
                mRecentStListFragment.filter(mFilter);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            // app icon in action bar clicked; go home
            ((MetroApp) getApplication()).addEvent(Constants.SCREEN_SELECT_STATION + " " + getDirection(),
                    Constants.BACK, getTab());
            finish();
            return true;
        case R.id.btn_settings:
            ((MetroApp) getApplication()).addEvent(Constants.SCREEN_SELECT_STATION + " " + getDirection(),
                    Constants.MENU_SETTINGS, getTab());
            onSettings(false);
            return true;
        case R.id.btn_limitations:
            ((MetroApp) getApplication()).addEvent(Constants.SCREEN_SELECT_STATION + " " + getDirection(),
                    Constants.LIMITATIONS, getTab());
            onSettings(true);
            return true;
        case R.id.btn_about:
            ((MetroApp) getApplication()).addEvent(Constants.SCREEN_SELECT_STATION + " " + getDirection(),
                    Constants.MENU_ABOUT, getTab());
            Intent intentAbout = new Intent(this, AboutActivity.class);
            intentAbout.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intentAbout);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
        ((MetroApp) getApplication()).addEvent(Constants.SCREEN_SELECT_STATION + " " + getDirection(),
                Constants.BACK, getTab());

        super.onBackPressed();
    }

    private String getDirection() {
        return m_bIn ? Constants.FROM : Constants.TO;
    }

    private String getTab() {
        int i = getSupportActionBar().getSelectedTab().getPosition();
        return i == 0 ? Constants.TAB_AZ : i == 1 ? Constants.TAB_LINES : Constants.TAB_RECENT;
    }

    public void finish(int nStationId, int nPortalId) {
        JSONArray stationsIds = getRecentStations(prefs, isIn());
        String direction = isIn() ? KEY_PREF_RECENT_DEP_STATIONS : KEY_PREF_RECENT_ARR_STATIONS;
        int index = indexOf(stationsIds, nStationId);

        if (index == -1 && stationsIds.length() == MAX_RECENT_ITEMS) {
            stationsIds = remove(stationsIds, 0);
            stationsIds.put(nStationId);
        }

        if (index == -1 && stationsIds.length() < MAX_RECENT_ITEMS)
            stationsIds.put(nStationId);

        if (index != -1) {
            stationsIds = remove(stationsIds, index);
            stationsIds.put(nStationId);
        }

        prefs.edit().putString(direction, stationsIds.toString()).apply();

        mStationId = nStationId;
        mPortalId = nPortalId;
        finish();
    }

    @Override
    public void finish() {
        resultIntent.putExtra(BUNDLE_STATIONID_KEY, mStationId);
        resultIntent.putExtra(BUNDLE_PORTALID_KEY, mPortalId);
        resultIntent.putExtra(BUNDLE_CITY_CHANGED, isCityChanged);
        setResult(RESULT_OK, resultIntent);
        super.finish();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //update fragments to new data
        switch (requestCode) {
        case PREF_RESULT:
            if (data != null) {
                isCityChanged = isCityChanged ? isCityChanged : data.getBooleanExtra(BUNDLE_CITY_CHANGED, false);

                if (isCityChanged) {
                    clearRecent(PreferenceManager.getDefaultSharedPreferences(this));
                    mStationId = -1;
                    mPortalId = -1;
                }
            }

            if (mAlphaStListFragment != null)
                mAlphaStListFragment.update();
            if (mLinesStListFragment != null)
                mLinesStListFragment.update();
            if (mRecentStListFragment != null)
                mRecentStListFragment.update();
            break;
        case SUBSCREEN_PORTAL_RESULT:
            if (resultCode == RESULT_OK) {
                int stationID = data.getIntExtra(BUNDLE_STATIONID_KEY, 0);
                int portalID = data.getIntExtra(BUNDLE_PORTALID_KEY, 0);
                finish(stationID, portalID);
            }
            break;
        default:
            break;
        }
    }

    protected void onSettings(boolean isLimitations) {
        if (isLimitations)
            startActivity(new Intent(this, LimitationsActivity.class));
        //            startActivityForResult(new Intent(this, LimitationsActivity.class), PREF_RESULT);
        else {
            Intent intentSet = new Intent(this, PreferencesActivity.class);
            startActivityForResult(intentSet, PREF_RESULT);
        }
    }

    public static JSONArray getRecentStations(SharedPreferences prefs, boolean isDeparture) {
        String direction = isDeparture ? KEY_PREF_RECENT_DEP_STATIONS : KEY_PREF_RECENT_ARR_STATIONS;
        JSONArray stationIds = new JSONArray();

        try {
            stationIds = new JSONArray(prefs.getString(direction, "[]"));
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return stationIds;
    }

    public static int indexOf(JSONArray array, int item) {
        for (int i = 0; i < array.length(); i++) {
            try {
                if (item == array.get(i))
                    return i;
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        return -1;
    }

    public static JSONArray remove(JSONArray array, int index) {
        JSONArray replacedIds = new JSONArray();

        for (int i = 0; i < array.length(); i++)
            if (i != index)
                try {
                    replacedIds.put(array.get(i));
                } catch (JSONException e) {
                    e.printStackTrace();
                }

        return replacedIds;
    }
}