org.videolan.vlc2.gui.audio.AudioBrowserFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.videolan.vlc2.gui.audio.AudioBrowserFragment.java

Source

/*****************************************************************************
 * AudioBrowserActivity.java
 *****************************************************************************
 * Copyright  2011-2012 VLC authors and VideoLAN
 *
 * 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 2 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

package org.videolan.vlc2.gui.audio;

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

import org.videolan.libvlc.LibVlcUtil;
import org.videolan.libvlc.Media;
import org.videolan.vlc2.MediaLibrary;
import org.videolan.vlc2.R;
import org.videolan.vlc2.audio.AudioServiceController;
import org.videolan.vlc2.gui.CommonDialogs;
import org.videolan.vlc2.gui.MainActivity;
import org.videolan.vlc2.util.AndroidDevices;
import org.videolan.vlc2.util.VLCRunnable;
import org.videolan.vlc2.util.WeakHandler;
import org.videolan.vlc2.widget.FlingViewGroup;
import org.videolan.vlc2.widget.FlingViewGroup.ViewSwitchListener;
import org.videolan.vlc2.widget.HeaderScrollView;

import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;

public class AudioBrowserFragment extends Fragment {
    public final static String TAG = "VLC/AudioBrowserFragment";

    private FlingViewGroup mFlingViewGroup;
    private int mFlingViewPosition = 0;

    private HeaderScrollView mHeader;
    private AudioServiceController mAudioController;
    private MediaLibrary mMediaLibrary;

    private AudioBrowserListAdapter mSongsAdapter;
    private AudioBrowserListAdapter mArtistsAdapter;
    private AudioBrowserListAdapter mAlbumsAdapter;
    private AudioBrowserListAdapter mGenresAdapter;

    private View mEmptyView;

    public final static int MODE_TOTAL = 4; // Number of audio browser modes
    public final static int MODE_ARTIST = 0;
    public final static int MODE_ALBUM = 1;
    public final static int MODE_SONG = 2;
    public final static int MODE_GENRE = 3;

    /* All subclasses of Fragment must include a public empty constructor. */
    public AudioBrowserFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mAudioController = AudioServiceController.getInstance();

        mMediaLibrary = MediaLibrary.getInstance();

        mSongsAdapter = new AudioBrowserListAdapter(getActivity(), AudioBrowserListAdapter.ITEM_WITH_COVER);
        mArtistsAdapter = new AudioBrowserListAdapter(getActivity(), AudioBrowserListAdapter.ITEM_WITH_COVER);
        mAlbumsAdapter = new AudioBrowserListAdapter(getActivity(), AudioBrowserListAdapter.ITEM_WITH_COVER);
        mGenresAdapter = new AudioBrowserListAdapter(getActivity(), AudioBrowserListAdapter.ITEM_WITHOUT_COVER);

        mSongsAdapter.setContextPopupMenuListener(mContextPopupMenuListener);
        mArtistsAdapter.setContextPopupMenuListener(mContextPopupMenuListener);
        mAlbumsAdapter.setContextPopupMenuListener(mContextPopupMenuListener);
        mGenresAdapter.setContextPopupMenuListener(mContextPopupMenuListener);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        ((ActionBarActivity) getActivity()).getSupportActionBar().setTitle(R.string.audio);

        View v = inflater.inflate(R.layout.audio_browser, container, false);

        mFlingViewGroup = (FlingViewGroup) v.findViewById(R.id.content);
        mFlingViewGroup.setOnViewSwitchedListener(mViewSwitchListener);

        mHeader = (HeaderScrollView) v.findViewById(R.id.header);
        mHeader.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent e) {
                // prevent the user from scrolling the header
                return true;
            }
        });

        mEmptyView = v.findViewById(R.id.no_media);

        ListView songsList = (ListView) v.findViewById(R.id.songs_list);
        ListView artistList = (ListView) v.findViewById(R.id.artists_list);
        ListView albumList = (ListView) v.findViewById(R.id.albums_list);
        ListView genreList = (ListView) v.findViewById(R.id.genres_list);

        songsList.setAdapter(mSongsAdapter);
        artistList.setAdapter(mArtistsAdapter);
        albumList.setAdapter(mAlbumsAdapter);
        genreList.setAdapter(mGenresAdapter);

        songsList.setOnItemClickListener(songListener);
        artistList.setOnItemClickListener(artistListListener);
        albumList.setOnItemClickListener(albumListListener);
        genreList.setOnItemClickListener(genreListListener);

        registerForContextMenu(songsList);
        registerForContextMenu(artistList);
        registerForContextMenu(albumList);
        registerForContextMenu(genreList);

        return v;
    }

    @Override
    public void onPause() {
        super.onPause();
        mMediaLibrary.removeUpdateHandler(mHandler);
    }

    @Override
    public void onResume() {
        super.onResume();
        mFlingViewGroup.setPosition(mFlingViewPosition);
        mHeader.highlightTab(-1, mFlingViewPosition);
        mHeader.scroll(mFlingViewPosition / 3.f);
        updateLists();
        mMediaLibrary.addUpdateHandler(mHandler);
    }

    OnItemClickListener songListener = new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> av, View v, int p, long id) {
            ArrayList<String> mediaLocation = mSongsAdapter.getLocations(p);
            mAudioController.load(mediaLocation, 0);
        }
    };

    OnItemClickListener artistListListener = new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> av, View v, int p, long id) {
            ArrayList<Media> mediaList = mArtistsAdapter.getMedia(p);
            MainActivity activity = (MainActivity) getActivity();
            AudioAlbumsSongsFragment frag = (AudioAlbumsSongsFragment) activity
                    .showSecondaryFragment("albumsSongs");
            if (frag != null) {
                frag.setMediaList(mediaList, mediaList.get(0).getArtist());
            }
        }
    };

    OnItemClickListener albumListListener = new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> av, View v, int p, long id) {
            ArrayList<String> mediaLocation = mAlbumsAdapter.getLocations(p);
            mAudioController.load(mediaLocation, 0);
        }
    };

    OnItemClickListener genreListListener = new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> av, View v, int p, long id) {
            ArrayList<Media> mediaList = mGenresAdapter.getMedia(p);
            MainActivity activity = (MainActivity) getActivity();
            AudioAlbumsSongsFragment frag = (AudioAlbumsSongsFragment) activity
                    .showSecondaryFragment("albumsSongs");
            if (frag != null) {
                frag.setMediaList(mediaList, mediaList.get(0).getGenre());
            }
        }
    };

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        MenuInflater inflater = getActivity().getMenuInflater();
        inflater.inflate(R.menu.audio_list_browser, menu);
        setContextMenuItems(menu, v);
    }

    private void setContextMenuItems(Menu menu, View v) {
        final int pos = mFlingViewGroup.getPosition();
        if (pos != MODE_SONG) {
            menu.setGroupVisible(R.id.songs_view_only, false);
            menu.setGroupVisible(R.id.phone_only, false);
        }
        if (pos == MODE_ARTIST || v.getId() == MODE_GENRE) {
            MenuItem play = menu.findItem(R.id.audio_list_browser_play);
            play.setVisible(true);
        }
        if (!AndroidDevices.isPhone())
            menu.setGroupVisible(R.id.phone_only, false);
    }

    @Override
    public boolean onContextItemSelected(MenuItem menu) {
        if (!getUserVisibleHint())
            return super.onContextItemSelected(menu);

        AdapterContextMenuInfo info = (AdapterContextMenuInfo) menu.getMenuInfo();
        if (info != null && handleContextItemSelected(menu, info.position))
            return true;
        return super.onContextItemSelected(menu);
    }

    private boolean handleContextItemSelected(MenuItem item, int position) {
        ContextMenuInfo menuInfo = item.getMenuInfo();

        int startPosition;
        int groupPosition;
        List<String> medias;
        int id = item.getItemId();

        boolean useAllItems = id == R.id.audio_list_browser_play_all;
        boolean append = id == R.id.audio_list_browser_append;

        if (ExpandableListContextMenuInfo.class.isInstance(menuInfo)) {
            ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuInfo;
            groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition);
        } else
            groupPosition = position;

        if (id == R.id.audio_list_browser_delete) {
            AlertDialog alertDialog = CommonDialogs.deleteMedia(getActivity(),
                    mSongsAdapter.getLocations(groupPosition).get(0),
                    new VLCRunnable(mSongsAdapter.getItem(groupPosition)) {
                        @Override
                        public void run(Object o) {
                            AudioBrowserListAdapter.ListItem listItem = (AudioBrowserListAdapter.ListItem) o;
                            Media media = listItem.mMediaList.get(0);
                            mMediaLibrary.getMediaItems().remove(media);
                            mAudioController.removeLocation(media.getLocation());
                            updateLists();
                        }
                    });
            alertDialog.show();
            return true;
        }

        if (id == R.id.audio_list_browser_set_song) {
            AudioUtil.setRingtone(mSongsAdapter.getItem(groupPosition).mMediaList.get(0), getActivity());
            return true;
        }

        if (useAllItems) {
            medias = new ArrayList<String>();
            startPosition = mSongsAdapter.getListWithPosition(medias, groupPosition);
        } else {
            startPosition = 0;
            switch (mFlingViewGroup.getPosition()) {
            case MODE_SONG:
                medias = mSongsAdapter.getLocations(groupPosition);
                break;
            case MODE_ARTIST:
                medias = mArtistsAdapter.getLocations(groupPosition);
                break;
            case MODE_ALBUM:
                medias = mAlbumsAdapter.getLocations(groupPosition);
                break;
            case MODE_GENRE:
                medias = mGenresAdapter.getLocations(groupPosition);
                break;
            default:
                return true;
            }
        }

        if (append)
            mAudioController.append(medias);
        else
            mAudioController.load(medias, startPosition);

        return super.onContextItemSelected(item);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mSongsAdapter.clear();
        mArtistsAdapter.clear();
        mAlbumsAdapter.clear();
        mGenresAdapter.clear();
    }

    private final ViewSwitchListener mViewSwitchListener = new ViewSwitchListener() {

        @Override
        public void onSwitching(float progress) {
            mHeader.scroll(progress);
        }

        @Override
        public void onSwitched(int position) {
            mHeader.highlightTab(mFlingViewPosition, position);
            mFlingViewPosition = position;
        }

        @Override
        public void onTouchDown() {
        }

        @Override
        public void onTouchUp() {
        }

        @Override
        public void onTouchClick() {
        }

        @Override
        public void onBackSwitched() {
        }
    };

    /**
     * Handle changes on the list
     */
    private Handler mHandler = new AudioBrowserHandler(this);

    private static class AudioBrowserHandler extends WeakHandler<AudioBrowserFragment> {
        public AudioBrowserHandler(AudioBrowserFragment owner) {
            super(owner);
        }

        @Override
        public void handleMessage(Message msg) {
            AudioBrowserFragment fragment = getOwner();
            if (fragment == null)
                return;

            switch (msg.what) {
            case MediaLibrary.MEDIA_ITEMS_UPDATED:
                fragment.updateLists();
                break;
            }
        }
    };

    private void updateLists() {
        List<Media> audioList = MediaLibrary.getInstance().getAudioItems();

        if (audioList.isEmpty())
            mEmptyView.setVisibility(View.VISIBLE);
        else
            mEmptyView.setVisibility(View.GONE);

        mSongsAdapter.clear();
        mArtistsAdapter.clear();
        mAlbumsAdapter.clear();
        mGenresAdapter.clear();

        Collections.sort(audioList, MediaComparators.byName);
        for (int i = 0; i < audioList.size(); i++) {
            Media media = audioList.get(i);
            mSongsAdapter.add(media.getTitle(), media.getArtist(), media);
        }
        mSongsAdapter.addScrollSections();

        Collections.sort(audioList, MediaComparators.byArtist);
        for (int i = 0; i < audioList.size(); i++) {
            Media media = audioList.get(i);
            mArtistsAdapter.add(media.getArtist(), null, media);
        }
        mArtistsAdapter.addLetterSeparators();

        Collections.sort(audioList, MediaComparators.byAlbum);
        for (int i = 0; i < audioList.size(); i++) {
            Media media = audioList.get(i);
            mAlbumsAdapter.add(media.getAlbum(), media.getArtist(), media);
        }
        mAlbumsAdapter.addLetterSeparators();

        Collections.sort(audioList, MediaComparators.byGenre);
        for (int i = 0; i < audioList.size(); i++) {
            Media media = audioList.get(i);
            mGenresAdapter.add(media.getGenre(), null, media);
        }
        mGenresAdapter.addLetterSeparators();

        mSongsAdapter.notifyDataSetChanged();
        mArtistsAdapter.notifyDataSetChanged();
        mAlbumsAdapter.notifyDataSetChanged();
        mGenresAdapter.notifyDataSetChanged();
        // Refresh the fast scroll data, since SectionIndexer doesn't respect notifyDataSetChanged
        int[] lists = { R.id.songs_list, R.id.artists_list, R.id.albums_list, R.id.genres_list };
        if (getView() != null) {
            for (int r : lists) {
                ListView l = (ListView) getView().findViewById(r);
                l.setFastScrollEnabled(false);
                l.setFastScrollEnabled(true);
            }
        }
    }

    AudioBrowserListAdapter.ContextPopupMenuListener mContextPopupMenuListener = new AudioBrowserListAdapter.ContextPopupMenuListener() {

        @Override
        @TargetApi(Build.VERSION_CODES.HONEYCOMB)
        public void onPopupMenu(View anchor, final int position) {
            if (!LibVlcUtil.isHoneycombOrLater()) {
                // Call the "classic" context menu
                anchor.performLongClick();
                return;
            }

            PopupMenu popupMenu = new PopupMenu(getActivity(), anchor);
            popupMenu.getMenuInflater().inflate(R.menu.audio_list_browser, popupMenu.getMenu());
            setContextMenuItems(popupMenu.getMenu(), anchor);

            popupMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    return handleContextItemSelected(item, position);
                }
            });
            popupMenu.show();
        }

    };
}