tw.idv.palatis.danboorugallery.PostDetailActivity.java Source code

Java tutorial

Introduction

Here is the source code for tw.idv.palatis.danboorugallery.PostDetailActivity.java

Source

////////////////////////////////////////////////////////////////////////////////
// Danbooru Gallery Android - an danbooru-style imageboard browser
//     Copyright (C) 2014  Victor Tseng
//
//     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 tw.idv.palatis.danboorugallery;

import android.annotation.TargetApi;
import android.app.ActionBar;
import android.app.Activity;
import android.app.LoaderManager;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.support.v4.view.ViewPager;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;

import tw.idv.palatis.danboorugallery.android.content.CustomTaskLoader;
import tw.idv.palatis.danboorugallery.database.PostsTable;
import tw.idv.palatis.danboorugallery.model.Host;
import tw.idv.palatis.danboorugallery.model.Post;
import tw.idv.palatis.danboorugallery.util.PostDetailPagerAdapter;
import tw.idv.palatis.danboorugallery.util.SiteSession;
import tw.idv.palatis.danboorugallery.util.SystemUiHider;
import tw.idv.palatis.danboorugallery.util.UiHider;

public class PostDetailActivity extends Activity implements PostDetailFragment.Callbacks,
        LoaderManager.LoaderCallbacks<Cursor>, ViewPager.OnPageChangeListener {
    public static final String TAG = "PostDetailActivity";

    private static final int AUTO_HIDE_DELAY_MILLIS = 3000;

    private UiHider mUiHider;
    private ViewPager mViewPager;
    private LinearLayout mControlsView;
    private PostDetailPagerAdapter mPagerAdapter;
    private TextView mInfoText;
    private ImageButton mPlayPauseButton;

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    }

    @Override
    public void onPageSelected(int position) {
        mPosition = position;
        Cursor post_cursor = mPagerAdapter.getCursor(mPosition);
        if (post_cursor != null && post_cursor.getCount() != 0) {
            Host host = SiteSession.getHostById(post_cursor.getInt(PostsTable.INDEX_POST_HOST_ID));
            Post post = Post.fromCursor(host, post_cursor, null);
            mInfoText.setText(post.describeContent(this));

            // FIXME: hard coded page limit
            boolean forced = (position < 10) || (position > post_cursor.getCount() - 10);
            long created_at = post_cursor.getLong(PostsTable.INDEX_POST_CREATED_AT);
            SiteSession.fetchPosts(created_at, forced, null);
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }

    private Runnable mNextPageRunnable = new Runnable() {
        @Override
        public void run() {
            int next = mViewPager.getCurrentItem() + 1;
            if (next >= mViewPager.getAdapter().getCount())
                next = 0;
            int nextnext = next + 1;
            if (nextnext >= mViewPager.getAdapter().getCount())
                nextnext = 0;
            mViewPager.getAdapter().instantiateItem(mViewPager, nextnext);
            mViewPager.setCurrentItem(next, next != 0);
            mViewPager.postDelayed(this, DanbooruGallerySettings.getAutoplayDelay());
        }
    };

    private DataSetObserver mPostsObserver = new DataSetObserver() {
        @Override
        public void onChanged() {
            super.onChanged();
        }

        @Override
        public void onInvalidated() {
            super.onInvalidated();
            mPagerAdapter.swapCursor(null);
        }
    };

    private int mPosition;

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
        return new CustomTaskLoader<Cursor>(getApplicationContext()) {
            @Override
            public Cursor runTaskInBackground(CancellationSignal signal) {
                return SiteSession.getAllPostsCursor(PostsTable.POST_ALL_COLUMNS);
            }

            @Override
            public void cleanUp(Cursor oldCursor) {
            }
        };
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        if (mPosition != -1) {
            // tries to find the position in the new cursor
            Cursor oldCursor = mPagerAdapter.getCursor(mPosition);
            if (oldCursor != null) {
                int post_id = oldCursor.getInt(PostsTable.INDEX_POST_POST_ID);
                cursor.moveToPosition(-1);
                while (cursor.moveToNext())
                    if (cursor.getInt(PostsTable.INDEX_POST_POST_ID) == post_id) {
                        mPosition = cursor.getPosition();
                        break;
                    }
            }
        }

        mPagerAdapter.swapCursor(cursor);
        mViewPager.setCurrentItem(mPosition, false);
        cursor.moveToPosition(mPosition);
        Host host = SiteSession.getHostById(cursor.getInt(PostsTable.INDEX_POST_HOST_ID));
        Post post = Post.fromCursor(host, cursor, null);
        mInfoText.setText(post.describeContent(PostDetailActivity.this));
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        mPagerAdapter.swapCursor(null);
    }

    private boolean mIsAutoplaying = false;

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

        if (mIsAutoplaying) {
            mViewPager.removeCallbacks(mNextPageRunnable);
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            mPlayPauseButton.setImageResource(android.R.drawable.ic_media_play);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_post_detail);

        setupActionBar();

        mViewPager = (ViewPager) findViewById(R.id.post_detail_pager);
        mControlsView = (LinearLayout) findViewById(R.id.post_detail_content_controls);
        mInfoText = (TextView) findViewById(R.id.post_detail_info);
        mPlayPauseButton = (ImageButton) findViewById(R.id.post_detail_button_autoplay);

        mPlayPauseButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mIsAutoplaying = !mIsAutoplaying) {
                    mPlayPauseButton.setImageResource(android.R.drawable.ic_media_pause);
                    mViewPager.postDelayed(mNextPageRunnable, DanbooruGallerySettings.getAutoplayDelay());
                    mUiHider.hide();
                    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
                } else {
                    mPlayPauseButton.setImageResource(android.R.drawable.ic_media_play);
                    mViewPager.removeCallbacks(mNextPageRunnable);
                    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
                }
            }
        });
        mPlayPauseButton.setImageResource(android.R.drawable.ic_media_play);

        PostsTable.registerDataSetObserver(mPostsObserver);

        // FIXME: hard coded key
        if (savedInstanceState == null)
            mPosition = getIntent().getIntExtra("post_position", -1);
        else
            mPosition = savedInstanceState.getInt("post_position", -1);

        mPagerAdapter = new PostDetailPagerAdapter(getFragmentManager(), null);
        mViewPager.setOnPageChangeListener(this);
        mViewPager.setAdapter(mPagerAdapter);
        mViewPager.setPageMargin(16); // TODO: i'm lazy to calculate dp here...

        mViewPager.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                if (mIsAutoplaying) {
                    mViewPager.removeCallbacks(mNextPageRunnable);
                    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
                    mPlayPauseButton.setImageResource(android.R.drawable.ic_media_play);
                }
                return false;
            }
        });

        mUiHider = new SystemUiHider(getWindow().getDecorView(), AUTO_HIDE_DELAY_MILLIS,
                new UiHider.OnVisibilityChangeListener() {
                    // Cached values.
                    int mShortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);

                    @Override
                    @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
                    public void onVisibilityChange(boolean visible) {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
                            // If the ViewPropertyAnimator API is available
                            // (Honeycomb MR2 and later), use it to animate the
                            // in-layout UI controls at the bottom of the
                            // screen.
                            mControlsView.animate().alpha(visible ? 1.0f : 0.0f).setDuration(mShortAnimTime);
                        } else {
                            // If the ViewPropertyAnimator APIs aren't
                            // available, simply show or hide the in-layout UI
                            // controls.
                            mControlsView.setVisibility(visible ? View.VISIBLE : View.GONE);
                        }

                        if (visible)
                            getActionBar().show();
                        else
                            getActionBar().hide();
                    }
                });

        getLoaderManager().initLoader(R.id.loader_post_ids, null, this);
    }

    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);

        // Trigger the initial hide() shortly after the activity has been
        // created, to briefly hint to the user that UI controls
        // are available.
        mUiHider.show();
        mUiHider.delayedHide(AUTO_HIDE_DELAY_MILLIS);
    }

    /**
     * Set up the {@link android.app.ActionBar}, if the API is available.
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void setupActionBar() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            // Show the Up button in the action bar.
            getActionBar().setDisplayHomeAsUpEnabled(true);
            getActionBar().setHomeButtonEnabled(true);
            getActionBar().addOnMenuVisibilityListener(new ActionBar.OnMenuVisibilityListener() {
                @Override
                public void onMenuVisibilityChanged(boolean visible) {
                    if (visible) {
                        mUiHider.setAutoHideDelay(UiHider.AUTO_HIDE_DELAY_DISABLED);
                        mUiHider.show();
                    } else {
                        mUiHider.setAutoHideDelay(AUTO_HIDE_DELAY_MILLIS);
                        mUiHider.delayedHide();
                    }
                }
            });
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == android.R.id.home) {
            onBackPressed();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("post_position", mViewPager.getCurrentItem());
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        mViewPager.setCurrentItem(savedInstanceState.getInt("post_position", 0), false);
    }

    @Override
    public void onBackPressed() {
        // super.onBackPressed();
        // This ID represents the Home or Up button. In the case of this
        // activity, the Up button is shown. Use NavUtils to allow users
        // to navigate up one level in the application structure. For
        // more details, see the Navigation pattern on Android Design:
        //
        // http://developer.android.com/design/patterns/navigation.html#up-vs-back
        //
        Intent intent = new Intent(this, PostListActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.setAction(Intent.ACTION_VIEW);
        intent.putExtra("post_position", mViewPager.getCurrentItem());
        navigateUpTo(intent);
    }

    @Override
    public void onImageClick() {
        mUiHider.toggle();
        if (mIsAutoplaying) {
            mViewPager.removeCallbacks(mNextPageRunnable);
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            mPlayPauseButton.setImageResource(android.R.drawable.ic_media_play);
        }
    }
}