org.jorge.cmp.ui.fragment.ArticleReaderFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.jorge.cmp.ui.fragment.ArticleReaderFragment.java

Source

/*
 * This file is part of LoLin1.
 *
 * LoLin1 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.
 *
 * LoLin1 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 LoLin1. If not, see <http://www.gnu.org/licenses/>.
 *
 * Created by Jorge Antonio Diaz-Benito Soriano.
 */

package org.jorge.cmp.ui.fragment;

import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.ScrollView;
import android.widget.TextView;

import com.melnykov.fab.FloatingActionButton;

import org.jorge.cmp.LoLin1Application;
import org.jorge.cmp.R;
import org.jorge.cmp.datamodel.FeedArticle;
import org.jorge.cmp.datamodel.LoLin1Account;
import org.jorge.cmp.datamodel.Realm;
import org.jorge.cmp.io.database.SQLiteDAO;
import org.jorge.cmp.io.prefs.PreferenceAssistant;
import org.jorge.cmp.ui.component.StickyParallaxNotifyingScrollView;
import org.jorge.cmp.util.PicassoUtils;

import java.util.Arrays;
import java.util.concurrent.Executors;

public class ArticleReaderFragment extends Fragment {

    public static final String KEY_ACCOUNT = "KEY_ACCOUNT";
    private static Class mClass;
    private Context mContext;
    private int mDefaultImageId;
    private String TAG;
    private FeedArticle mArticle;
    public static final String KEY_ARTICLE = "ARTICLE";
    private ActionBarActivity mActivity;
    @SuppressWarnings("FieldCanBeLocal")
    private Drawable mActionBarBackgroundDrawable;
    private LoLin1Account mAccount;
    private final Drawable.Callback mDrawableCallback = new Drawable.Callback() {
        @Override
        public void invalidateDrawable(Drawable who) {
            final ActionBar actionBar = mActivity.getSupportActionBar();
            if (actionBar != null)
                actionBar.setBackgroundDrawable(who);
        }

        @Override
        public void scheduleDrawable(Drawable who, Runnable what, long when) {
        }

        @Override
        public void unscheduleDrawable(Drawable who, Runnable what) {
        }
    };
    private ActionBar mActionBar;
    private float mOriginalElevation;
    private FloatingActionButton mMarkAsReadFab;

