com.lillicoder.newsblurry.stories.StoriesListFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.lillicoder.newsblurry.stories.StoriesListFragment.java

Source

/**
 * Copyright 2012 Scott Weeden-Moody
 *
 * 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 com.lillicoder.newsblurry.stories;

import java.util.List;

import org.json.JSONException;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

import com.lillicoder.newsblurry.R;
import com.lillicoder.newsblurry.exception.ApiRequestException;
import com.lillicoder.newsblurry.feeds.Feed;
import com.lillicoder.newsblurry.net.OnTaskCompletedListener;
import com.lillicoder.newsblurry.views.LabeledProgressBar;

/**
 * Fragment that displays a list of stories for a single feed.
 * @author lillicoder
 */
public class StoriesListFragment extends Fragment {

    private static final String EXCEPTION_NO_FEED_CANNOT_DISPLAY_STORIES = "There was no feed set for this fragment, cannot displays stories.";

    private OnTaskCompletedListener<List<Story>> _storiesTaskListener = new OnTaskCompletedListener<List<Story>>() {
        @Override
        public void onPreExecute() {
            StoriesListFragment.this.showLoading();
        }

        @Override
        public void onFailure(Exception exception) {
            int errorMessageResource;
            if (exception instanceof ApiRequestException)
                // Connection failure, show connection settings error.
                errorMessageResource = R.string.status_connectionFailure;
            else if (exception instanceof JSONException)
                // Failed to parse fetched results, prompt to try again later.
                errorMessageResource = R.string.status_unableToParseFeeds;
            else
                // Show generic error
                errorMessageResource = R.string.status_genericFailure;

            String errorMessage = StoriesListFragment.this.getString(errorMessageResource);
            StoriesListFragment.this.showErrorMessage(errorMessage);
        }

        @Override
        public void onSuccess(List<Story> result) {
            StoriesListFragment.this.updateList(result);
        }
    };

    private LabeledProgressBar _labeledProgresssBar;
    private ListView _storiesList;

    private StoriesListAdapter _storiesAdapter;

    private Feed _feed;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_stories_list, null);

        this._storiesList = (ListView) root.findViewById(R.id.StoriesListFragment_storiesList);
        this._labeledProgresssBar = (LabeledProgressBar) root
                .findViewById(R.id.StoriesListFragment_labeledProgressBar);

        return root;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        Feed feed = this.getFeed();
        if (feed != null)
            this.fetchStories(feed.getId());
        else
            throw new IllegalStateException(EXCEPTION_NO_FEED_CANNOT_DISPLAY_STORIES);

        this._storiesList.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // Display the selected story.
                Story story = (Story) parent.getItemAtPosition(position);

                Intent displayStory = new Intent(StoriesListFragment.this.getActivity(), StoryActivity.class);
                displayStory.putExtra(StoryActivity.INTENT_STORY_TO_DISPLAY, story);

                StoriesListFragment.this.startActivity(displayStory);
            }
        });
    }

    /**
     * Fetches the stories for the given feed ID.
     * @param feedId Feed ID of the feed whose stories will be fetched.
     */
    private void fetchStories(int feedId) {
        DownloadStoriesTask task = new DownloadStoriesTask(this.getActivity(), this._storiesTaskListener);
        task.execute(feedId);
    }

    /**
     * Gets the {@link Feed} whose stories are displayed by this fragment.
     * @return {@link Feed} whose stories are being displayed.
     */
    public Feed getFeed() {
        return this._feed;
    }

    /**
     * Gets the {@link StoriesListAdapter} backing this fragment's stories list.
     * @return {@link StoriesListAdapter} backing the stories list;
     */
    private StoriesListAdapter getListAdapter() {
        return this._storiesAdapter;
    }

    /**
     * Sets the {@link Feed} whose stories this fragment should display.
     * @param feed {@link Feed} to whose stories are to be displayed.
     */
    public void setFeed(Feed feed) {
        this._feed = feed;
    }

    /**
     * Convenience method that shows an error message label
     * with the given message.
     * @param message Error message to display.
     */
    private void showErrorMessage(String message) {
        this._storiesList.setVisibility(View.GONE);

        this._labeledProgresssBar.showErrorMessage(message);
    }

    /**
     * Convenience method that shows the progress bar 
     * with a load stories label.
     */
    private void showLoading() {
        this._storiesList.setVisibility(View.GONE);

        String loadingMessage = this.getString(R.string.StoriesListFragment_loadingStoriesLabel);
        this._labeledProgresssBar.showLoading(loadingMessage);
    }

    /**
     * Convenience method that shows the stories list.
     */
    private void showStoriesList() {
        this._labeledProgresssBar.setVisibility(View.GONE);

        this._storiesList.setVisibility(View.VISIBLE);
    }

    /**
     * Updates this fragment's story list to display the given collection
     * of {@link Story}.
     * @param storiesToDisplay {@link List} of {@link Story} to display.
     */
    private void updateList(List<Story> storiesToDisplay) {
        StoriesListAdapter adapter = this.getListAdapter();
        if (adapter != null) {
            adapter.update(storiesToDisplay);
        } else {
            adapter = new StoriesListAdapter(storiesToDisplay);
            this._storiesList.setAdapter(adapter);
        }

        if (storiesToDisplay == null || storiesToDisplay.isEmpty()) {
            String noStoriesMessage = this.getString(R.string.StoriesListFragment_noStoriesLabel);
            this.showErrorMessage(noStoriesMessage);
        } else {
            this.showStoriesList();
        }
    }

}