Java tutorial
/* * Copyright (C) 2017 Team Gateship-One * (Hendrik Borghorst & Frederik Luetkes) * * The AUTHORS.md file contains a detailed contributors list: * <https://github.com/gateship-one/malp/blob/master/AUTHORS.md> * * 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 org.gateshipone.malp.application.fragments.serverfragments; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.Resources; import android.graphics.drawable.Drawable; 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.FragmentStatePagerAdapter; import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v4.view.ViewPager; import android.support.v7.widget.SearchView; import android.util.Log; import android.util.SparseArray; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.View; import android.view.ViewGroup; import org.gateshipone.malp.R; import org.gateshipone.malp.application.callbacks.FABFragmentCallback; import org.gateshipone.malp.application.utils.ThemeUtils; public class MyMusicTabsFragment extends Fragment implements TabLayout.OnTabSelectedListener { public final static String TAG = MyMusicTabsFragment.class.getSimpleName(); public final static String MY_MUSIC_REQUESTED_TAB = "ARG_REQUESTED_TAB"; private MyMusicPagerAdapter mMyMusicPagerAdapter; public enum DEFAULTTAB { ARTISTS, ALBUMS } private FABFragmentCallback mFABCallback = null; private ViewPager mViewPager; private SearchView mSearchView; private Menu mOptionMenu; /** * Saved search string when user rotates devices */ private String mSearchString; /** * Constant for state saving */ public final static String MYMUSICFRAGMENT_SAVED_INSTANCE_SEARCH_STRING = "MyMusicFragment.SearchString"; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View rootView = inflater.inflate(R.layout.fragment_tab_pager, container, false); // create tabs TabLayout tabLayout = (TabLayout) rootView.findViewById(R.id.my_music_tab_layout); // Icons final ColorStateList tabColors = tabLayout.getTabTextColors(); Resources res = getResources(); Drawable drawable = res.getDrawable(R.drawable.ic_recent_actors_24dp, null); if (drawable != null) { Drawable icon = DrawableCompat.wrap(drawable); DrawableCompat.setTintList(icon, tabColors); tabLayout.addTab(tabLayout.newTab().setIcon(icon)); } drawable = res.getDrawable(R.drawable.ic_album_24dp, null); if (drawable != null) { Drawable icon = DrawableCompat.wrap(drawable); DrawableCompat.setTintList(icon, tabColors); tabLayout.addTab(tabLayout.newTab().setIcon(icon)); } tabLayout.setTabGravity(TabLayout.GRAVITY_FILL); mViewPager = (ViewPager) rootView.findViewById(R.id.my_music_viewpager); mMyMusicPagerAdapter = new MyMusicPagerAdapter(getChildFragmentManager()); mViewPager.setAdapter(mMyMusicPagerAdapter); mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); tabLayout.setOnTabSelectedListener(this); // set start page Bundle args = getArguments(); DEFAULTTAB tab = DEFAULTTAB.ALBUMS; if (args != null && savedInstanceState == null) { tab = DEFAULTTAB.values()[args.getInt(MY_MUSIC_REQUESTED_TAB)]; switch (tab) { case ARTISTS: mViewPager.setCurrentItem(0); break; case ALBUMS: mViewPager.setCurrentItem(1); break; } } // try to resume the saved search string if (savedInstanceState != null) { mSearchString = savedInstanceState.getString(MYMUSICFRAGMENT_SAVED_INSTANCE_SEARCH_STRING); } setHasOptionsMenu(true); return rootView; } @Override public void onTabSelected(TabLayout.Tab tab) { View view = this.getView(); if (view != null) { // dismiss searchview if (mSearchView != null && mOptionMenu != null && !mSearchView.isIconified()) { mSearchView.setIconified(true); mOptionMenu.findItem(R.id.action_search).collapseActionView(); } ViewPager myMusicViewPager = (ViewPager) view.findViewById(R.id.my_music_viewpager); myMusicViewPager.setCurrentItem(tab.getPosition()); } } @Override public void onResume() { super.onResume(); if (null != mFABCallback) { mFABCallback.setupFAB(false, null); mFABCallback.setupToolbar(getString(R.string.app_name), true, true, false); } } /** * Called when the fragment is first attached to its context. */ @Override public void onAttach(Context context) { super.onAttach(context); // This makes sure that the container activity has implemented // the callback interface. If not, it throws an exception try { mFABCallback = (FABFragmentCallback) context; } catch (ClassCastException e) { mFABCallback = null; } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // save the already typed search string (or null if nothing is entered) outState.putString(MYMUSICFRAGMENT_SAVED_INSTANCE_SEARCH_STRING, mSearchString); } /** * Initialize the options menu. * Be sure to call {@link #setHasOptionsMenu} before. * * @param menu The container for the custom options menu. * @param menuInflater The inflater to instantiate the layout. */ @Override public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) { // Inflate the menu; this adds items to the action bar if it is present. menuInflater.inflate(R.menu.fragment_menu_library, menu); mOptionMenu = menu; // get tint color int tintColor = ThemeUtils.getThemeColor(getContext(), R.attr.malp_color_text_accent); Drawable drawable = menu.findItem(R.id.action_search).getIcon(); drawable = DrawableCompat.wrap(drawable); DrawableCompat.setTint(drawable, tintColor); menu.findItem(R.id.action_search).setIcon(drawable); mSearchView = (SearchView) menu.findItem(R.id.action_search).getActionView(); // Check if a search string is saved from before if (mSearchString != null) { // Expand the view mSearchView.setIconified(false); menu.findItem(R.id.action_search).expandActionView(); // Set the query string mSearchView.setQuery(mSearchString, false); GenericMPDFragment fragment = mMyMusicPagerAdapter.getRegisteredFragment(mViewPager.getCurrentItem()); // Notify the adapter fragment.applyFilter(mSearchString); } mSearchView.setOnQueryTextListener(new SearchTextObserver()); super.onCreateOptionsMenu(menu, menuInflater); } @Override public void onTabUnselected(TabLayout.Tab tab) { GenericMPDFragment fragment = mMyMusicPagerAdapter.getRegisteredFragment(mViewPager.getCurrentItem()); if (null != fragment) { fragment.removeFilter(); } } @Override public void onTabReselected(TabLayout.Tab tab) { } private class MyMusicPagerAdapter extends FragmentStatePagerAdapter { static final int NUMBER_OF_PAGES = 2; private SparseArray<GenericMPDFragment> mRegisteredFragments; public MyMusicPagerAdapter(FragmentManager fm) { super(fm); mRegisteredFragments = new SparseArray<>(); } @Override public int getItemPosition(Object object) { return POSITION_NONE; } @Override public Object instantiateItem(ViewGroup container, int position) { GenericMPDFragment fragment = (GenericMPDFragment) super.instantiateItem(container, position); mRegisteredFragments.put(position, fragment); return fragment; } @Override public void destroyItem(ViewGroup container, int position, Object object) { mRegisteredFragments.remove(position); super.destroyItem(container, position, object); } @Override public Fragment getItem(int i) { switch (i) { case 0: return new ArtistsFragment(); case 1: return new AlbumsFragment(); default: return null; } } @Override public int getCount() { // this is done in order to reload all tabs return NUMBER_OF_PAGES; } public GenericMPDFragment getRegisteredFragment(int position) { return mRegisteredFragments.get(position); } } private class SearchTextObserver implements SearchView.OnQueryTextListener { @Override public boolean onQueryTextSubmit(String query) { applyFilter(query); return false; } @Override public boolean onQueryTextChange(String newText) { applyFilter(newText); return true; } private void applyFilter(String filter) { GenericMPDFragment fragment = mMyMusicPagerAdapter.getRegisteredFragment(mViewPager.getCurrentItem()); if (filter.isEmpty()) { mSearchString = null; fragment.removeFilter(); } else { mSearchString = filter; fragment.applyFilter(filter); } } } }