uk.org.downiesoft.slideshow.SlidesFragment.java Source code

Java tutorial

Introduction

Here is the source code for uk.org.downiesoft.slideshow.SlidesFragment.java

Source

/* 
 Copyright 2014-2016 Alan G. Downie
    
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
    
 http://www.apache.org/licenses/LICENSE-2.0
    
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
package uk.org.downiesoft.slideshow;

import android.app.ActionBar;
import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.content.res.ResourcesCompat;
import android.view.ActionMode;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnSystemUiVisibilityChangeListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

/** 
 * Extension of {@link uk.org.downiesoft.slideshow.SlideBufferFragment} to manage slideshow UI
 */
public class SlidesFragment extends SlideBufferFragment implements ActionMode.Callback {

    public static final String TAG = SlidesFragment.class.getName();

    /** Reference to ProgressBar from layout. */
    private ProgressBar mProgress;

    /** Flag indicating if there is a slide show in progress. */
    private boolean mSlideshowRunning = false;
    /** The currently active ActionMode (or null if not active). */
    private ActionMode mActionMode;

    /** A handler for posting future events (slide change, UI hide) */
    private Handler mSlideshowHandler = new Handler();
    /** Runnable to change slides. */
    private Runnable slideshowRunnable = new Runnable() {
        @Override
        public void run() {
            SlideShowActivity.debug(2, TAG, "slideshowRunnable.nextImage");
            nextImage(-1);
            resetSlideTimer();
        }
    };
    /** UIHider to manage immersive mode changes to UI. */
    private UiHider mUiHider;

