Android Open Source - GuildViewerApp2 News Detail Fragment






From Project

Back to project page GuildViewerApp2.

License

The source code is released under:

Apache License

If you think the Android project GuildViewerApp2 listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.skywomantechnology.app.guildviewer;
/*  w w w. j a  v a  2s . c  o  m*/
/*
 * Guild Viewer is an Android app that allows users to view news feeds and news feed details
 * on a mobile device and while not logged into the game servers.
 *
 * Copyright 2014 Sky Woman Technology LLC
 *
 *    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.
 */

import android.app.Fragment;
import android.app.LoaderManager;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.os.Bundle;
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.ImageView;
import android.widget.ShareActionProvider;
import android.widget.TextView;

import com.skywomantechnology.app.guildviewer.data.GuildViewerContract;
import com.skywomantechnology.app.guildviewer.data.GuildViewerContract.MemberEntry;
import com.skywomantechnology.app.guildviewer.data.GuildViewerContract.NewsEntry;

//import android.util.Log;

/**
 * A fragment representing a single News detail screen.
 * This fragment is either contained in a {@link NewsListActivity}
 * in two-pane mode (on tablets) or a {@link NewsDetailActivity}
 * on handsets.
 */
public class NewsDetailFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {

   // private final String LOG_TAG = NewsDetailFragment.class.getSimpleName();

    // Columns to get from content provider that are used in this fragment
    private static final String[] NEWS_LIST_COLUMNS = {
            NewsEntry.TABLE_NAME + "." + NewsEntry._ID,
            NewsEntry.COLUMN_TYPE,
            NewsEntry.COLUMN_REGION,
            NewsEntry.COLUMN_REALM,
            NewsEntry.COLUMN_GUILD,
            NewsEntry.COLUMN_TIMESTAMP,
            NewsEntry.COLUMN_CHARACTER,
            NewsEntry.COLUMN_ITEM_ID,
            NewsEntry.COLUMN_ITEM_NAME,
            NewsEntry.COLUMN_ITEM_DESCRIPTION,
            NewsEntry.COLUMN_ITEM_ICON,
            NewsEntry.COLUMN_ACHIEVEMENT_TITLE,
            NewsEntry.COLUMN_ACHIEVEMENT_DESCRIPTION,
            NewsEntry.COLUMN_ACHIEVEMENT_ICON
    };

    public static class ViewHolder {
        private TextView mNewsEvent;
        private TextView mExtraInformation;
        private ImageView mItemIcon;
        private TextView mItemDetail;
        private TextView mTimeStamp;
        private TextView mCharacter;

        public ViewHolder(View view) {
            if (view != null) {
                mNewsEvent = (TextView) view.findViewById(R.id.detailedNewsEvent);
                mExtraInformation = (TextView) view.findViewById(R.id.extraInformation);
                mItemIcon = (ImageView) view.findViewById(R.id.detail_item_icon);
                mItemDetail = (TextView) view.findViewById(R.id.detailedItem);
                mTimeStamp = (TextView) view.findViewById(R.id.detailedTimestamp);
                mCharacter = (TextView) view.findViewById(R.id.detailedCharacter);
            }
        }
    }

    // ID for the cursor loader (in case we end up with more than one)
    private static final int DETAIL_LOADER = 110;

    private String mArgItemId;  // used to know which news item we are looking at
    private long mNewsListItemId; // lets us build the URI using WOW's id not the database one

    // used for sharing the news detail information
    private ShareActionProvider mShareActionProvider;
    private String mNewsItem;   // used for share text

    /**
     * Constructor that sets up usage of the options menu
     */
    public NewsDetailFragment() {
        setHasOptionsMenu(true);
    }

    /**
     * Make sure to store the current news item key for correct lifecycle processing
     *
     * @param outState bundle to save information for future use
     */
    @Override
    public void onSaveInstanceState(Bundle outState) {
        outState.putString(NewsListFragment.NEWS_ID_KEY, mArgItemId);
        super.onSaveInstanceState(outState);
    }

    /**
     * Make sure that the correct data is loaded into the details fragment
     * by obtaining the news item key and loading the data from the cursor loader
     */
    @Override
    public void onResume() {
        super.onResume();
        Bundle arguments = getArguments();
        if (arguments != null && arguments.containsKey(NewsListFragment.NEWS_ID_KEY) &&
                mArgItemId != null ) {
            getLoaderManager().restartLoader(DETAIL_LOADER, null, this);
        }
    }

