com.commonsware.android.arXiv.ArticleListFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.commonsware.android.arXiv.ArticleListFragment.java

Source

/*
arXiv mobile - a Free arXiv app for android
http://code.google.com/p/arxiv-mobile/
    
Copyright (C) 2010 Jack Deslippe
Copyright (C) 2013 Marius Lewerenz
    
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    
 */

package com.commonsware.android.arXiv;

import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ArticleListFragment extends ListFragment
        implements arXivLoader.arXivLoaderCallbacks, AbsListView.OnScrollListener {
    private int firstResult = 1, resultsPerLoad = 30;
    private int currentFirstVisibleItem, currentVisibleItemCount, currentScrollState, totalCount;
    private long feedId;
    private int fontSize = 16;
    private String name, url, query, sortBy;
    private ArrayAdapter<ArticleList.Item> adapter;
    private ArticleList.Item[] content;
    private View footer;
    private Boolean error = false;
    private View errorStrip;
    private TextView errorMsg;
    private arXivLoader.arXivLoaderManager loaderManager;

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

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
        sortBy = prefs.getString("sortBy", "lastUpdatedDate");
        fontSize = prefs.getInt("fontSize", 16);

        footer = getActivity().getLayoutInflater().inflate(R.layout.activity_circle, null);
        errorStrip = getActivity().getLayoutInflater().inflate(R.layout.error_strip, null);
        View icon = errorStrip.findViewById(R.id.refresh);
        icon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getListView().addFooterView(footer);
                getListView().removeFooterView(errorStrip);
                loaderManager.restartLoader(0, ArticleListFragment.this);
            }
        });
        errorMsg = (TextView) errorStrip.findViewById(R.id.errorMsg);

        getListView().addFooterView(footer);
        getListView().setOnScrollListener(this);

        Intent intent = getActivity().getIntent();
        name = intent.getStringExtra("keyname");
        query = intent.getStringExtra("keyquery");
        url = intent.getStringExtra("keyurl");
        feedId = intent.getLongExtra("feedId", -1);

        loaderManager = new arXivLoader.arXivLoaderManager(getLoaderManager());

        Object o = getActivity().getLastCustomNonConfigurationInstance();
        if (o != null && o instanceof ArticleList.Item[]) {
            adapter = new ArticleAdapter((ArticleList.Item[]) o);
            setListAdapter(adapter);
            getListView().removeFooterView(footer);
            firstResult = adapter.getCount() + 1;
            totalCount = savedInstanceState.getInt("totalCount");
            error = savedInstanceState.getBoolean("error");
            if (error) {
                errorMsg.setText(savedInstanceState.getCharSequence("errorMsg"));
                getListView().addFooterView(errorStrip);
            }
        } else {
            adapter = new ArticleAdapter();
            loaderManager.initLoader(0, this);
        }
    }

    @Override
    public arXivLoader onCreateLoader(int i) {
        String urlAddress = "http://export.arxiv.org/api/query?" + query + "&sortBy=" + sortBy
                + "&sortOrder=descending&start=" + (firstResult - 1) + "&max_results=" + resultsPerLoad;
        return new APILoader(getActivity(), urlAddress, query, firstResult);
    }

    @Override
    public void onLoaderReset(arXivLoader itemLoader) {

    }

    @Override
    public void onLoadFinished(arXivLoader itemLoader, List<ArticleList.Item> list) {
        for (ArticleList.Item item : list)
            adapter.add(item);
        if (getListAdapter() != adapter)
            setListAdapter(adapter);
        firstResult = adapter.getCount() + 1;
        getListView().removeFooterView(footer);
        error = itemLoader.hasError();
        if (error) {
            errorMsg.setText(itemLoader.getErrorMsg());
            getListView().addFooterView(errorStrip);
        } else {
            totalCount = itemLoader.getTotalCount();
            if (feedId != -1) {
                final ContentValues cv = new ContentValues();
                cv.put(Feeds.UNREAD, 0);
                cv.put(Feeds.COUNT, totalCount);
                cv.put(Feeds.LAST_UPDATE, System.currentTimeMillis());
                final Uri feedUri = ContentUris.withAppendedId(Feeds.CONTENT_URI, feedId);
                new Thread() {
                    @Override
                    public void run() {
                        getActivity().getContentResolver().update(feedUri, cv, null, null);
                        getActivity().getContentResolver().notifyChange(feedUri, null);
                    }
                }.start();
            }
        }
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        if (position >= adapter.getCount())
            return;
        ArticleList.Item item = adapter.getItem(position);
        Intent myIntent = new Intent(getActivity(), SingleItemWindow.class);
        myIntent.putExtra("keytitle", item.title);
        myIntent.putExtra("keylink", item.link);
        myIntent.putExtra("keydescription", item.description);
        myIntent.putExtra("keycreator", item.authors);
        myIntent.putExtra("keyname", name);
        startActivity(myIntent);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("totalCount", totalCount);
        if (error) {
            outState.putBoolean("error", error);
            outState.putCharSequence("errorMsg", errorMsg.getText());
        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        this.currentFirstVisibleItem = firstVisibleItem;
        this.currentVisibleItemCount = visibleItemCount;
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        this.currentScrollState = scrollState;
        this.isScrollCompleted();
    }

    private void isScrollCompleted() {
        if (this.currentVisibleItemCount > 0 && this.currentScrollState == SCROLL_STATE_IDLE
                && currentFirstVisibleItem + currentVisibleItemCount == firstResult - 1
                && getListView().getFooterViewsCount() == 0) {
            if (firstResult < totalCount) {
                getListView().addFooterView(footer);
                loaderManager.restartLoader(0, this);
            }
        }
    }

    public ArticleList.Item[] getContent() {
        content = new ArticleList.Item[adapter.getCount()];
        for (int i = 0; i < adapter.getCount(); i++) {
            content[i] = adapter.getItem(i);
        }
        return content;
    }

    public int getFontSize() {
        return fontSize;
    }

    public void setFontSize(int size) {
        fontSize = size;
        getListView().invalidateViews();
    }

    private class ArticleAdapter extends ArrayAdapter<ArticleList.Item> {
        private ArticleAdapter() {
            super(getActivity(), android.R.layout.simple_list_item_1);
        }

        private ArticleAdapter(ArticleList.Item[] objects) {
            super(getActivity(), android.R.layout.simple_list_item_1,
                    new ArrayList<ArticleList.Item>(Arrays.asList(objects)));
            // We need to create a new List here, to be able to use add().
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            View row = convertView;
            ViewHolder holder;
            if (row == null) {
                LayoutInflater inflater = getActivity().getLayoutInflater();
                row = inflater.inflate(R.layout.searchrow, parent, false);
                holder = new ViewHolder();
                holder.text1 = (TextView) row.findViewById(R.id.text1);
                holder.text2 = (TextView) row.findViewById(R.id.text2);
                holder.linLay = (LinearLayout) row.findViewById(R.id.linlay);
                row.setTag(holder);
            } else
                holder = (ViewHolder) row.getTag();
            holder.text1.setText(getItem(position).title);
            holder.text1.setTextSize(fontSize);
            holder.text2.setText(getItem(position).text2);
            holder.text2.setTextSize(fontSize - 2);
            holder.linLay.setBackgroundResource((position % 2 == 0) ? R.color.back2 : R.color.back4);
            return row;
        }

        class ViewHolder {
            public TextView text1, text2;
            public LinearLayout linLay;
        }
    }
}