com.fastbootmobile.encore.app.fragments.PlaylistListFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.fastbootmobile.encore.app.fragments.PlaylistListFragment.java

Source

/*
 * Copyright (C) 2014 Fastboot Mobile, LLC.
 *
 * 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.fastbootmobile.encore.app.fragments;

import android.app.Activity;
import android.app.ActivityOptions;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Process;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.GridView;

import com.fastbootmobile.encore.app.MainActivity;
import com.fastbootmobile.encore.app.PlaylistActivity;
import com.fastbootmobile.encore.app.R;
import com.fastbootmobile.encore.app.adapters.PlaylistGridAdapter;
import com.fastbootmobile.encore.app.adapters.PlaylistListAdapter;
import com.fastbootmobile.encore.app.ui.MaterialTransitionDrawable;
import com.fastbootmobile.encore.model.Album;
import com.fastbootmobile.encore.model.Artist;
import com.fastbootmobile.encore.model.Playlist;
import com.fastbootmobile.encore.model.SearchResult;
import com.fastbootmobile.encore.model.Song;
import com.fastbootmobile.encore.providers.ILocalCallback;
import com.fastbootmobile.encore.providers.IMusicProvider;
import com.fastbootmobile.encore.providers.ProviderAggregator;
import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator;
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator;
import com.h6ah4i.android.widget.advrecyclerview.decoration.SimpleListDividerDecorator;
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager;

import org.json.JSONException;

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

/**
 * A simple {@link android.support.v4.app.Fragment} subclass, showing a list of playlists.
 * Use the {@link PlaylistListFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class PlaylistListFragment extends Fragment implements ILocalCallback {
    private static final String TAG = "PlaylistListFragment";

    private PlaylistListAdapter mAdapter;
    private PlaylistGridAdapter mGridAdapter;
    private LinearLayoutManager mLayoutManager;
    private RecyclerView mRecyclerView;
    private RecyclerViewDragDropManager mRecyclerViewDragDropManager;
    private RecyclerView.Adapter mWrappedAdapter;
    private Handler mHandler;
    private boolean mIsStandalone;
    private final ArrayList<Playlist> mPlaylistsUpdated = new ArrayList<>();

    private Runnable mUpdateListRunnable = new Runnable() {
        @Override
        public void run() {
            synchronized (mPlaylistsUpdated) {
                if (mAdapter != null) {
                    mAdapter.addAllUnique(mPlaylistsUpdated);
                }
                if (mGridAdapter != null) {
                    mGridAdapter.addAllUnique(mPlaylistsUpdated);
                }

                mPlaylistsUpdated.clear();
            }

            if (mAdapter != null && getActivity() != null) {
                try {
                    mAdapter.sortList(getActivity().getApplicationContext());
                } catch (JSONException e) {
                    Log.e(TAG, "Unable to sort playlists list");
                }
                mAdapter.notifyDataSetChanged();
            }
            if (mGridAdapter != null) {
                mGridAdapter.notifyDataSetChanged();
            }
        }
    };

    private Runnable mDataChangedRunnable = new Runnable() {
        @Override
        public void run() {
            if (mGridAdapter != null) {
                mGridAdapter.notifyDataSetChanged();
            }
            if (mAdapter != null) {
                mAdapter.notifyDataSetChanged();
            }
        }
    };

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param isStandalone Whether this fragment is embedded in My Songs or is the Playlists section
     * @return A new instance of fragment PlaylistListFragment.
     */
    public static PlaylistListFragment newInstance(boolean isStandalone) {
        PlaylistListFragment fragment = new PlaylistListFragment();
        fragment.setIsStandalone(isStandalone);
        return fragment;
    }

    /**
     * Default constructor. Use {@link #newInstance(boolean)} to create an instance of this fragment
     */
    public PlaylistListFragment() {
        mAdapter = new PlaylistListAdapter();
    }

    /**
     * Sets whether or not the fragment is displayed standalone (root of an activity's contents)
     * or within another container (e.g. a viewpager contents).
     * @param isStandalone Whether this fragment is embedded in My Songs or is the Playlists section
     */
    public void setIsStandalone(boolean isStandalone) {
        mIsStandalone = isStandalone;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mHandler = new Handler();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View root = inflater.inflate(R.layout.fragment_playlist, container, false);
        if (root instanceof GridView) {
            // We're in landscape, and thus have a GridView
            mGridAdapter = new PlaylistGridAdapter(root.getContext().getApplicationContext());
            mAdapter = null;
        } else {
            // We're in portrait with the recycler view
            mAdapter = new PlaylistListAdapter();
            mGridAdapter = null;
        }

        return root;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        // If mAdapter isn't null, we're in portrait with the draggable list view.
        if (mAdapter != null) {
            mRecyclerView = (RecyclerView) view.findViewById(R.id.rvPlaylists);
            mLayoutManager = new LinearLayoutManager(getContext());

            // drag & drop manager
            mRecyclerViewDragDropManager = new RecyclerViewDragDropManager();

            //adapter
            mWrappedAdapter = mRecyclerViewDragDropManager.createWrappedAdapter(mAdapter); // wrap for dragging

            final GeneralItemAnimator animator = new RefactoredDefaultItemAnimator();

            mRecyclerView.setLayoutManager(mLayoutManager);
            mRecyclerView.setAdapter(mWrappedAdapter); // requires *wrapped* adapter
            mRecyclerView.setItemAnimator(animator);

            // additional decorations
            mRecyclerView.addItemDecoration(
                    new SimpleListDividerDecorator(getResources().getDrawable(R.drawable.list_divider), true));

            mRecyclerViewDragDropManager.attachRecyclerView(mRecyclerView);

            if (!mIsStandalone) {
                mRecyclerView.setPadding(0, 0, 0, 0);
            }
        } else {
            // We're in landscape with the grid view
            GridView root = (GridView) view.findViewById(R.id.gvPlaylists);
            root.setAdapter(mGridAdapter);

            if (!mIsStandalone) {
                root.setPadding(0, 0, 0, 0);
            }

            // Setup the click listener
            root.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    MainActivity act = (MainActivity) getActivity();
                    PlaylistGridAdapter.ViewHolder tag = (PlaylistGridAdapter.ViewHolder) view.getTag();
                    Intent intent = PlaylistActivity.craftIntent(act, mGridAdapter.getItem(position),
                            ((MaterialTransitionDrawable) tag.ivCover.getDrawable()).getFinalDrawable()
                                    .getBitmap());

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        ActivityOptions opt = ActivityOptions.makeSceneTransitionAnimation(getActivity(),
                                tag.ivCover, "itemImage");
                        act.startActivity(intent, opt.toBundle());
                    } else {
                        act.startActivity(intent);
                    }
                }
            });
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (mIsStandalone) {
            MainActivity mainActivity = (MainActivity) activity;
            mainActivity.onSectionAttached(MainActivity.SECTION_PLAYLISTS);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        ProviderAggregator.getDefault().addUpdateCallback(this);
        updatePlaylists();
    }

    @Override
    public void onPause() {
        super.onPause();
        ProviderAggregator.getDefault().removeUpdateCallback(this);
    }

    private void updatePlaylists() {
        new GetPlaylistsTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

    @Override
    public void onSongUpdate(List<Song> s) {
    }

    @Override
    public void onAlbumUpdate(List<Album> a) {
    }

    @Override
    public void onPlaylistUpdate(final List<Playlist> p) {
        if (p != null) {
            synchronized (mPlaylistsUpdated) {
                mPlaylistsUpdated.addAll(p);
            }

            mHandler.removeCallbacks(mUpdateListRunnable);
            mHandler.post(mUpdateListRunnable);
        }
    }

    @Override
    public void onPlaylistRemoved(String ref) {
        Log.d(TAG, "Playlist removed: " + ref);
        if (ref != null) {
            synchronized (mPlaylistsUpdated) {
                for (Playlist playlist : mPlaylistsUpdated) {
                    if (playlist.getRef().equals(ref)) {
                        mPlaylistsUpdated.remove(playlist);
                        break;
                    }
                }
            }

            mAdapter.remove(ref);
            mHandler.removeCallbacks(mDataChangedRunnable);
            mHandler.post(mDataChangedRunnable);
        }
    }

    @Override
    public void onArtistUpdate(List<Artist> a) {
    }

    @Override
    public void onProviderConnected(final IMusicProvider provider) {
        new Thread() {
            public void run() {
                // HACK: Wait a bit for the provider to be ready
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ignore) {
                }

                try {
                    onPlaylistUpdate(provider.getPlaylists());
                } catch (RemoteException e) {
                    Log.e(TAG, "Cannot get playlists");
                }
            }
        }.start();
    }

    @Override
    public void onSearchResult(List<SearchResult> searchResult) {
    }

    private class GetPlaylistsTask extends AsyncTask<Void, Void, List<Playlist>> {
        @Override
        protected List<Playlist> doInBackground(Void... params) {
            Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
            return ProviderAggregator.getDefault().getAllPlaylists();
        }

        @Override
        protected void onPostExecute(List<Playlist> playlists) {
            if (mAdapter != null) {
                mAdapter.clear();
                mAdapter.addAllUnique(playlists);

                Activity activity = getActivity();

                if (activity != null) {
                    try {
                        mAdapter.sortList(activity.getApplicationContext());
                    } catch (JSONException e) {
                        Log.e(TAG, "Unable to sort playlists list");
                    }
                }

                mAdapter.notifyDataSetChanged();
            }

            if (mGridAdapter != null) {
                mGridAdapter.clear();
                mGridAdapter.addAllUnique(playlists);
                mGridAdapter.notifyDataSetChanged();
            }
        }
    }
}