org.catnut.fragment.MyRelationshipFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.catnut.fragment.MyRelationshipFragment.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.Toast;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import org.catnut.R;
import org.catnut.adapter.UsersAdapter;
import org.catnut.api.FriendshipsAPI;
import org.catnut.core.CatnutAPI;
import org.catnut.core.CatnutProvider;
import org.catnut.core.CatnutRequest;
import org.catnut.metadata.User;
import org.catnut.processor.UserProcessor;
import org.catnut.ui.ProfileActivity;
import org.catnut.util.CatnutUtils;
import org.catnut.util.Constants;
import org.json.JSONArray;
import org.json.JSONObject;

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

    private static final String TAG = "MyRelationshipFragment";

    private static final String NEXT_CURSOR = "next_cursor";

    private static final String[] PROJECTION = new String[] { BaseColumns._ID, User.screen_name, User.remark,
            //         User.profile_image_url,
            User.avatar_large, User.verified, User.location, User.description, User.following, User.follow_me };

    private RequestQueue mRequestQueue;

    private UsersAdapter mAdapter;

    // ?
    private boolean mIsFollowing = false;

    private String mSelection;
    private int mTotal;
    private int mNextCursor;
    private long mUid;
    // load
    private int mLastTotalNumber;

    public static MyRelationshipFragment getFragment(boolean following) {
        Bundle args = new Bundle();
        args.putBoolean(TAG, following);
        MyRelationshipFragment fragment = new MyRelationshipFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mIsFollowing = getArguments().getBoolean(TAG);
        mRequestQueue = mApp.getRequestQueue();
        mSelection = (mIsFollowing ? User.following : User.follow_me) + "=1";
        mUid = mApp.getAccessToken().uid;
    }

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

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        // load it!
        mSwipeRefreshLayout.setRefreshing(true);
        if (savedInstanceState == null) {
            refresh();
        } else {
            initFromLocal();
        }
    }

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

    @Override
    public void onStart() {
        super.onStart();
        ActionBar bar = getActivity().getActionBar();
        bar.setIcon(R.drawable.ic_title_people);
        bar.setTitle(getString(mIsFollowing ? R.string.my_followings_title : R.string.follow_me_title));
    }

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

    @Override
    protected void refresh() {
        // ???
        if (!isNetworkAvailable()) {
            Toast.makeText(getActivity(), getString(R.string.network_unavailable), Toast.LENGTH_SHORT).show();
            initFromLocal();
            return;
        }
        // refresh!
        CatnutAPI api = mIsFollowing ? FriendshipsAPI.friends(mUid, getFetchSize(), 0, 1)
                : FriendshipsAPI.followers(mUid, getFetchSize(), 0, 1);
        mRequestQueue.add(new CatnutRequest(getActivity(), api, new UserProcessor.UsersProcessor(),
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        Log.d(TAG, "refresh done...");
                        mTotal = response.optInt(TOTAL_NUMBER);
                        mNextCursor = response.optInt(NEXT_CURSOR);
                        // ???
                        mLastTotalNumber = 0;
                        JSONArray jsonArray = response.optJSONArray(User.MULTIPLE);
                        int newSize = jsonArray.length(); // ...
                        Bundle args = new Bundle();
                        args.putInt(TAG, newSize);
                        getLoaderManager().restartLoader(0, args, MyRelationshipFragment.this);
                    }
                }, errorListener)).setTag(TAG);
    }

    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, User.TABLE, null, null,
                    null);
            Cursor cursor = getActivity().getContentResolver().query(CatnutProvider.parse(User.MULTIPLE), null,
                    query, null, null);
            if (cursor.moveToNext()) {
                mTotal = cursor.getInt(0);
            }
            cursor.close();
        }
    };

    @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(max_id);
        } else {
            // 
            loadFromLocal();
            // ?
            new Thread(updateLocalCount).start();
        }
    }

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

    // max_id 
    private void loadFromCloud(long max_id) {
        mSwipeRefreshLayout.setRefreshing(true);
        CatnutAPI api = mIsFollowing ? FriendshipsAPI.friends(mUid, getFetchSize(), mNextCursor, 1)
                : FriendshipsAPI.followers(mUid, getFetchSize(), mNextCursor, 1);
        mRequestQueue.add(new CatnutRequest(getActivity(), api, new UserProcessor.UsersProcessor(),
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        Log.d(TAG, "load more from cloud done...");
                        mTotal = response.optInt(TOTAL_NUMBER);
                        mNextCursor = response.optInt(NEXT_CURSOR);
                        mLastTotalNumber = mAdapter.getCount();
                        int newSize = response.optJSONArray(User.MULTIPLE).length() + mAdapter.getCount();
                        Bundle args = new Bundle();
                        args.putInt(TAG, newSize);
                        getLoaderManager().restartLoader(0, args, MyRelationshipFragment.this);
                    }
                }, errorListener)).setTag(TAG);
    }

    @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(User.remark).append(" like ")
                        .append(CatnutUtils.like(mCurFilter)).append(" or ").append(User.screen_name)
                        .append(" like ").append(CatnutUtils.like(mCurFilter)).append(")").toString();
            } else {
                search = false;
            }
        }
        int limit = args.getInt(TAG, getFetchSize());
        return CatnutUtils.getCursorLoader(getActivity(), CatnutProvider.parse(User.MULTIPLE), PROJECTION,
                selection, null, User.TABLE, null, 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 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;
    }

    @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 || mLastTotalNumber == mAdapter.getCount()) {
                Log.d(TAG, "load all done..." + mAdapter.getCount());
                super.loadAllDone();
            } else {
                Log.d(TAG, "load...");
                loadMore(mAdapter.getItemId(mAdapter.getCount() - 1));
            }
        } else {
            Log.d(TAG, "cannot load more!");
        }
    }
}