    public static Fragment newInstance(Context context, FeedArticle article, Class c, LoLin1Account acc) {
        Bundle args = new Bundle();
        args.putParcelable(ArticleReaderFragment.KEY_ARTICLE, article);
        int errorResId = R.drawable.feed_article_image_placeholder;
        args.putInt(FeedListFragment.ERROR_RES_ID_KEY, errorResId);
        args.putParcelable(ArticleReaderFragment.KEY_ACCOUNT, acc);
        mClass = c;

        return ArticleReaderFragment.instantiate(context, ArticleReaderFragment.class.getName(), args);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mContext = LoLin1Application.getInstance().getContext();
        mActivity = (ActionBarActivity) activity;
        final Bundle args = getArguments();
        if (args == null)
            throw new IllegalStateException("ArticleReader created without arguments");
        mArticle = args.getParcelable(KEY_ARTICLE);
        TAG = mArticle.getUrl();
        mDefaultImageId = args.getInt(FeedListFragment.ERROR_RES_ID_KEY);
        mAccount = args.getParcelable(KEY_ACCOUNT);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.actionbar_article_reader, menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.home:
        case R.id.homeAsUp:
            mActivity.onBackPressed();
        case R.id.action_browse_to:
            mArticle.requestBrowseToAction(mContext);
            return Boolean.TRUE;
        case R.id.action_share:
            mArticle.requestShareAction(mContext);
            return Boolean.TRUE;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        setHasOptionsMenu(Boolean.TRUE);
        final View ret = inflater.inflate(R.layout.fragment_article_reader, container, Boolean.FALSE);
        View mHeaderView = ret.findViewById(R.id.image);
        PicassoUtils.loadInto(mContext, mArticle.getImageUrl(), mDefaultImageId,
                (android.widget.ImageView) mHeaderView, TAG);
        final String title = mArticle.getTitle();
        mHeaderView.setContentDescription(title);
        ((TextView) ret.findViewById(R.id.title)).setText(title);
        WebView contentView = (WebView) ret.findViewById(android.R.id.text1);
        WebSettings webViewSettings = contentView.getSettings();
        contentView.setOverScrollMode(View.OVER_SCROLL_NEVER);
        webViewSettings.setJavaScriptCanOpenWindowsAutomatically(Boolean.TRUE);
        webViewSettings.setBuiltInZoomControls(Boolean.FALSE);
        contentView.setBackgroundColor(0x00000000); //I wonder why the default background is white
        contentView.loadData(mArticle.getPreviewText(), "text/html; charset=UTF-8", "UTF-8");

        mActionBar = mActivity.getSupportActionBar();
        mActionBar.setDisplayHomeAsUpEnabled(Boolean.TRUE);
        mActionBarBackgroundDrawable = new ColorDrawable(
                mContext.getResources().getColor(R.color.toolbar_background));
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
            mActionBarBackgroundDrawable.setCallback(mDrawableCallback);
        }
        mActionBar.setBackgroundDrawable(mActionBarBackgroundDrawable);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mOriginalElevation = mActionBar.getElevation();
            mActionBar.setElevation(0); //So that the shadow of the ActionBar doesn't show over
            // the article title
        }
        mActionBar.setTitle(mActivity.getString(R.string.section_title_article_reader));

        StickyParallaxNotifyingScrollView scrollView = (StickyParallaxNotifyingScrollView) ret
                .findViewById(R.id.scroll_view);
        scrollView.setOnScrollChangedListener(mOnScrollChangedListener);
        scrollView.smoothScrollTo(0, 0);

        if (!mArticle.isRead()) {
            mMarkAsReadFab = (FloatingActionButton) ret.findViewById(R.id.fab_button_mark_as_read);
            mMarkAsReadFab.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    markArticleAsRead(mArticle);
                    if (mMarkAsReadFab.isShown())
                        mMarkAsReadFab.hide();
                }

                private void markArticleAsRead(FeedArticle article) {
                    final Realm r = Realm.getInstanceByRealmId(ArticleReaderFragment.this.mAccount.getRealmEnum());
                    String l = PreferenceAssistant.readSharedString(mContext, PreferenceAssistant.PREF_LANG, null);
                    if (l == null || !Arrays.asList(r.getLocales()).contains(l)) {
                        l = r.getLocales()[0];
                        PreferenceAssistant.writeSharedString(mContext, PreferenceAssistant.PREF_LANG, l);
                    }
                    final Class newsClass = NewsListFragment.class;
                    final Class communityClass = CommunityListFragment.class;
                    final Class schoolClass = SchoolListFragment.class;
                    String tableName;
                    if (mClass == newsClass) {
                        if (l == null || !Arrays.asList(r.getLocales()).contains(l)) {
                            l = r.getLocales()[0];
                            PreferenceAssistant.writeSharedString(mContext, PreferenceAssistant.PREF_LANG, l);
                        }
                        tableName = SQLiteDAO.getNewsTableName(r, l);
                    } else if (mClass == communityClass) {
                        tableName = SQLiteDAO.getCommunityTableName();
                    } else if (mClass == schoolClass) {
                        tableName = SQLiteDAO.getSchoolTableName();
                    } else {
                        throw new IllegalArgumentException(
                                "Feed list fragment class " + mClass.getCanonicalName() + " not recognized.");
                    }
                    new AsyncTask<Object, Void, Void>() {
                        @Override
                        protected Void doInBackground(Object... params) {
                            SQLiteDAO.getInstance().markArticleAsRead((FeedArticle) params[0], (String) params[1]);
                            return null;
                        }
                    }.executeOnExecutor(Executors.newSingleThreadExecutor(), article, tableName);
                    article.markAsRead();
                }
            });

            mMarkAsReadFab.hide();
            mMarkAsReadFab.setVisibility(View.VISIBLE);

            showMarkAsReadFabIfItProceeds();
        }
        return ret;
    }

    private void showMarkAsReadFabIfItProceeds() {
        if (!mArticle.isRead())
            mMarkAsReadFab.show();
    }

    private StickyParallaxNotifyingScrollView.OnScrollChangedListener mOnScrollChangedListener = new StickyParallaxNotifyingScrollView.OnScrollChangedListener() {
        public void onScrollChanged(ScrollView who, int l, int t, int oldL, int oldT) {
            if (mMarkAsReadFab != null)
                if (!who.canScrollVertically(1) || !who.canScrollVertically(-1)) {
                    showMarkAsReadFabIfItProceeds();
                } else if (t < oldT) {
                    showMarkAsReadFabIfItProceeds();
                } else if (t > oldT) {
                    if (mMarkAsReadFab.isShown())
                        mMarkAsReadFab.hide();
                }
        }
    };

    @Override
    public void onDestroy() {
        super.onDestroy();
        PicassoUtils.cancel(mContext, TAG);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mActionBar.setElevation(mOriginalElevation);
        }
    }
}