package com.ustc.dystu.dandelion.fragment;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.SearchView;
import android.widget.SearchView.OnCloseListener;
import android.widget.SearchView.OnQueryTextListener;
import android.widget.TextView;
import android.widget.Toast;
import com.ustc.dystu.dandelion.FriendsInfoActivity;
import com.ustc.dystu.dandelion.R;
import com.ustc.dystu.dandelion.bean.FansInfo;
import com.ustc.dystu.dandelion.bean.UserInfo;
import com.ustc.dystu.dandelion.constant.Constants;
import com.ustc.dystu.dandelion.net.DandRequestListener;
import com.ustc.dystu.dandelion.net.DandelionAPI;
import com.ustc.dystu.dandelion.utils.CacheUtils;
import com.ustc.dystu.dandelion.utils.DandAsyncTask;
import com.ustc.dystu.dandelion.utils.Logger;
import com.ustc.dystu.dandelion.utils.image.ImageCache;
import com.ustc.dystu.dandelion.utils.image.ImageFetcher;
public class FriendsFragment extends BaseFragment implements OnScrollListener {
private static final String TAG = FriendsFragment.class.getSimpleName();
private static final int REQUEST_GET_FANS_LIST = 0x1;
private ArrayList<FansInfo> mListData = new ArrayList<FansInfo>();
private ArrayList<FansInfo> mSavedList = new ArrayList<FansInfo>();// 联系人列表数据缓存
private ListView listView;
private FansListAdapter mAdapter;
private int currentPage = -1;
private long mTotalCount = 0;
private int mLastSavedTotalCount = -1;
private View mFooterView;
private static final int PAGE_SIZE = 200;
private static final String SEARCH_SIZE = "100";
private ViewHolder holder;
private TextView footText;
private ProgressBar footBar;
private ImageView ivBack;
private boolean isSearching = false;
private SearchFansTask mSearchFansTask;
private SearchView mSvSearch;
private ViewStub mVSSearch;
private String mSearchKey;
private ImageView ivRefresh;
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
hideFooterView();
switch (msg.what) {
case REQUEST_GET_FANS_LIST:
if (msg.obj != null) {
ArrayList<FansInfo> list = (ArrayList<FansInfo>) msg.obj;
if (!isSearching) {
mListData.addAll(list);
mAdapter.notifyDataSetChanged();
mSavedList.clear();
mSavedList.addAll(mListData);
} else {
mSavedList.addAll(list);
}
} else {
Toast.makeText(getActivity(), "好友列表为空!", Toast.LENGTH_SHORT)
.show();
}
break;
case ERROR_RESPONSE:
if (msg.obj != null) {
Toast.makeText(getActivity(), (String) msg.obj,
Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
};
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_friends, null);
mVSSearch = (ViewStub) view.findViewById(R.id.vs_search);
ivRefresh = (ImageView) view.findViewById(R.id.iv_refresh);
ivBack = (ImageView) view.findViewById(R.id.iv_back);
ivBack.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
getActivity().finish();
}
});
ivRefresh.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
refresh();
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
mVSSearch.setLayoutResource(R.layout.search_view);
mVSSearch.inflate();
mSvSearch = (SearchView) view.findViewById(R.id.sv_search);
mSvSearch.setIconifiedByDefault(false);
mSvSearch.setQueryHint(getString(R.string.search_friends));
mSvSearch.setOnCloseListener(new OnCloseListener() {
@Override
public boolean onClose() {
searchCancel();
return true;
}
});
mSvSearch.setOnQueryTextListener(new OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
// 这里访问搜索接口
if (TextUtils.isEmpty(newText)) {
searchCancel();
} else {
mSearchKey = newText;
isSearching = true;
mListData.clear();
showFooterView();
if (mSearchFansTask != null
&& mSearchFansTask.getStatus() == DandAsyncTask.Status.RUNNING) {
mSearchFansTask.cancel(true);
}
mSearchFansTask = new SearchFansTask(newText,
SEARCH_SIZE);
mSearchFansTask.execute();
}
return false;
}
});
}
mAdapter = new FansListAdapter(FriendsFragment.this.getActivity(),
mListData);
listView = (ListView) view.findViewById(R.id.list);
listView.setAdapter(mAdapter);
listView.setItemsCanFocus(false);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
mFooterView = inflater.inflate(R.layout.friends_list_foot, null);
mFooterView.setEnabled(false);
footText = (TextView) mFooterView.findViewById(R.id.tv_foot_view);
footBar = (ProgressBar) mFooterView.findViewById(R.id.pb_foot_refresh);
hideFooterView();
listView.setOnScrollListener(this);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
hideInputMethod();
FansInfo fansInfo = mListData.get(position);
Intent intent = new Intent();
intent.putExtra("fans_info", fansInfo);
intent.setClass(getActivity(), FriendsInfoActivity.class);
startActivity(intent);
}
});
return view;
};
@Override
protected void afterActivityCreated() {
initFansList();
}
private void initFansList() {
currentPage = 1;
DandelionAPI.getInstance(getActivity()).getFansList(
new DandRequestListener(mHandler) {
@Override
public void onComplete(String response) {
Message msg = Message.obtain();
try {
if (TextUtils.isEmpty(response)
|| response.contains("error_code")) {
msg.what = ERROR_RESPONSE;
JSONObject obj = new JSONObject(response);
msg.obj = obj.getString("error");
Logger.d(TAG, "error-->" + msg.obj);
} else {
if (!response.equals("[]")) {
JSONObject obj = new JSONObject(response);
String total = obj.getString("total_number");
if (Integer.parseInt(total) > 0) {
JSONArray jsonArray = obj
.getJSONArray("users");
ArrayList<FansInfo> list = FansInfo
.create(jsonArray);
msg.obj = list;
}
}
msg.what = REQUEST_GET_FANS_LIST;
}
mHandler.sendMessage(msg);
} catch (JSONException e) {
e.printStackTrace();
msg.what = ERROR_RESPONSE;
msg.obj = "数据解析异常";
mHandler.sendMessage(msg);
}
}
}, currentPage, PAGE_SIZE);
showFooterView();
}
private GetUserInfoTask task;
private int mStartIndex;
private int mEndIndex;
private class FansListAdapter extends BaseAdapter {
private ArrayList<FansInfo> list;
private LayoutInflater inflater;
private ImageFetcher mImageWorker;
public FansListAdapter(Context context, ArrayList<FansInfo> list) {
this.list = list;
inflater = LayoutInflater.from(context);
mImageWorker = new ImageFetcher(context, 80);
mImageWorker.setImageCache(new ImageCache(context,
Constants.THUMNAIL_CACHE_PROFILE_PATH));
mImageWorker.setLoadingImage(R.drawable.icon_vdisk);
mImageWorker.setImageFadeIn(false);
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.fans_list_item, null);
holder = new ViewHolder();
holder.fansIcon = (ImageView) convertView
.findViewById(R.id.iv_fans_icon);
holder.fansName = (TextView) convertView
.findViewById(R.id.iv_fans_name);
convertView.setTag(holder);
}
holder = (ViewHolder) convertView.getTag();
FansInfo info = list.get(position);
holder.fansName.setText(info.screen_name);
if (info.profile_image_url != null
&& !info.profile_image_url.trim().equals("")) {
mImageWorker.loadImage(info.profile_image_url, holder.fansIcon,
R.drawable.icon_vdisk, true);
} else {
holder.fansIcon.setImageResource(R.drawable.icon_vdisk);
}
return convertView;
}
}
private static final class ViewHolder {
public ImageView fansIcon;
public TextView fansName;
}
private void refresh() {
if (!isSearching) {
mListData.clear();
initFansList();
} else {
if (!TextUtils.isEmpty(mSearchKey)) {
mListData.clear();
showFooterView();
if (mSearchFansTask != null
&& mSearchFansTask.getStatus() == DandAsyncTask.Status.RUNNING) {
mSearchFansTask.cancel(true);
}
mSearchFansTask = new SearchFansTask(
mSearchKey, SEARCH_SIZE);
mSearchFansTask.execute();
} else {
searchCancel();
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (visibleItemCount > 0
&& (firstVisibleItem + visibleItemCount == totalItemCount)) {
if (totalItemCount != mLastSavedTotalCount && !isSearching) {
mLastSavedTotalCount = totalItemCount;
Logger.i(TAG, "currentPage---->" + currentPage + "/"
+ mTotalCount);
// long i = 0;
// if ((mTotalCount % PAGE_SIZE) == 0) {
// i = mTotalCount / PAGE_SIZE;
// } else {
// i = mTotalCount / PAGE_SIZE + 1;
// }
// if (currentPage < i) {
// // 加载下一页
// currentPage++;
// try {
// initFansList();
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
}
}
if (isSearching) {
// Logger.i(TAG, "onScroll---->isSearching");
mStartIndex = firstVisibleItem;
mEndIndex = firstVisibleItem + visibleItemCount;
if (mEndIndex >= totalItemCount) {
mEndIndex = totalItemCount;
}
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE && isSearching) {
// Logger.i(TAG, "onScrollSateChanged---->isSearching");
if (task != null
&& task.getStatus() == DandAsyncTask.Status.RUNNING) {
task.cancel(true);
}
task = new GetUserInfoTask(mStartIndex, mEndIndex);
task.execute();
}
}
private void hideFooterView() {
Logger.i(TAG, "hide footer view called");
if (listView != null) {
if (mFooterView != null) {
listView.removeFooterView(mFooterView);
}
}
}
private void showFooterView() {
if (mFooterView != null) {
// 保证只有一个FooterView
listView.removeFooterView(mFooterView);
footText.setText("正在加载");
footBar.setVisibility(View.VISIBLE);
listView.addFooterView(mFooterView);
listView.setAdapter(mAdapter);
}
}
private void showEmptyView() {
if (mFooterView != null) {
// 保证只有一个FooterView
listView.removeFooterView(mFooterView);
footText.setText("无结果");
footBar.setVisibility(View.GONE);
listView.addFooterView(mFooterView);
listView.setAdapter(mAdapter);
}
}
private void searchCancel() {
isSearching = false;
if (task != null && task.getStatus() == DandAsyncTask.Status.RUNNING) {
task.cancel(true);
}
mStartIndex = 0;
mEndIndex = 0;
if (mSavedList != null) {
mListData.clear();
mListData.addAll(mSavedList);
mAdapter.notifyDataSetChanged();
}
hideFooterView();
if (currentPage < mTotalCount / PAGE_SIZE) {
showFooterView();
}
}
// TODO: 移动到VDiskApi的类里面去
public class GetUserInfoTask extends DandAsyncTask<Object[], Void, String> {
int mStartIndex;
int mEndIndex;
public GetUserInfoTask(int mStartIndex, int mEndIndex) {
this.mStartIndex = mStartIndex;
this.mEndIndex = mEndIndex;
}
@Override
protected void onPostExecute(String url) {
mAdapter.notifyDataSetChanged();
}
@Override
protected String doInBackground(Object[]... params) {
try {
for (; mStartIndex < mEndIndex; mStartIndex++) {
Logger.i(TAG, "mStartIndex-->" + mStartIndex
+ ";mEndIndex-->" + mEndIndex);
try {
FansInfo info = (FansInfo) mAdapter
.getItem(mStartIndex);
Logger.d("FansInfo", info.id + "-->" + info.screen_name);
String[] response = DandelionAPI.getInstance(
getActivity()).getUserInfo(info.id);
if (response != null) {
UserInfo userInfo = UserInfo.create(new JSONObject(
response[1]));
info.profile_image_url = userInfo.profile_image_url;
if ("false".equals(response[0])) {
CacheUtils
.updateCache(
getActivity(),
CacheUtils
.getKey(CacheUtils.CACHE_USER_INFO,
new String[] {
"uid",
info.id }),
response[1]);
}
}
} catch (Exception e) {
e.printStackTrace();
}
publishProgress();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Void... values) {
mAdapter.notifyDataSetChanged();
}
}
/**
* 搜索粉丝列表,使用Weibo API
*/
public class SearchFansTask extends DandAsyncTask<Void, Void, Object> {
String q;
String count;
public SearchFansTask(String q, String count) {
this.q = q;
this.count = count;
}
@Override
protected Object doInBackground(Void... params) {
try {
String response = DandelionAPI.getInstance(getActivity())
.searchFans(q, count);
JSONArray array = new JSONArray(response);
ArrayList<FansInfo> fansList = FansInfo.sCreate(array);
return fansList;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Object result) {
hideFooterView();
if (result != null) {
if (isSearching) {
ArrayList<FansInfo> slist = (ArrayList<FansInfo>) result;
Logger.i(TAG, "search fans list succeed!");
mListData.clear();
mListData.addAll(slist);
if (mListData.isEmpty()) {
showEmptyView();
} else {
mAdapter.notifyDataSetChanged();
if (task != null
&& task.getStatus() == DandAsyncTask.Status.RUNNING) {
task.cancel(true);
}
if (mAdapter.getCount() < 10) {
mEndIndex = mAdapter.getCount();
task = new GetUserInfoTask(mStartIndex, mEndIndex);
task.execute();
} else {
mEndIndex = 10;
task = new GetUserInfoTask(mStartIndex, mEndIndex);
task.execute();
}
}
}
} else {
Toast.makeText(getActivity(), "搜索失败", Toast.LENGTH_SHORT)
.show();
}
}
}
public void hideInputMethod() {
if (mSvSearch != null) {
mSvSearch.clearFocus();
InputMethodManager imm = (InputMethodManager) getActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mSvSearch.getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
}
}