    /**
     * {@inheritDoc}
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        Point displaySize = new Point();
        getActivity().getWindowManager().getDefaultDisplay().getRealSize(displaySize);
        mDisplaySize.set(displaySize.x, displaySize.y);
        mUiHider = new UiHider(getActivity());
        mUiHider.showUi(true);
        /* Reference to main layout. */
        View view = inflater.inflate(R.layout.imageview_fragment, container, false);
        this.setHasOptionsMenu(true);
        mImageViews[mCurrentView] = (ScaleableImageView) view.findViewById(R.id.fullscreen_content);
        mImageViews[mPrevView] = (ScaleableImageView) view.findViewById(R.id.fullscreen_prevbmp);
        mImageViews[mNextView] = (ScaleableImageView) view.findViewById(R.id.fullscreen_nextbmp);
        mFilenameText = (TextView) view.findViewById(R.id.fullscreen_text);
        mProgress = (ProgressBar) view.findViewById(R.id.imageviewProgressBar);
        mEmptyText = (TextView) view.findViewById(R.id.slideEmptyText);
        setViewPositions();
        Window window = getActivity().getWindow();
        window.getDecorView().setOnSystemUiVisibilityChangeListener(mUiHider);
        return view;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onStart() {
        super.onStart();
        if (mAutostart) {
            sSlideBuffer.invalidate();
            startSlideshow(matchOrientation());
            mAutostart = false;
        } else {
            sSlideBuffer.setParams(this, sPresentation, mDisplaySize, true);
            setImage(getCurrentImage(), 0, TRANSITION_NONE);
            sSlideBuffer.rebuffer();
            mUiHider.showUi(true);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onStop() {
        super.onStop();
        mSlideshowHandler.removeCallbacks(slideshowRunnable);
        mUiHider.cancelHide();
        getActivity().getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onDestroy() {
        super.onDestroy();
        if (sPresentation != null)
            sPresentation.close();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.slidesfragment_menu, menu);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        menu.setGroupVisible(R.id.menu_group_start_slideshow, !mSlideshowRunning);
        menu.setGroupVisible(R.id.menu_group_stop_slideshow, mSlideshowRunning);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.action_start_slideshow:
            startSlideshow(matchOrientation());
            return true;
        case R.id.action_stop_slideshow:
            if (mSlideshowRunning) {
                stopSlideshow();
            }
            return true;
        default:
            return false;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        resetSlideTimer();
    }

    /**
     * Called by activity when back key is pressed. Used by this fragment to
     * stop a running slideshow.
     * @return True if the back key has been consumed, otherwise false.
     */
    public boolean offerBackKey() {
        SlideShowActivity.debug(1, TAG, "offerBackKey() %s", mSlideshowRunning);
        if (mSlideshowRunning) {
            stopSlideshow();
            mUiHider.showUi(true);
            return true;
        }
        return false;
    }

    /**
     * Cancel any pending slide change callback and resubmit a new one with the original delay.
     */
    private void resetSlideTimer() {
        mSlideshowHandler.removeCallbacks(slideshowRunnable);
        if (mSlideshowRunning) {
            mSlideshowHandler.postDelayed(slideshowRunnable, interval() * 1000);
        }
    }

    /**
     * Stop the current slideshow.
     * Resets any filter and randomisation while still showing the slide we stopped at.
     */
    private void stopSlideshow() {
        mSlideshowHandler.removeCallbacks(slideshowRunnable);
        mSlideshowRunning = false;
        mUiHider.showUi(true);
        sPresentation.clearFilter();
        sPresentation.setRandomise(false);
        setImage(getCurrentImage());
        Window window = getActivity().getWindow();
        window.setFlags(0, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        getActivity().invalidateOptionsMenu();
    }

    /**
     * Start a slideshow.
     * @param aMatchOrientation If true, filter the slides to match the current orientation and callback.
     */
    private void startSlideshow(boolean aMatchOrientation) {
        if (aMatchOrientation) {
            mEmptyText.setText(R.string.text_finding_images);
            new FilterTask().executeOnExecutor(SlideShowActivity.THREAD_POOL_EXECUTOR);
        } else {
            if (sPresentation.getCount() > 0) {
                sPresentation.setRandomise(randomise());
                int interval = Integer
                        .parseInt(mSlideshowSettings.getString(getString(R.string.PREFS_INTERVAL), "5"));
                mSlideshowHandler.postDelayed(slideshowRunnable, interval * 1000);
                if (!mAutostart) {
                    mUiHider.delayedHide(100);
                } else {
                    mUiHider.hideUi();
                }
                mSlideshowRunning = true;
                Activity activity = getActivity();
                if (activity != null) {
                    Window window = getActivity().getWindow();
                    window.setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
                            WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
                    sSlideBuffer.showSlide(sPresentation.currentEntry());
                }
            } else {
                mEmptyText.setText(R.string.text_no_suitable_image);
                Toast.makeText(getActivity(), R.string.text_no_suitable_image, Toast.LENGTH_SHORT).show();
                sPresentation.clearFilter();
                getActivity().finish();
            }
        }
        getActivity().invalidateOptionsMenu();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int transitionEffect() {
        if (!mSlideshowRunning) {
            return TRANSITION_WIPE;
        } else {
            return Integer.parseInt(mSlideshowSettings.getString(getString(R.string.PREFS_TRANSITION_EFFECT), "0"));
        }
    }

    /**
     * Called by child views to determine if touch actions are disabled.
     * @return True if touch actions are disabled in child views.
     */
    public boolean isLocked() {
        return super.isLocked() || mSlideshowRunning;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doSingleTap() {
        SlideShowActivity.debug(2, TAG, "doSingleTap");
        if (mSlideshowRunning) {
            stopSlideshow();
        }
        mUiHider.toggleUi();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doDoubleTap() {
        resetSlideTimer();
        super.doDoubleTap();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doLongPress() {
        SlideShowActivity.debug(1, TAG, "doLongPress(): slideshow running=%s", mSlideshowRunning);
        if (!mSlideshowRunning) {
            mUiHider.showUi(false);
            if (mActionMode == null) {
                mActionMode = getActivity().startActionMode(SlidesFragment.this);
            }
        }
        getActivity().invalidateOptionsMenu();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean onCreateActionMode(ActionMode p1, Menu p2) {
        MenuInflater inflater = p1.getMenuInflater();
        inflater.inflate(R.menu.slides_context, p2);
        //      Window window = getActivity().getWindow();
        //      int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        //            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        //            | View.SYSTEM_UI_FLAG_LOW_PROFILE
        //            | View.SYSTEM_UI_FLAG_FULLSCREEN
        //            | View.SYSTEM_UI_FLAG_IMMERSIVE;
        //      window.getDecorView().setSystemUiVisibility(flags);
        getViewBounds(true, mScratchRects);
        mImageViews[mPrevView].setTranslationX(mScratchRects[mPrevView].left);
        mImageViews[mNextView].setTranslationX(mScratchRects[mNextView].left);
        UiHider.setActionMode(true);
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean onPrepareActionMode(ActionMode p1, Menu p2) {
        Window window = getActivity().getWindow();
        //      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        //         window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 
        //         window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); 
        //         window.setStatusBarColor(mColorBlueOverlay);
        //         window.setNavigationBarColor(mColorBlackOverlay);
        //      }
        if (sPresentation.getType() == Presentation.LIST_PRESENTATION) {
            p2.removeItem(R.id.action_add_favourite);
        }
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        switch (item.getItemId()) {
        case R.id.context_set_wallpaper:
            Bitmap bitmap = mImageViews[mCurrentView].getSnapshot();
            if (bitmap != null) {
                BitmapManager.setWallpaper(getActivity(), bitmap);
            } else {
                Toast.makeText(getActivity(), R.string.text_wallpaper_failed, Toast.LENGTH_SHORT).show();
            }
            break;
        case R.id.context_take_snapshot:
            BitmapManager.saveSnapshot(getActivity(), sPresentation, getCurrentImage(), mImageViews[mCurrentView]);
            break;
        case R.id.action_properties:
            BitmapManager.displayBitmapProperties(getActivity(), this.sPresentation,
                    sPresentation.getCurrentSlideIndex());
            break;
        case R.id.action_add_favourite:
            ListPresentation favourites = FavouritesManager.getInstance(getActivity());
            favourites.add(sPresentation.getFullPath(getCurrentImage()).getPath());
            favourites.save(true);
            Toast.makeText(getActivity(), R.string.text_added_favourite, Toast.LENGTH_SHORT).show();
            break;
        default:
            return false;
        }
        mode.finish();
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onDestroyActionMode(ActionMode p1) {
        mActionMode = null;
        mUiHider.delayedHide();
        UiHider.setActionMode(false);
    }

    /**
     * Called by parent activity to handle cursor key events.
     * @param keyCode The keycode associated with the key pressed.
     * @return true if the keycode was consumed.
     */
    public boolean onKeyUp(int keyCode) {
        switch (keyCode) {
        case KeyEvent.KEYCODE_DPAD_LEFT:
            prevImage(1);
            return true;
        case KeyEvent.KEYCODE_DPAD_RIGHT:
        case KeyEvent.KEYCODE_SPACE:
            nextImage(-1);
            return true;
        case KeyEvent.KEYCODE_DPAD_UP:
            mUiHider.hideUi();
            return true;
        case KeyEvent.KEYCODE_DPAD_DOWN:
            mUiHider.showUi(false);
            return true;
        }
        return false;
    }

    /**
     * Background task to filter images by orientation before starting slide show.
     */
    private class FilterTask extends AsyncTask<Void, Void, Void> {

        /**
         * {@inheritDoc}
         */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mProgress.setVisibility(View.VISIBLE);
            mProgress.bringToFront();
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected Void doInBackground(Void... p1) {
            sPresentation.filterOrientation(mDisplaySize.x, mDisplaySize.y);
            sSlideBuffer.invalidate();
            return null;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            mProgress.setVisibility(View.GONE);
            startSlideshow(false);
        }

    }

}