    /**
     * This options menu allows sharing of the news event
     *
     * @param menu to inflate for the options menu
     * @param inflater Inflater to use to inflate the options menu
     */
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        // process the share functionality from this menu
        inflater.inflate(R.menu.detailfragment, menu);
        MenuItem menuItem = menu.findItem(R.id.action_share);
        if (menuItem != null) {
            mShareActionProvider = (ShareActionProvider) menuItem.getActionProvider();
        }
        if (mNewsItem != null && mShareActionProvider != null) {
            doShare(createShareGuildNewsEventIntent());
        }
    }

    /**
     * Simple method to make the sharing code easier to use
     *
     * @param shareIntent  The intent to use for sharing
     */
    public void doShare(Intent shareIntent) {
        // When you want to share set the share intent.
        mShareActionProvider.setShareIntent(shareIntent);
    }


    /**
     * Creates an intent for sharing the guild news item
     * adds a simple text message with an app hashtag
     * @return Intent used to share the guild news item
     */
    private Intent createShareGuildNewsEventIntent() {
        Intent shareIntent = new Intent(Intent.ACTION_SEND);
        shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
        shareIntent.setType("text/plain");
        // remove any line feeds when sharing the data and add a hashtag
        shareIntent.putExtra(Intent.EXTRA_TEXT, mNewsItem.replaceAll("\n", " ")
                + Constants.GUILDVIEWER_SHARE_HASHTAG);
        return shareIntent;
    }

    /**
     *
     * @param savedInstanceState bundle of information previously saved
     */
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (savedInstanceState != null) {
            mArgItemId = savedInstanceState.getString(NewsListFragment.NEWS_ID_KEY);
        }
        Bundle arguments = getArguments();
        if (arguments != null && arguments.containsKey(NewsListFragment.NEWS_ID_KEY)) {
            getLoaderManager().initLoader(DETAIL_LOADER, null, this);
        }
    }

    /**
     *
     * @param inflater inflates layouts
     * @param container for ViewGroup
     * @param savedInstanceState bundle of information previously saved
     * @return View created
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        // find out if we have stored the news item key some where
        // we use the two id's differently even though they are the stored
        // with the same keys
        Bundle arguments = getArguments();
        if (arguments != null) {
            mNewsListItemId = arguments.getLong(NewsListFragment.NEWS_ID_KEY);
        }
        if (savedInstanceState != null) {
            mArgItemId = savedInstanceState.getString(NewsListFragment.NEWS_ID_KEY);
        }

        // set up the UI
        return inflater.inflate(R.layout.fragment_news_detail, container, false);
    }

    /**
     * Goes to the content provider to load up the detail needed for display
     *
     * @param id  Loader identifier
     * @param bundle of information passed
     * @return Cursor Loader with content
     */
    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
        // Now create and return a CursorLoader that will take care of
        // creating a Cursor for the data being displayed.
        return new CursorLoader(
                getActivity(),
                GuildViewerContract.NewsEntry.buildNewsListUriWithId(mNewsListItemId),
                NEWS_LIST_COLUMNS,
                null,
                null,
                null   // sort order
        );
    }

    /**
     * When the cursor information is loaded then process it
     * Create the display text and put them in the the appropriate views
     * also process the share item if needed
     *
     * @param cursorLoader loader for data
     * @param data loaded information
     */
    @Override
    public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor data) {
        if (data != null && data.moveToFirst()) {

            // generate the guild information
            String region = getRegionIdentifier(getActivity(),
                    data.getString(data.getColumnIndex(NewsEntry.COLUMN_REGION)));
            String realm = data.getString(data.getColumnIndex(NewsEntry.COLUMN_REALM));
            String guildName = data.getString(data.getColumnIndex(NewsEntry.COLUMN_GUILD));
            String guildInfo = String.format(getString(R.string.format_guild_info_details),
                    guildName, realm, region);

            // generate the guild news timestamp
            long tm = data.getLong(data.getColumnIndex(NewsEntry.COLUMN_TIMESTAMP));
            String timestamp =
                    Utility.getReadableDateString(tm, getString(R.string.format_timestamp_details));

            // generate the news item string to display
            String newsType = data.getString(data.getColumnIndex(NewsEntry.COLUMN_TYPE));
            boolean isItem = newsType.contains(Constants.ITEM);

            String verb = Utility.getNewsTypeVerb(getActivity(), newsType);

            String character = data.getString(data.getColumnIndex(NewsEntry.COLUMN_CHARACTER));

            // Give the user some Character details for this view
            String details = processCharacterInformation(character);

            ViewHolder viewHolder = new ViewHolder(getView());
            viewHolder.mItemIcon.setImageResource(Utility.getImageResourceForNewsDetails(newsType));

            String itemName = data.getString(data.getColumnIndex(NewsEntry.COLUMN_ITEM_NAME));
            String achievementTitle = data.getString(data.getColumnIndex(NewsEntry.COLUMN_ACHIEVEMENT_TITLE));

            // Save this news event for the share intent
            mNewsItem = String.format(getActivity().getString(R.string.format_share_info), character, guildInfo, verb,
                    (isItem ? itemName : achievementTitle), timestamp);

            String characterInformation = String.format(getActivity().getString(R.string.format_character_details),
                    character, details, guildInfo);
            viewHolder.mCharacter.setText(characterInformation);
            viewHolder.mNewsEvent.setText(verb);

            String itemDetails = String.format(getActivity().getString(R.string.format_item_details),
                    (String) (isItem ? itemName : achievementTitle));
            viewHolder.mItemDetail.setText(itemDetails);

            // set the icon for the details view
            String timeFormatted =
                    String.format(getActivity().getString(R.string.format_display_timestamp), timestamp);
            viewHolder.mTimeStamp.setText(timeFormatted);

            // if there is extra details then display them
            viewHolder.mExtraInformation.setText("");
            if (newsType.toLowerCase().contains(Constants.ACHIEVEMENT) ) {
                String extraInfo = String.format(getActivity().getString(R.string.format_extra_achievement),
                        character,
                        data.getString(data.getColumnIndex(NewsEntry.COLUMN_ACHIEVEMENT_DESCRIPTION)));
                viewHolder.mExtraInformation.setText(extraInfo);
            }
            else if (newsType.contains(Constants.ITEM)) {
                String itemDescription = data.getString(data.getColumnIndex(NewsEntry.COLUMN_ITEM_DESCRIPTION));
                String extraInfo = "";
                if (!itemDescription.isEmpty()) {
                    extraInfo = String.format(getString(R.string.format_extra_item), itemDescription);
                }
                viewHolder.mExtraInformation.setText(extraInfo);
            }

            // If onCreateOptionsMenu has already happened, we need to update the share intent now.
            if (mShareActionProvider != null) {
                doShare(createShareGuildNewsEventIntent());
            }
        }

    }

    /**
     * Find some character details and create a detail string message
     *
     * @param character to find the details about
     * @return String with some character information that can be displayed
     */
    private String processCharacterInformation(String character) {
        Cursor memberCursor = getActivity().getContentResolver().query(
                MemberEntry.buildGuildMemberUriWithName(character),
                null, // leaving "columns" null just returns all the columns.
                null, // cols for "where" clause
                null, // values for "where" clause
                null  // sort order
        );
        String charInfo;
        if (memberCursor != null && memberCursor.getCount() > 0) {
            memberCursor.moveToFirst();
            String race = memberCursor.getString(memberCursor.getColumnIndex(MemberEntry.COLUMN_RACE));
            String charClass = memberCursor.getString(memberCursor.getColumnIndex(MemberEntry.COLUMN_CLASS));
            int level = memberCursor.getInt(memberCursor.getColumnIndex(MemberEntry.COLUMN_LEVEL));
            charInfo = String.format(getActivity().getString(R.string.format_level_class),
                    Integer.toString(level), race, charClass );
            memberCursor.close();
        } else {
            // if the guild member information is not loaded or doesn't exist just don't
            // display anything... better than displaying "null" which it was doing
            charInfo = "";
        }
        return charInfo;
    }

    /**
     * get a more readable region identifier for the UI
     * @param context current activity
     * @param region indicates which WOW server to use
     * @return String with the server path
     */
    public static String getRegionIdentifier(Context context, String region) {
        String[] regionValues = context.getResources().getStringArray(R.array.list_region_values);
        String[] regionIdentifiers = context.getResources().getStringArray(R.array.list_region_options);
        int current = 0;
        String returnValue = region;
        for (String rv : regionValues) {
            if (rv.contentEquals(region)) {
                returnValue = regionIdentifiers[current];
            }
            current++;
        }
        // if a match wasn't found then just use the raw region value
        return returnValue;
    }

    /**
     * Required method
     *
     * @param cursorLoader loader for data
     */
    @Override
    public void onLoaderReset(Loader<Cursor> cursorLoader) {
    }

}




