cn.newgxu.android.bbs.ui.ForumsTopicsFragment.java Source code

Java tutorial

Introduction

Here is the source code for cn.newgxu.android.bbs.ui.ForumsTopicsFragment.java

Source

/*
 * Copyright (c) 2001-2013 newgxu.cn <the original author or authors>.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package cn.newgxu.android.bbs.ui;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import cn.newgxu.android.bbs.R;
import cn.newgxu.android.bbs.activity.ViewTopicActivity;
import cn.newgxu.android.bbs.app.BBSApplication;
import cn.newgxu.android.bbs.provider.EntityProvider.Topic;
import cn.newgxu.android.bbs.util.Consts;
import cn.newgxu.android.bbs.util.L;
import cn.newgxu.android.bbs.util.NewgxuUtils;

import com.actionbarsherlock.app.SherlockListFragment;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshListView;
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnLastItemVisibleListener;
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;

/**
 * 
 * @author longkai
 * @email im.longkai@gmail.com
 * @since 2013-5-29
 * @version 0.1
 */
public class ForumsTopicsFragment extends SherlockListFragment
        implements OnRefreshListener<ListView>, OnLastItemVisibleListener {

    private static final String TAG = ForumsTopicsFragment.class.getSimpleName();

    private static final String LAST_POS = "last_pos";

    private SimpleAdapter mAdapter;
    private LinkedList<Map<String, Object>> data;

    private BBSApplication app;
    private int mPostion;

    private ListView listView;
    private PullToRefreshListView refreshListView;

    private int forumId;
    private boolean isClassic;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        this.app = (BBSApplication) activity.getApplication();
        this.data = new LinkedList<Map<String, Object>>();
        this.forumId = getArguments().getInt(Consts.FID);
        this.isClassic = getArguments().getBoolean(Consts.IS_CLASSIC, false);
    }

    @Override
    public void onDestroyView() {
        data.clear();
        super.onDestroyView();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null) {
            this.mPostion = savedInstanceState.getInt(LAST_POS, 0);
        }
        Log.d(TAG, "on create pos: " + mPostion);
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        Toast.makeText(getActivity(), String.format("postion: %d, id: %d", position, id), Toast.LENGTH_SHORT)
                .show();
        Intent intent = new Intent(getActivity(), ViewTopicActivity.class);
        Log.d(TAG, this.data.get(position - 1).get(Topic.TITLE).toString());
        intent.putExtra(Consts.TID, Integer.parseInt(this.data.get(position - 1).get(Topic.ID).toString()));
        getActivity().startActivity(intent);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        refreshListView = (PullToRefreshListView) inflater.inflate(R.layout.pull_refresh_list, container, false);
        this.listView = refreshListView.getRefreshableView();
        refreshListView.setOnRefreshListener(this);
        refreshListView.setOnLastItemVisibleListener(this);

        //      refreshListView.setOnRefreshListener(this);
        return refreshListView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Bundle args = getArguments();
        new GetFromBBS().execute(Consts.DOMAIN + args.getString(Consts.URL));
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        //      if (getListView() != null) {
        //         mPostion = getListView().getFirstVisiblePosition();
        //         Log.d(TAG, "on saved pos: " + mPostion);
        //         outState.putInt(LAST_POS, mPostion);
        //      }
        super.onSaveInstanceState(outState);
    }

    private class GetFromBBS extends AsyncTask<String, String, String> {

        private boolean connected;

        @Override
        protected String doInBackground(String... params) {
            if (connected) {
                String result = NewgxuUtils.httpGet(params[0]);
                publishProgress(result);
                return "ok";
            } else {
                return "no";
            }
        }

        @Override
        protected void onPostExecute(String result) {
            if (!connected) {
                Toast.makeText(getActivity(), R.string.network_down, Toast.LENGTH_SHORT).show();
            }
        }

        @Override
        protected void onPreExecute() {
            if (app.connected()) {
                connected = true;
            }
        }

        @Override
        protected void onProgressUpdate(String... values) {
            if (!connected) {
                return;
            }
            try {
                JSONArray array = new JSONObject(values[0]).getJSONArray(Consts.TOPICS);
                for (int i = 0; i < array.length(); i++) {
                    JSONObject json = array.getJSONObject(i);
                    data.add(topic2Map(json));
                }
                mAdapter = new SimpleAdapter(getActivity(), data, R.layout.topic_row,
                        new String[] { Topic.TITLE, Topic.ADDED_TIME, Topic.CLICK_TIMES, Topic.REPLIED_TIMES,
                                Topic.LAST_REPLIED_TIME, Topic.LAST_REPLIED_USER_NICK, Topic.AUTHOR_NICK },
                        new int[] { R.id.topic_title, R.id.topic_added_time, R.id.topic_click_times,
                                R.id.totpic_replied_times, R.id.topic_last_reply_time,
                                R.id.topic_last_reply_usernick, R.id.topic_author_nick });
                setListAdapter(mAdapter);
                //            setSelection(mPostion);
            } catch (JSONException e) {
                Log.wtf(TAG, e);
            }
        }

    }

    private class RefreshOrLoadMore extends AsyncTask<Boolean, String, String> {

        private boolean connected;
        private String error;
        private boolean isRefresh;

        @Override
        protected String doInBackground(Boolean... params) {
            if (connected) {
                String url = null;
                isRefresh = params[0];
                if (isRefresh) {
                    url = Consts.DOMAIN + String.format("/api/topics?type=%d&fid=%d&count=20&top_tid=%d",
                            Topic.FORUM_REFRESH, forumId, data.getFirst().get(Topic.ID));
                } else {
                    url = Consts.DOMAIN + String.format("/api/topics?type=%d&fid=%d&count=20&last_tid=%d",
                            Topic.FORUM_FETCH_MORE, forumId, data.getLast().get(Topic.ID));
                }
                String result = NewgxuUtils.httpGet(url);
                Log.d(TAG, result);
                publishProgress(result);
                return result;
            }
            return null;
        }

        @Override
        protected void onPreExecute() {
            if (app.connected()) {
                connected = true;
            }
        }

        @Override
        protected void onPostExecute(String result) {
            if (!connected) {
                Toast.makeText(getActivity(), R.string.network_down, Toast.LENGTH_SHORT).show();
            } else if (error != null) {
                Toast.makeText(getActivity(), error, Toast.LENGTH_SHORT).show();
            }
        }

        @Override
        protected void onProgressUpdate(String... values) {
            JSONObject json;
            try {
                json = new JSONObject(values[0]);
                if (json.getInt(Consts.STATUS) == Consts.NO) {
                    this.error = getResources().getString(R.string.error, json.getString(Consts.MSG),
                            json.getString(Consts.REASON));
                } else {
                    JSONArray array = json.getJSONArray("topics");
                    int length = array.length();
                    L.d(TAG, "length is: %d", length);
                    for (int i = 0; i < length; i++) {
                        JSONObject t = array.getJSONObject(i);
                        Map<String, Object> map = topic2Map(t);
                        if (isRefresh) {
                            data.addFirst(map);
                        } else {
                            data.addLast(map);
                        }
                        mAdapter.notifyDataSetChanged();
                    }
                    Toast.makeText(
                            getActivity(), getResources()
                                    .getString(isRefresh ? R.string.updates_count : R.string.fetchs_count, length),
                            Toast.LENGTH_SHORT).show();
                }
            } catch (JSONException e) {
                Log.wtf(TAG, e);
            } finally {
                refreshListView.onRefreshComplete();
            }
        }

    }

    @Override
    public void onRefresh(PullToRefreshBase<ListView> refreshView) {
        if (!isClassic) {
            Toast.makeText(getActivity(), "pull to refresh!", Toast.LENGTH_SHORT).show();
            new RefreshOrLoadMore().execute(true);
        } else {
            refreshListView.onRefreshComplete();
        }
    }

    @Override
    public void onLastItemVisible() {
        if (!isClassic) {
            Toast.makeText(getActivity(), R.string.fetching, Toast.LENGTH_SHORT).show();
            new RefreshOrLoadMore().execute(false);
        }
    }

    private Map<String, Object> topic2Map(JSONObject t) throws JSONException {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(Topic.ID, t.getInt(Topic.ID));
        map.put(Topic.ADDED_TIME, DateUtils.getRelativeTimeSpanString(t.getLong(Topic.ADDED_TIME)));
        map.put(Topic.CLICK_TIMES, t.getInt(Topic.CLICK_TIMES) + getResources().getString(R.string.click));
        map.put(Topic.LAST_REPLIED_TIME, DateUtils.getRelativeTimeSpanString(t.getLong(Topic.LAST_REPLIED_TIME)));
        map.put(Topic.REPLIED_TIMES, t.getInt(Topic.REPLIED_TIMES) + getResources().getString(R.string.reply));
        map.put(Topic.TITLE, t.getString(Topic.TITLE));
        map.put(Topic.AUTHOR_NICK, t.getString(Topic.AUTHOR_NICK));
        map.put(Topic.LAST_REPLIED_USER_NICK, t.getString(Topic.LAST_REPLIED_USER_NICK));
        return map;
    }

}