com.nononsenseapps.feeder.ui.ReaderFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.nononsenseapps.feeder.ui.ReaderFragment.java

Source

/*
 * Copyright (c) 2015 Jonas Kalderstam.
 *
 * 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.nononsenseapps.feeder.ui;

import android.content.Intent;
import android.graphics.Point;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.ShareActionProvider;
import android.text.Spanned;
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.widget.TextView;

import com.nononsenseapps.feeder.R;
import com.nononsenseapps.feeder.db.FeedItemSQL;
import com.nononsenseapps.feeder.db.RssContentProvider;
import com.nononsenseapps.feeder.model.ImageTextLoader;
import com.nononsenseapps.feeder.util.TabletUtils;
import com.nononsenseapps.feeder.views.ObservableScrollView;
import com.nononsenseapps.text.HtmlConverter;

import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.util.Locale;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link ReaderFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class ReaderFragment extends Fragment implements LoaderManager.LoaderCallbacks<Spanned> {
    public static final String ARG_TITLE = "title";
    public static final String ARG_DESCRIPTION = "body";
    public static final String ARG_LINK = "link";
    public static final String ARG_ENCLOSURE = "enclosure";
    public static final String ARG_IMAGEURL = "imageurl";
    public static final String ARG_ID = "dbid";
    public static final String ARG_FEEDTITLE = "feedtitle";
    public static final String ARG_AUTHOR = "author";
    public static final String ARG_DATE = "date";
    // TODO Change
    static final DateTimeFormatter dateTimeFormat = DateTimeFormat.mediumDate().withLocale(Locale.getDefault());
    private static final int TEXT_LOADER = 1;
    // TODO database id
    private long _id = -1;
    // All content contained in RssItem
    private FeedItemSQL mRssItem;
    private TextView mTitleTextView;
    private TextView mBodyTextView;
    private ObservableScrollView mScrollView;
    private TextView mAuthorTextView;
    private TextView mFeedTitleTextView;

    private final HtmlConverter htmlformatter;

    public ReaderFragment() {
        htmlformatter = new HtmlConverter();
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param rssItem the Item to open in the reader
     * @return A new instance of fragment ReaderFragment.
     */
    public static ReaderFragment newInstance(FeedItemSQL rssItem) {
        ReaderFragment fragment = new ReaderFragment();
        // Save some time on load
        fragment.mRssItem = rssItem;
        fragment._id = rssItem.id;

        fragment.setArguments(RssItemToBundle(rssItem, null));
        return fragment;
    }

    /**
     * Convert an RssItem into a Bundle for use with Fragment Arguments
     *
     * @param rssItem to convert
     * @param bundle  may be null
     * @return bundle of rssItem plus id
     */
    public static Bundle RssItemToBundle(FeedItemSQL rssItem, Bundle bundle) {
        if (bundle == null) {
            bundle = new Bundle();
        }
        bundle.putLong(ARG_ID, rssItem.id);
        bundle.putString(ARG_TITLE, rssItem.title);
        bundle.putString(ARG_DESCRIPTION, rssItem.description);
        bundle.putString(ARG_LINK, rssItem.link);
        bundle.putString(ARG_ENCLOSURE, rssItem.enclosurelink);
        bundle.putString(ARG_IMAGEURL, rssItem.imageurl);
        bundle.putString(ARG_FEEDTITLE, rssItem.feedtitle);
        bundle.putString(ARG_AUTHOR, rssItem.author);
        bundle.putString(ARG_DATE, rssItem.getPubDateString());
        return bundle;
    }

    public static FeedItemSQL RssItemFromBundle(Bundle bundle) {
        FeedItemSQL rssItem = new FeedItemSQL();
        rssItem.id = bundle.getLong(ARG_ID, -1);
        rssItem.title = bundle.getString(ARG_TITLE);
        rssItem.description = (bundle.getString(ARG_DESCRIPTION));
        rssItem.link = (bundle.getString(ARG_LINK));
        rssItem.enclosurelink = (bundle.getString(ARG_ENCLOSURE));
        rssItem.imageurl = (bundle.getString(ARG_IMAGEURL));
        rssItem.author = (bundle.getString(ARG_AUTHOR));
        rssItem.setPubDate(bundle.getString(ARG_DATE));
        rssItem.feedtitle = (bundle.getString(ARG_FEEDTITLE));
        return rssItem;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null) {
            _id = savedInstanceState.getLong(ARG_ID);
            mRssItem = RssItemFromBundle(savedInstanceState);

        } else if (mRssItem == null) {
            // Construct from arguments
            _id = getArguments().getLong(ARG_ID, -1);
            mRssItem = RssItemFromBundle(getArguments());
        }

        if (_id > 0) {
            RssContentProvider.MarkItemAsRead(getActivity(), _id);
        }

        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        final int theLayout;
        if (TabletUtils.isTablet(getActivity())) {
            theLayout = R.layout.fragment_reader_tablet;
        } else {
            theLayout = R.layout.fragment_reader;
        }
        View rootView = inflater.inflate(theLayout, container, false);

        mScrollView = (ObservableScrollView) rootView.findViewById(R.id.scroll_view);
        mTitleTextView = (TextView) rootView.findViewById(R.id.story_title);
        mBodyTextView = (TextView) rootView.findViewById(R.id.story_body);
        mAuthorTextView = (TextView) rootView.findViewById(R.id.story_author);
        mFeedTitleTextView = (TextView) rootView.findViewById(R.id.story_feedtitle);

        if (mRssItem.title == null) {
            mTitleTextView.setText("Nothing to display!");
        } else {
            mTitleTextView.setText(htmlformatter.toSpanned(mRssItem.title, getActivity()));
        }
        if (mRssItem.description == null) {
            mBodyTextView.setText("Nothing to display!");
        } else {
            //Log.d("JONAS", "Text is:\n" + mRssItem.description);
            // Set without images as a place holder
            mBodyTextView.setText(htmlformatter.toSpanned(mRssItem.description, getActivity()));
        }

        if (mRssItem.feedtitle == null) {
            mFeedTitleTextView.setText("NOthing to display!");
        } else {
            mFeedTitleTextView.setText(mRssItem.feedtitle);
        }

        if (mRssItem.author == null && mRssItem.getPubDate() != null) {
            mAuthorTextView.setText(getString(R.string.on_date,
                    mRssItem.getPubDate().withZone(DateTimeZone.getDefault()).toString(dateTimeFormat)));
        } else if (mRssItem.getPubDate() != null) {
            mAuthorTextView.setText(getString(R.string.by_author_on_date, mRssItem.author,
                    mRssItem.getPubDate().withZone(DateTimeZone.getDefault()).toString(dateTimeFormat)));
        } else {
            mAuthorTextView.setVisibility(View.GONE);
        }

        // Load images in text
        getLoaderManager().restartLoader(TEXT_LOADER, new Bundle(), this);

        return rootView;
    }

    @Override
    public void onActivityCreated(Bundle bundle) {
        super.onActivityCreated(bundle);
        // TODO set for scrollview
        ((BaseActivity) getActivity()).enableActionBarAutoHide(mScrollView);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        RssItemToBundle(mRssItem, outState);
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onDetach() {
        getLoaderManager().destroyLoader(TEXT_LOADER);
        super.onDetach();
    }

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

        // Locate MenuItem with ShareActionProvider
        MenuItem shareItem = menu.findItem(R.id.action_share);

        // Fetch and store ShareActionProvider
        ShareActionProvider shareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shareItem);

        // Set intent
        Intent shareIntent = new Intent(Intent.ACTION_SEND);
        shareIntent.setType("text/plain");
        shareIntent.putExtra(Intent.EXTRA_TEXT, mRssItem.link);
        shareActionProvider.setShareIntent(shareIntent);

        // Show/Hide enclosure
        menu.findItem(R.id.action_open_enclosure).setVisible(mRssItem.enclosurelink != null);
        // Add filename to tooltip
        if (mRssItem.enclosurelink != null) {
            String filename = mRssItem.getEnclosureFilename();
            if (filename != null) {
                menu.findItem(R.id.action_open_enclosure).setTitle(filename);
            }
        }

        // Don't forget super call here
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem menuItem) {
        switch (menuItem.getItemId()) {
        case R.id.action_open_in_browser:
            // Open in browser
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(mRssItem.link)));
            return true;
        case R.id.action_open_enclosure:
            // Open enclosure link
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(mRssItem.enclosurelink)));
            return true;
        default:
            return super.onOptionsItemSelected(menuItem);
        }
    }

    /**
     * Instantiate and return a new Loader for the given ID.
     *
     * @param id   The ID whose loader is to be created.
     * @param args Any arguments supplied by the caller.
     * @return Return a new Loader instance that is ready to start loading.
     */
    @Override
    public Loader<Spanned> onCreateLoader(final int id, final Bundle args) {
        Point size = new Point();
        getActivity().getWindowManager().getDefaultDisplay().getSize(size);
        // Using twice window height since we do scroll vertically
        if (TabletUtils.isTablet(getActivity())) {
            // Tablet has fixed width
            return new ImageTextLoader(getActivity(), mRssItem.description,
                    new Point(Math.round(getResources().getDimension(R.dimen.reader_tablet_width)), 2 * size.y));
        } else {
            // Base it on window size
            return new ImageTextLoader(getActivity(), mRssItem.description,
                    new Point(size.x - 2 * Math.round(getResources().getDimension(R.dimen.keyline_1)), 2 * size.y));
        }
    }

    @Override
    public void onLoadFinished(final Loader<Spanned> loader, final Spanned data) {
        mBodyTextView.setText(data);
    }

    @Override
    public void onLoaderReset(final Loader<Spanned> loader) {
        // nothing really
    }
}