Java Source Code List

com.skywomantechnology.app.guildviewer.Constants.java
com.skywomantechnology.app.guildviewer.NewsAdapter.java
com.skywomantechnology.app.guildviewer.NewsDetailActivity.java
com.skywomantechnology.app.guildviewer.NewsDetailFragment.java
com.skywomantechnology.app.guildviewer.NewsListActivity.java
com.skywomantechnology.app.guildviewer.NewsListFragment.java
com.skywomantechnology.app.guildviewer.SetPreferenceActivity.java
com.skywomantechnology.app.guildviewer.SettingsFragment.java
com.skywomantechnology.app.guildviewer.Utility.java
com.skywomantechnology.app.guildviewer.data.GuildViewerAchievement.java
com.skywomantechnology.app.guildviewer.data.GuildViewerContract.java
com.skywomantechnology.app.guildviewer.data.GuildViewerDbHelper.java
com.skywomantechnology.app.guildviewer.data.GuildViewerGuild.java
com.skywomantechnology.app.guildviewer.data.GuildViewerItem.java
com.skywomantechnology.app.guildviewer.data.GuildViewerMember.java
com.skywomantechnology.app.guildviewer.data.GuildViewerNewsItem.java
com.skywomantechnology.app.guildviewer.data.NewsProvider.java
com.skywomantechnology.app.guildviewer.sync.GuildViewerAuthenticatorService.java
com.skywomantechnology.app.guildviewer.sync.GuildViewerAuthenticator.java
com.skywomantechnology.app.guildviewer.sync.GuildViewerSyncAdapter.java
com.skywomantechnology.app.guildviewer.sync.GuildViewerSyncService.java