org.catnut.fragment.FavoriteFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.catnut.fragment.FavoriteFragment.java

Source

/*
 * The MIT License (MIT)
 * Copyright (c) 2014 longkai
 * The software shall be used for good, not evil.
 */
package org.catnut.fragment;

import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.CursorAdapter;
import android.widget.Toast;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import org.catnut.R;
import org.catnut.adapter.TweetAdapter;
import org.catnut.api.FavoritesAPI;
import org.catnut.core.CatnutProvider;
import org.catnut.core.CatnutRequest;
import org.catnut.metadata.Status;
import org.catnut.metadata.User;
import org.catnut.processor.StatusProcessor;
import org.catnut.ui.TweetActivity;
import org.catnut.util.CatnutUtils;
import org.catnut.util.Constants;
import org.json.JSONArray;
import org.json.JSONObject;

/**
 * ???
 *
 * @author longkai
 */
public class FavoriteFragment extends TimelineFragment {

    public static final String TAG = "FavoriteFragment"; // ??

    /**  */
    private static final String[] PROJECTION = new String[] { "s._id", Status.uid, Status.columnText,
            Status.thumbnail_pic, Status.bmiddle_pic, Status.original_pic, Status.comments_count,
            Status.reposts_count, Status.attitudes_count, Status.source, Status.retweeted_status, Status.favorited,
            Status.pic_urls, "s." + Status.created_at, User.screen_name, User.verified,
            //         User.profile_image_url,
            User.avatar_large, User.remark };

    private RequestQueue mRequestQueue;

    private int mCurrentPage = 1; // 1?api
    private int mTotal = 0;
    private int mDeleteCount = 0;
    private String mSelection;

    private CursorAdapter mAdapter;

    public static FavoriteFragment getFragment() {
        FavoriteFragment fragment = new FavoriteFragment();
        return fragment;
    }

