package net.coding.program.project.detail;
import android.app.Activity;
import android.content.Intent;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import net.coding.program.FootUpdate;
import net.coding.program.MyApp;
import net.coding.program.R;
import net.coding.program.common.BlankViewDisplay;
import net.coding.program.common.Global;
import net.coding.program.common.base.CustomMoreFragment;
import net.coding.program.common.widget.FlowLabelLayout;
import net.coding.program.model.ProjectObject;
import net.coding.program.model.TopicObject;
import net.coding.program.project.detail.topic.TopicListDetailActivity_;
import net.coding.program.user.UserDetailActivity_;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EFragment;
import org.androidannotations.annotations.FragmentArg;
import org.androidannotations.annotations.OptionsItem;
import org.androidannotations.annotations.OptionsMenu;
import org.androidannotations.annotations.ViewById;
import org.androidannotations.annotations.res.AnimationRes;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
@EFragment(R.layout.fragment_project_topic_list)
@OptionsMenu(R.menu.project_task)
public class TopicListFragment extends CustomMoreFragment implements FootUpdate.LoadMore {
static final int RESULT_ADD = 1;
static final int RESULT_DETAIL = 2;
private static final int ID_TYPE_ALL = 0;
private static final int ID_TYPE_MY = 1;
private static final String TYPE_ALL = "全部讨论";
private static final String TYPE_MY = "我的讨论";
private static final int ID_LABEL_ALL = -1;
private static final String LABEL_ALL = "全部标签";
private static final String ORDER_REPLY_TIME = "最后评论排序";
private static final String ORDER_PUBLISH_TIME = "发布时间排序";
private static final String ORDER_HOT = "热门排序";
private static final int ID_ORDER_REPLY_TIME = 51;
private static final int ID_ORDER_PUBLISH_TIME = 49;
private static final int ID_ORDER_HOT = 53;
private static final String URI_TOPICS = Global.HOST_API + "/user/%s/project/%s/topics/mobile?type=%s&orderBy=%s";
private static final String URI_TYPE_COUNTS = Global.HOST_API + "/user/%s/project/%s/topics/count";
private static final String URI_ALL_LABELS = Global.HOST_API + "/user/%s/project/%s/topics/labels?withCount=true";
private static final String URI_MY_LABELS = Global.HOST_API + "/user/%s/project/%s/topics/labels/my";
// 刷新页面后如果当前标签不再存在,则自动变回【全部标签】再刷新
private static final String URI_ALL_LABELS_THEN_RELOAD = "URI_ALL_LABELS_THEN_RELOAD";
private static final String URI_MY_LABELS_THEN_RELOAD = "URI_MY_LABELS_THEN_RELOAD";
@FragmentArg
ProjectObject mProjectObject;
@ViewById
ListView listView;
@ViewById
View mask;
@ViewById
DropdownButton chooseType, chooseLabel, chooseOrder;
@ViewById
DropdownListView dropdownType, dropdownLabel, dropdownOrder;
@ViewById
View blankLayout;
@AnimationRes
Animation dropdown_in, dropdown_out, dropdown_mask_out;
View.OnClickListener onClickUser = new View.OnClickListener() {
@Override
public void onClick(View v) {
String globaKey = (String) v.getTag();
Intent intent = new Intent(getActivity(), UserDetailActivity_.class);
intent.putExtra("globalKey", globaKey);
startActivity(intent);
}
};
private ArrayList<TopicObject> mData = new ArrayList<>();
private String urlGet;
View.OnClickListener onClickRetry = new View.OnClickListener() {
@Override
public void onClick(View v) {
onRefresh();
}
};
BaseAdapter baseAdapter = new BaseAdapter() {
@Override
public int getCount() {
return mData.size();
}
@Override
public Object getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.fragment_project_topic_list_item, parent, false);
holder = new ViewHolder();
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
holder.icon.setOnClickListener(onClickUser);
holder.title = (TextView) convertView.findViewById(R.id.title);
holder.time = (TextView) convertView.findViewById(R.id.time);
holder.time.setFocusable(false);
holder.refId = (TextView) convertView.findViewById(R.id.referenceId);
holder.discuss = (TextView) convertView.findViewById(R.id.discuss);
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.flowLayout = (FlowLabelLayout) convertView.findViewById(R.id.flowLayout);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
TopicObject data = (TopicObject) getItem(position);
iconfromNetwork(holder.icon, data.owner.avatar);
holder.icon.setTag(data.owner.global_key);
holder.title.setText(Global.changeHyperlinkColor(data.title));
holder.refId.setText(data.getRefId());
holder.name.setText(data.owner.name);
holder.time.setText(Global.changeHyperlinkColor(Global.dayToNow(data.created_at)));
holder.discuss.setText(String.format("%d", data.child_count));
int flowWidth = MyApp.sWidthPix - Global.dpToPx(66 + 12);
holder.flowLayout.setLabels(data.labels, flowWidth);
if (position == (getCount() - 1)) {
loadMore();
}
return convertView;
}
};
private DropdownButtonsController dropdownButtonsController = new DropdownButtonsController();
@AfterViews
protected void init() {
dropdownButtonsController.init();
initRefreshLayout();
showDialogLoading();
mFootUpdate.init(listView, mInflater, this);
listView.setAdapter(baseAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(getActivity(), TopicListDetailActivity_.class);
intent.putExtra("topicObject", ((TopicObject) baseAdapter.getItem((int) id)));
getParentFragment().startActivityForResult(intent, RESULT_DETAIL);
}
});
dropdownButtonsController.flushAll(true);
}
@Override
public void loadMore() {
getNextPageNetwork(urlGet, urlGet);
}
@Override
public void onRefresh() {
urlGet = getLink();
initSetting();
loadMore();
}
@Override
public void parseJson(int code, JSONObject respanse, String tag, int pos, Object data) throws JSONException {
if (URI_TYPE_COUNTS.equals(tag)) {
if (code == 0 && dropdownButtonsController != null && respanse != null)
dropdownButtonsController.flushCounts(respanse.optJSONObject("data"));
return;
}
if (URI_ALL_LABELS.equals(tag)) {
if (code == 0 && dropdownButtonsController != null && respanse != null)
dropdownButtonsController.flushAllLabels(respanse.optJSONArray("data"));
return;
}
if (URI_MY_LABELS.equals(tag)) {
if (code == 0 && dropdownButtonsController != null && respanse != null)
dropdownButtonsController.flushMyLabels(respanse.optJSONArray("data"));
return;
}
if (URI_MY_LABELS_THEN_RELOAD.equals(tag)) {
if (code == 0 && dropdownButtonsController != null && respanse != null) {
dropdownButtonsController.flushMyLabels(respanse.optJSONArray("data"));
onRefresh();
}
return;
}
if (URI_ALL_LABELS_THEN_RELOAD.equals(tag)) {
if (code == 0 && dropdownButtonsController != null && respanse != null) {
dropdownButtonsController.flushAllLabels(respanse.optJSONArray("data"));
onRefresh();
}
return;
}
setRefreshing(false);
hideProgressDialog();
if (code == 0) {
if (isLoadingFirstPage(tag)) {
mData.clear();
}
if (respanse.has("data")) {
JSONArray jsonArray = respanse.getJSONObject("data").getJSONArray("list");
for (int i = 0; i < jsonArray.length(); ++i) {
JSONObject json = jsonArray.getJSONObject(i);
TopicObject topicObject = new TopicObject(json);
mData.add(topicObject);
}
}
BlankViewDisplay.setBlank(mData.size(), TopicListFragment.this, true, blankLayout, onClickRetry);
baseAdapter.notifyDataSetChanged();
} else {
showErrorMsg(code, respanse);
BlankViewDisplay.setBlank(mData.size(), TopicListFragment.this, false, blankLayout, onClickRetry);
}
mFootUpdate.updateState(code, isLoadingLastPage(tag), mData.size());
}
@OptionsItem
void action_add() {
Intent intent = new Intent(getActivity(), TopicAddActivity_.class);
intent.putExtra("projectObject", mProjectObject);
getParentFragment().startActivityForResult(intent, RESULT_ADD);
}
@Override
public void onResume() {
super.onResume();
dropdownButtonsController.reset();
dropdownButtonsController.flushAll(false);
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case RESULT_ADD:
if (resultCode == Activity.RESULT_OK) {
// TopicObject topic = (TopicObject) data.getSerializableExtra("topic");
// mData.add(0, topic);
// baseAdapter.notifyDataSetChanged();
// dropdownButtonsController.flushAll();
dropdownButtonsController.flushAll(false);
}
break;
case RESULT_DETAIL:
if (resultCode == Activity.RESULT_OK) {
// int id = data.getIntExtra("id", -1);
// if (id != -1) {
// for (int i = 0; i < mData.size(); ++i) {
// if (mData.get(i).id == (id)) {
// mData.remove(i);
// baseAdapter.notifyDataSetChanged();
// break;
// }
// }
// } else {
// int topicId = data.getIntExtra("topic_id", 0);
// int childrenCount = data.getIntExtra("child_count", -1);
// for (int i = 0; i < mData.size(); ++i) {
// if (mData.get(i).id == topicId) {
// mData.get(i).child_count = childrenCount;
// baseAdapter.notifyDataSetChanged();
// break;
// }
// }
// }
//
// Serializable topicObject = data.getSerializableExtra("topic");
// if (topicObject instanceof TopicObject) {
// TopicObject topicData = (TopicObject) topicObject;
//
// for (int i = 0; i < mData.size(); ++i) {
// if (mData.get(i).id == topicData.id) {
// mData.set(i, topicData);
// baseAdapter.notifyDataSetChanged();
// break;
// }
// }
//
// }
dropdownButtonsController.flushAll(false);
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
protected String getLink() {
String topicType = dropdownType.current.value;
String topicOrder = dropdownOrder.current.value;
String url = String.format(URI_TOPICS, mProjectObject.owner_user_name, mProjectObject.name, topicType, topicOrder);
if (dropdownLabel.current != null && !TextUtils.isEmpty(dropdownLabel.current.value)) {
url += "&labelId=" + dropdownLabel.current.value;
}
return url;
}
@Click
void mask() {
dropdownButtonsController.hide();
}
public static class ViewHolder {
public ImageView icon;
public TextView title;
public TextView discuss;
public TextView time;
public TextView name;
public FlowLabelLayout flowLayout;
public TextView refId;
}
private class DropdownButtonsController implements DropdownListView.Container {
private DropdownListView currentDropdownList;
private List<DropdownItemObject> datasetType = new ArrayList<>(2);
private List<DropdownItemObject> datasetAllLabel = new ArrayList<>();
private List<DropdownItemObject> datasetMyLabel = new ArrayList<>();
private List<DropdownItemObject> datasetLabel = datasetAllLabel;
private List<DropdownItemObject> datasetOrder = new ArrayList<>(3);
@Override
public void show(DropdownListView view) {
if (currentDropdownList != null) {
currentDropdownList.clearAnimation();
currentDropdownList.startAnimation(dropdown_out);
currentDropdownList.setVisibility(View.GONE);
currentDropdownList.button.setChecked(false);
}
currentDropdownList = view;
mask.clearAnimation();
mask.setVisibility(View.VISIBLE);
currentDropdownList.clearAnimation();
currentDropdownList.startAnimation(dropdown_in);
currentDropdownList.setVisibility(View.VISIBLE);
currentDropdownList.button.setChecked(true);
}
@Override
public void hide() {
if (currentDropdownList != null) {
currentDropdownList.clearAnimation();
currentDropdownList.startAnimation(dropdown_out);
currentDropdownList.button.setChecked(false);
mask.clearAnimation();
mask.startAnimation(dropdown_mask_out);
}
currentDropdownList = null;
}
@Override
public void onSelectionChanged(DropdownListView view) {
if (view == dropdownType) {
updateLabels(getCurrentLabels());
}
onRefresh();
}
void reset() {
chooseType.setChecked(false);
chooseLabel.setChecked(false);
chooseOrder.setChecked(false);
dropdownType.setVisibility(View.GONE);
dropdownLabel.setVisibility(View.GONE);
dropdownOrder.setVisibility(View.GONE);
mask.setVisibility(View.GONE);
dropdownType.clearAnimation();
dropdownLabel.clearAnimation();
dropdownOrder.clearAnimation();
mask.clearAnimation();
}
void init() {
reset();
datasetType.add(new DropdownItemObject(TYPE_ALL, ID_TYPE_ALL, "all"));
datasetType.add(new DropdownItemObject(TYPE_MY, ID_TYPE_MY, "my"));
dropdownType.bind(datasetType, chooseType, this, ID_TYPE_ALL);
datasetAllLabel.add(new DropdownItemObject(LABEL_ALL, ID_LABEL_ALL, null) {
@Override
public String getSuffix() {
return dropdownType.current == null ? "" : dropdownType.current.getSuffix();
}
});
datasetMyLabel.add(new DropdownItemObject(LABEL_ALL, ID_LABEL_ALL, null));
datasetLabel = datasetAllLabel;
dropdownLabel.bind(datasetLabel, chooseLabel, this, ID_LABEL_ALL);
datasetOrder.add(new DropdownItemObject(ORDER_REPLY_TIME, ID_ORDER_REPLY_TIME, "51"));
datasetOrder.add(new DropdownItemObject(ORDER_PUBLISH_TIME, ID_ORDER_PUBLISH_TIME, "49"));
datasetOrder.add(new DropdownItemObject(ORDER_HOT, ID_ORDER_HOT, "53"));
dropdownOrder.bind(datasetOrder, chooseOrder, this, ID_ORDER_REPLY_TIME);
dropdown_mask_out.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
if (currentDropdownList == null) {
reset();
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
private List<DropdownItemObject> getCurrentLabels() {
return dropdownType.current != null && dropdownType.current.id == ID_TYPE_MY ? datasetMyLabel : datasetAllLabel;
}
void updateLabels(List<DropdownItemObject> targetList) {
if (targetList == getCurrentLabels()) {
datasetLabel = targetList;
dropdownLabel.bind(datasetLabel, chooseLabel, this, dropdownLabel.current.id);
}
}
void flushAll(boolean reloadImmedate) {
getNetwork(String.format(URI_TYPE_COUNTS, mProjectObject.owner_user_name, mProjectObject.name), URI_TYPE_COUNTS);
if (reloadImmedate) {
getNetwork(String.format(URI_ALL_LABELS, mProjectObject.owner_user_name, mProjectObject.name), URI_ALL_LABELS);
getNetwork(String.format(URI_MY_LABELS, mProjectObject.owner_user_name, mProjectObject.name), URI_MY_LABELS);
onRefresh();
} else {
List<DropdownItemObject> currentList = getCurrentLabels();
getNetwork(String.format(URI_ALL_LABELS, mProjectObject.owner_user_name, mProjectObject.name), currentList == datasetAllLabel ? URI_ALL_LABELS_THEN_RELOAD : URI_ALL_LABELS);
getNetwork(String.format(URI_MY_LABELS, mProjectObject.owner_user_name, mProjectObject.name), currentList == datasetMyLabel ? URI_MY_LABELS_THEN_RELOAD : URI_MY_LABELS);
}
}
public void flushCounts(JSONObject json) {
if (json == null) return;
datasetType.get(ID_TYPE_ALL).setSuffix(" (" + json.optInt("all", 0) + ")");
datasetType.get(ID_TYPE_MY).setSuffix(" (" + json.optInt("my", 0) + ")");
dropdownType.flush();
dropdownLabel.flush();
}
void flushAllLabels(JSONArray array) {
flushLabels(array, datasetAllLabel);
}
void flushMyLabels(JSONArray array) {
flushLabels(array, datasetMyLabel);
}
private void flushLabels(JSONArray array, List<DropdownItemObject> targetList) {
if (array == null) return;
while (targetList.size() > 1) targetList.remove(targetList.size() - 1);
for (int i = 0, n = array.length(); i < n; i++) {
final JSONObject data = array.optJSONObject(i);
int id = data.optInt("id");
String name = data.optString("name");
if (TextUtils.isEmpty(name)) continue;
int topicsCount = data.optInt("count", 0);
// 只有all才做0数量过滤,因为my的返回数据总是0
if (topicsCount == 0 && targetList == datasetAllLabel) continue;
DropdownItemObject item = new DropdownItemObject(name, id, String.valueOf(id));
if (targetList == datasetAllLabel)
item.setSuffix(String.format(" (%d)", data.optInt("count", 0)));
targetList.add(item);
}
updateLabels(targetList);
}
}
}