com.lillicoder.newsblurry.feeds.FeedsListFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.lillicoder.newsblurry.feeds.FeedsListFragment.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.feeds;

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.net.OnTaskCompletedListener;
import com.lillicoder.newsblurry.stories.StoriesActivity;
import com.lillicoder.newsblurry.views.LabeledProgressBar;

/**
 * Fragment that displays the user's feeds.
 * @author lillicoder
 */
public class FeedsListFragment extends Fragment {

    private OnTaskCompletedListener<List<IFeed>> _feedsTaskListener = new OnTaskCompletedListener<List<IFeed>>() {
        @Override
        public void onPreExecute() {
            FeedsListFragment.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 = FeedsListFragment.this.getString(errorMessageResource);
            FeedsListFragment.this.showErrorMessage(errorMessage);
        }

        @Override
        public void onSuccess(List<IFeed> result) {
            // New results available, update the list.
            FeedsListFragment.this.updateList(result);
        }
    };

    private LabeledProgressBar _labeledProgresssBar;
    private ListView _feedsList;

    private FeedsListAdapter _feedsAdapter;

    private IFeed _feed;

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

        this._feedsList = (ListView) root.findViewById(R.id.FeedsListFragment_feedsList);
        this._labeledProgresssBar = (LabeledProgressBar) root
                .findViewById(R.id.FeedsListFragment_labeledProgressBar);

        return root;
    }

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

        this._feedsList.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                IFeed feed = (IFeed) parent.getItemAtPosition(position);
                if (feed.hasChildren()) {
                    // Load next fragment list for the child feeds.
                    Intent childFeeds = new Intent(FeedsListFragment.this.getActivity(), FeedsActivity.class);
                    childFeeds.putExtra(FeedsActivity.INTENT_FEED_TO_DISPLAY, feed);

                    FeedsListFragment.this.startActivity(childFeeds);
                } else {
                    // Feed is an actual feed, display stories.
                    Intent stories = new Intent(FeedsListFragment.this.getActivity(), StoriesActivity.class);
                    stories.putExtra(StoriesActivity.INTENT_FEED_TO_DISPLAY, feed);

                    FeedsListFragment.this.startActivity(stories);
                }
            }
        });

        // Check for passed feed to display. If it is present, we will
        // display the master list of feeds for the user.
        IFeed feed = this.getFeed();
        if (feed != null)
            this.updateList(feed.getChildren());
        else
            this.fetchFeeds();
    }

    /**
     * Fetches the user's master list of feeds.
     */
    private void fetchFeeds() {
        DownloadFeedsTask task = new DownloadFeedsTask(this.getActivity(), this._feedsTaskListener);
        task.execute();
    }

    /**
     * Gets the {@link IFeed} that this fragment is displaying.
     * @return {@link IFeed} being displayed.
     */
    public IFeed getFeed() {
        return this._feed;
    }

    /**
     * Gets the {@link FeedsListAdapter} backing this fragment's feed list.
     * @return {@link FeedsListAdapter} backing the feeds list.
     */
    private FeedsListAdapter getListAdapter() {
        return this._feedsAdapter;
    }

    /**
     * Sets the {@link IFeed} that this fragment should display.
     * @param feed {@link IFeed} to display.
     */
    public void setFeed(IFeed feed) {
        this._feed = feed;
    }

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

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

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

        this._labeledProgresssBar.showErrorMessage(message);
    }

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

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

    /**
     * Updates this fragment's feed list to display the given collection
     * of {@link IFeed}.
     * @param feedsToDisplay {@link List} of {@link IFeed} to display.
     */
    private void updateList(List<IFeed> feedsToDisplay) {
        // Update the list. If we do not have a valid adapter,
        // provide a new one using the given feeds to display.
        FeedsListAdapter adapter = this.getListAdapter();
        if (adapter != null) {
            adapter.update(feedsToDisplay);
        } else {
            adapter = new FeedsListAdapter(feedsToDisplay);
            this._feedsList.setAdapter(adapter);
        }

        if (feedsToDisplay == null || feedsToDisplay.isEmpty()) {
            String noFeedsMessage = this.getString(R.string.FeedsListFragment_noFeedsLabel);
            this.showErrorMessage(noFeedsMessage);
        } else {
            this.showFeedsList();
        }
    }

}