    @Override
    protected void refresh() {
        // ???
        if (!isNetworkAvailable()) {
            Toast.makeText(getActivity(), getString(R.string.network_unavailable), Toast.LENGTH_SHORT).show();
            initFromLocal();
            return;
        }
        // ??
        mCurrentPage = 0;
        mDeleteCount = 0;
        mTotal = 0;

        // go go go
        mRequestQueue.add(new CatnutRequest(getActivity(), FavoritesAPI.favorites(getFetchSize(), mCurrentPage),
                new StatusProcessor.FavoriteTweetsProcessor(), new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        Log.d(TAG, "refresh done...");
                        mDeleteCount += response.optInt(TAG);
                        mTotal = response.optInt(TOTAL_NUMBER);
                        // ???
                        JSONArray jsonArray = response.optJSONArray(Status.FAVORITES);
                        int newSize = jsonArray.length(); // ...
                        Bundle args = new Bundle();
                        args.putInt(TAG, newSize);
                        getLoaderManager().restartLoader(0, args, FavoriteFragment.this);
                    }
                }, errorListener)).setTag(TAG);
    }

    @Override
    protected void loadMore(long max_id) {
        // 
        // ?(??||?)
        boolean fromCloud = mPreferences.getBoolean(getString(R.string.pref_keep_latest),
                getResources().getBoolean(R.bool.pref_load_more_from_cloud));
        if (fromCloud && isNetworkAvailable()) {
            // ??ok?
            loadFromCloud();
        } else {
            // 
            loadFromLocal();
            // ?
            new Thread(updateLocalCount).start();
        }
    }

    private void loadFromCloud() {
        mSwipeRefreshLayout.setRefreshing(true);
        mRequestQueue.add(new CatnutRequest(getActivity(), FavoritesAPI.favorites(getFetchSize(), mCurrentPage),
                new StatusProcessor.FavoriteTweetsProcessor(), new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        Log.d(TAG, "load more from cloud done...");
                        mDeleteCount += response.optInt(TAG);
                        mTotal = response.optInt(TOTAL_NUMBER);
                        int newSize = response.optJSONArray(Status.FAVORITES).length() + mAdapter.getCount();
                        Bundle args = new Bundle();
                        args.putInt(TAG, newSize);
                        getLoaderManager().restartLoader(0, args, FavoriteFragment.this);
                    }
                }, errorListener)).setTag(TAG);
    }

    private void loadFromLocal() {
        Bundle args = new Bundle();
        args.putInt(TAG, mAdapter.getCount() + getFetchSize());
        getLoaderManager().restartLoader(0, args, this);
        mSwipeRefreshLayout.setRefreshing(true);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mRequestQueue = mApp.getRequestQueue();
        mSelection = Status.favorited + "=1";
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAdapter = new TweetAdapter(getActivity());
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mSwipeRefreshLayout.setRefreshing(true);
        if (mPreferences.getBoolean(getString(R.string.pref_keep_latest), true)) {
            refresh();
        } else {
            initFromLocal();
        }
    }

    private void initFromLocal() {
        Bundle args = new Bundle();
        args.putInt(TAG, getFetchSize());
        getLoaderManager().initLoader(0, args, this);
        new Thread(updateLocalCount).start();
    }

    private Runnable updateLocalCount = new Runnable() {
        @Override
        public void run() {
            String query = CatnutUtils.buildQuery(new String[] { "count(0)" }, mSelection, Status.TABLE, null, null,
                    null);
            Cursor cursor = getActivity().getContentResolver().query(CatnutProvider.parse(Status.MULTIPLE), null,
                    query, null, null);
            if (cursor.moveToNext()) {
                mTotal = cursor.getInt(0);
            }
            cursor.close();
        }
    };

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mListView.setAdapter(mAdapter);
    }

    @Override
    public void onStart() {
        super.onStart();
        ActionBar actionBar = getActivity().getActionBar();
        actionBar.setTitle(getString(R.string.my_favorites));
        actionBar.setIcon(R.drawable.ic_title_favorite);
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        String selection = mSelection;
        boolean search = args.getBoolean(SEARCH_TWEET);
        if (search) {
            if (!TextUtils.isEmpty(mCurFilter)) {
                selection = new StringBuilder(mSelection).append(" and ").append(Status.columnText).append(" like ")
                        .append(CatnutUtils.like(mCurFilter)).toString();
            } else {
                search = false;
            }
        }
        int limit = args.getInt(TAG, getFetchSize());
        return CatnutUtils.getCursorLoader(getActivity(), CatnutProvider.parse(Status.MULTIPLE), PROJECTION,
                selection, null, Status.TABLE + " as s", "inner join " + User.TABLE + " as u on s.uid=u._id",
                "s." + BaseColumns._ID + " desc", search ? null : String.valueOf(limit));
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        if (mSwipeRefreshLayout.isRefreshing()) {
            mSwipeRefreshLayout.setRefreshing(false);
        }
        mAdapter.swapCursor(data);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        mAdapter.swapCursor(null);
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        super.onScrollStateChanged(view, scrollState);
        boolean canLoading = SCROLL_STATE_IDLE == scrollState // ???
                && mListView.getLastVisiblePosition() == mAdapter.getCount() - 1 // 
                && (mSearchView == null || !mSearchView.isSearching()) // ?
                && !mSwipeRefreshLayout.isRefreshing(); // ??
        //            && mAdapter.getCount() > 0; // ?
        if (canLoading) {
            // ???
            if (mAdapter.getCount() >= (mTotal - mDeleteCount)) {
                Log.d(TAG, "load all done...");
                super.loadAllDone();
            } else {
                Log.d(TAG, "load...");
                loadMore(0); // ?
            }
        } else {
            Log.d(TAG, "cannot load more!");
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Cursor cursor = (Cursor) mAdapter.getItem(position);
        String screenName = cursor.getString(cursor.getColumnIndex(User.screen_name));
        Intent intent = new Intent(getActivity(), TweetActivity.class);
        intent.putExtra(Constants.ID, id);
        intent.putExtra(User.screen_name, screenName);
        startActivity(intent);
    }

    @Override
    public boolean onQueryTextChange(String newText) {
        String newFilter = !TextUtils.isEmpty(newText) ? newText : null;
        // Don't do anything if the filter hasn't actually changed.
        // Prevents restarting the loader when restoring state.
        if (mCurFilter == null && newFilter == null) {
            return true;
        }
        if (mCurFilter != null && mCurFilter.equals(newFilter)) {
            return true;
        }
        Bundle args = new Bundle();
        args.putBoolean(SEARCH_TWEET, true);
        mCurFilter = newFilter;
        getLoaderManager().restartLoader(0, args, this);
        return true;
    }
}