Resolve conflict.

This commit is contained in:
chenjuntao
2018-03-27 10:24:00 +08:00
39 changed files with 1912 additions and 391 deletions

View File

@ -1,11 +1,15 @@
package com.gh.base.fragment;
import android.app.Dialog;
import android.arch.lifecycle.Lifecycle;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.v4.app.DialogFragment;
import com.gh.gamecenter.R;
import com.lightgame.utils.RuntimeUtils;
import com.lightgame.utils.Utils;
/**
* @author CsHeng
@ -24,6 +28,24 @@ public class BaseDialogFragment extends DialogFragment {
return dialog;
}
public void toast(@StringRes int res) {
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED))
toast(getString(res));
}
public void toast(String msg) {
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED))
Utils.toast(getContext(), msg);
}
public void toastLong(@StringRes int msg) {
toastLong(getString(msg));
}
public void toastLong(String msg) {
RuntimeUtils.getInstance().toastLong(getContext(), msg);
}
}

View File

@ -0,0 +1,55 @@
package com.gh.base.fragment;
import android.app.Dialog;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.gh.gamecenter.R;
/**
* Wrap another fragment with dialog fragment.
*/
public class BaseDialogWrapperFragment extends BaseDialogFragment {
private Fragment mFragmentToWrap;
public static BaseDialogWrapperFragment getInstance(Fragment fragmentToWrap) {
BaseDialogWrapperFragment fragment = new BaseDialogWrapperFragment();
fragment.mFragmentToWrap = fragmentToWrap;
return fragment;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_dialog_wrapper, null);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getChildFragmentManager().beginTransaction().replace(R.id.fragment_placeholder, mFragmentToWrap).commitNowAllowingStateLoss();
}
@Override
public void onStart() {
super.onStart();
getDialog().getWindow().setGravity(Gravity.BOTTOM);
getDialog().getWindow().setLayout(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.setCanceledOnTouchOutside(true);
return dialog;
}
}

View File

@ -71,6 +71,13 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
@LayoutRes
protected abstract int getLayoutId();
/**
* 提供 Inflated 的 view ,可用于 data binding.
*/
protected View getInflatedLayout() {
return null;
}
/**
* 责任链谁处理了就返回true否则返回super.handleOnClick(View view)
*
@ -106,8 +113,15 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
isEverPause = false;
EventBus.getDefault().register(this);
mCachedView = View.inflate(getContext(), getLayoutId(), null);
// For data binding.
if (getInflatedLayout() != null) {
mCachedView = getInflatedLayout();
} else {
mCachedView = View.inflate(getContext(), getLayoutId(), null);
}
ButterKnife.bind(this, mCachedView);
initView(mCachedView);
}

View File

@ -151,6 +151,75 @@ public class CommentUtils {
}
public static void showAnswerCommentOptions(final CommentEntity commentEntity, final Context context,
final OnCommentCallBackListener listener, final String id, boolean showConversation) {
final Dialog dialog = new Dialog(context);
LinearLayout container = new LinearLayout(context);
container.setOrientation(LinearLayout.VERTICAL);
container.setBackgroundColor(Color.WHITE);
container.setPadding(0, DisplayUtils.dip2px(context, 12), 0, DisplayUtils.dip2px(context, 12));
List<String> dialogType = new ArrayList<>();
if (commentEntity.getUserData() == null || !commentEntity.getUserData().isCommentOwn()) {
dialogType.add("回复");
}
dialogType.add("复制");
dialogType.add("举报");
if (commentEntity.getParent() != null && showConversation) {
dialogType.add("查看对话");
}
for (String s : dialogType) {
final TextView reportTv = new TextView(context);
reportTv.setText(s);
reportTv.setTextSize(17);
reportTv.setTextColor(ContextCompat.getColor(context, R.color.title));
reportTv.setBackgroundResource(R.drawable.textview_white_style);
int widthPixels = context.getResources().getDisplayMetrics().widthPixels;
reportTv.setLayoutParams(new LinearLayout.LayoutParams((widthPixels * 9) / 10,
LinearLayout.LayoutParams.WRAP_CONTENT));
reportTv.setPadding(DisplayUtils.dip2px(context, 20), DisplayUtils.dip2px(context, 12),
0, DisplayUtils.dip2px(context, 12));
container.addView(reportTv);
reportTv.setOnClickListener(v -> {
dialog.cancel();
switch (reportTv.getText().toString()) {
case "回复":
CheckLoginUtils.checkLogin(context, () -> {
if (listener != null) {
listener.onCommentCallback(commentEntity);
} else if (!TextUtils.isEmpty(id)) {
context.startActivity(MessageDetailActivity.getMessageDetailIntent(context, commentEntity, id));
} else {
Utils.toast(context, "缺少关键属性");
}
});
break;
case "复制":
LibaoUtils.copyLink(commentEntity.getContent(), context);
break;
case "举报":
CheckLoginUtils.checkLogin(context, () -> showReportTypeDialog(commentEntity, context));
break;
case "查看对话":
context.startActivity(CommentDetailActivity.getAnswerCommentIntent(context, commentEntity.getId()));
break;
}
});
}
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(container);
dialog.show();
}
private static void showReportTypeDialog(final CommentEntity commentEntity, final Context context) {
final String[] arrReportType = new String[]{"垃圾广告营销", "恶意攻击谩骂", "淫秽色情信息",
"违法有害信息", "其它"};
@ -265,6 +334,61 @@ public class CommentUtils {
});
}
public static void postVoteToAnswerComment(final Context context, String answerId, final CommentEntity commentEntity,
final TextView commentLikeCountTv, final ImageView commentLikeIv, final OnVoteListener listener) {
CheckLoginUtils.checkLogin(context, () -> {
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.theme)) {
Utils.toast(context, "已经点过赞啦!");
return;
}
commentEntity.setVote(commentEntity.getVote() + 1);
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.theme));
commentLikeIv.setImageResource(R.drawable.ic_like_select);
commentLikeCountTv.setText(String.valueOf(commentEntity.getVote()));
commentLikeCountTv.setVisibility(View.VISIBLE);
PostCommentUtils.voteAnswerComment(context, answerId, commentEntity.getId(),
new PostCommentUtils.PostCommentListener() {
@Override
public void postSuccess(JSONObject response) {
if (listener != null) {
listener.onVote();
}
}
@Override
public void postFailed(Throwable e) {
commentEntity.setVote(commentEntity.getVote() - 1);
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.hint));
commentLikeIv.setImageResource(R.drawable.ic_like_unselect);
commentLikeCountTv.setText(String.valueOf(commentEntity.getVote()));
if (commentEntity.getVote() == 0) {
commentLikeCountTv.setVisibility(View.GONE);
} else {
commentLikeCountTv.setVisibility(View.VISIBLE);
}
if (e instanceof HttpException) {
HttpException exception = (HttpException) e;
if (exception.code() == 403) {
try {
String detail = new JSONObject(exception.response().errorBody().string()).getString("detail");
if ("voted".equals(detail)) {
Utils.toast(context, "已经点过赞啦!");
}
} catch (Exception ex) {
ex.printStackTrace();
}
return;
}
}
Utils.toast(context, "网络异常,点赞失败");
}
});
});
}
// 设置评论item 用户相关的view(点赞/头像/用户名)
public static void setCommentUserView(Context mContext, CommentViewHolder holder, CommentEntity entity) {

View File

@ -57,6 +57,62 @@ public class PostCommentUtils {
});
}
public static void addAnswerComment(final Context context, final String answerId, final String content,
final CommentEntity commentEntity,
final PostCommentListener listener) {
RequestBody body = RequestBody.create(MediaType.parse("application/json"), content);
Observable<ResponseBody> observable;
if (commentEntity != null) {
observable = RetrofitManager.getInstance(context).getApi().postReplyToAnswerComment(answerId, commentEntity.getId(), body);
} else {
observable = RetrofitManager.getInstance(context).getApi().postNewCommentToAnswer(answerId, body);
}
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new JSONObjectResponse() {
@Override
public void onResponse(JSONObject response) {
if (response.length() != 0) {
if (listener != null) {
listener.postSuccess(response);
}
} else {
Utils.toast(context, R.string.post_failure_hint);
}
}
@Override
public void onFailure(HttpException e) {
if (listener != null) {
listener.postFailed(e);
}
}
});
}
public static void voteAnswerComment(final Context context,final String answerId, final String commentId,
final PostCommentListener listener) {
RetrofitManager.getInstance(context).getApi()
.postVoteAnswerComment(answerId,commentId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<ResponseBody>() {
@Override
public void onResponse(ResponseBody response) {
if (listener != null) {
listener.postSuccess(null);
}
}
@Override
public void onFailure(HttpException e) {
if (listener != null) {
listener.postFailed(e);
}
}
});
}
public static void addCommentVoto(final Context context, final String commentId,
final PostCommentListener listener) {
RetrofitManager.getInstance(context).getApi()

View File

@ -189,7 +189,7 @@ public class RichEditor extends WebView {
try {
exec("javascript:RE.setHtml('" + URLEncoder.encode(contents, "UTF-8") + "');");
if (isLoadTbImage && !NetworkUtils.isWifiConnected(getContext())) {
if (isLoadTbImage && NetworkUtils.isWifiConnected(getContext())) {
exec("javascript:RE.replaceTbImage()");
}

View File

@ -5,6 +5,7 @@ import android.content.Intent;
import android.os.Bundle;
import com.gh.common.util.EntranceUtils;
import com.gh.gamecenter.ask.viewmodel.AnswerCommentConversationFragment;
import com.halo.assistant.fragment.comment.CommentDetailFragment;
/**
@ -22,4 +23,13 @@ public class CommentDetailActivity extends NormalActivity {
return getIntent(context, CommentDetailFragment.class, args);
}
public static Intent getAnswerCommentIntent(Context context, String commentId) {
Bundle args = new Bundle();
args.putString(EntranceUtils.KEY_COMMENTID, commentId);
// return new IntentFactory.Builder(context)
// .setActivity(CommentDetailActivity.class)
// .setFragment(CommentDetailFragment.class).setArgs(args).build();
return getIntent(context, AnswerCommentConversationFragment.class, args);
}
}

View File

@ -161,7 +161,9 @@ public class NormalActivity extends BaseActivity implements ToolbarController, T
MenuItem menuItem = menu.getItem(i);
// menu设置actionLayout后无法捕捉点击事件以icon为tag如果icon is null 手动设置menuItem点击事件
if (menuItem != null && menuItem.getIcon() == null) {
menuItem.getActionView().setOnClickListener((v) -> this.onMenuItemClick(menuItem));
if (menuItem.getActionView() != null) {
menuItem.getActionView().setOnClickListener((v) -> this.onMenuItemClick(menuItem));
}
}
}
}

View File

@ -0,0 +1,22 @@
package com.gh.gamecenter.adapter.viewholder;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.gh.gamecenter.R;
import butterknife.BindView;
public class AnswerCommentViewHolder extends CommentViewHolder {
@BindView(R.id.comment_quote_container)
public ViewGroup quoteContainer;
@BindView(R.id.comment_quote_author_tv)
public TextView quoteAuthorTv;
@BindView(R.id.comment_quote_content_tv)
public TextView quoteContentTv;
public AnswerCommentViewHolder(View itemView) {
super(itemView);
}
}

View File

@ -0,0 +1,104 @@
package com.gh.gamecenter.ask;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import com.gh.common.constant.ItemViewType;
import com.gh.common.util.CommentUtils;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.OnCommentCallBackListener;
import com.gh.gamecenter.adapter.viewholder.AnswerCommentViewHolder;
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder;
import com.gh.gamecenter.baselist.ListAdapter;
import com.gh.gamecenter.entity.CommentEntity;
public class AnswerCommentAdapter extends ListAdapter<CommentEntity> {
private String mAnswerId;
private boolean mIsShowingConversation;
private OnCommentCallBackListener mOnCommentCallBackListener;
public AnswerCommentAdapter(Context context, String answerId, boolean isShowingConversation, OnCommentCallBackListener commentCallBackListener) {
super(context);
mAnswerId = answerId;
mIsShowingConversation = isShowingConversation;
mOnCommentCallBackListener = commentCallBackListener;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == ItemViewType.LOADING) {
View view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false);
return new FooterViewHolder(view);
} else {
View view = mLayoutInflater.inflate(R.layout.answer_comment_item, parent, false);
return new AnswerCommentViewHolder(view);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof AnswerCommentViewHolder) {
initCommentViewHolder((AnswerCommentViewHolder) holder, position);
} else if (holder instanceof FooterViewHolder) {
initFooterViewHolder((FooterViewHolder) holder);
}
}
@Override
public int getItemViewType(int position) {
if (position == getItemCount() - 1) {
return ItemViewType.LOADING;
}
return 100;
}
@Override
public int getItemCount() {
return mEntityList == null || mEntityList.isEmpty() ? 0 : mEntityList.size() + FOOTER_ITEM_COUNT;
}
private void initCommentViewHolder(final AnswerCommentViewHolder holder, int position) {
final CommentEntity commentEntity = mEntityList.get(position);
holder.commentLine.setVisibility(View.GONE);
holder.commentLineBottom.setVisibility(View.VISIBLE);
CommentUtils.setCommentUserView(mContext, holder, commentEntity);
CommentUtils.setCommentTime(holder.commentTimeTv, commentEntity.getTime());
holder.commentContentTv.setText(commentEntity.getContent());
if (commentEntity.getParent() != null && commentEntity.getParent().getUser() != null) {
holder.quoteContainer.setVisibility(View.VISIBLE);
holder.quoteAuthorTv.setText(commentEntity.getParent().getUser().getName());
holder.quoteContentTv.setText("孙一峰星際爭霸與星際爭霸2的職業選手電競戰隊Xteam的經理美少女团体星際老男孩成員之一還在杭州經營水產生意。");
} else {
holder.quoteContainer.setVisibility(View.GONE);
}
holder.commentLikeIv.setOnClickListener(v -> CommentUtils.postVoteToAnswerComment(mContext, mAnswerId, commentEntity, holder.commentLikeCountTv, holder.commentLikeIv, null));
holder.itemView.setOnClickListener(v -> CommentUtils.showAnswerCommentOptions(commentEntity, mContext, mOnCommentCallBackListener, null, !mIsShowingConversation));
}
private void initFooterViewHolder(FooterViewHolder holder) {
if (mIsNetworkError) {
holder.loading.setVisibility(View.GONE);
holder.hint.setText(R.string.loading_error_network);
} else if (!mIsOver) {
holder.hint.setText(R.string.loading);
holder.loading.setVisibility(View.VISIBLE);
} else if (mEntityList.size() == 0) {
holder.loading.setVisibility(View.GONE);
holder.hint.setText(R.string.comment_empty);
} else {
holder.hint.setText(R.string.comment_nomore);
holder.loading.setVisibility(View.GONE);
}
}
}

View File

@ -0,0 +1,248 @@
package com.gh.gamecenter.ask;
import android.app.Application;
import android.app.Dialog;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import com.gh.base.fragment.BaseDialogWrapperFragment;
import com.gh.common.util.CheckLoginUtils;
import com.gh.common.util.DialogUtils;
import com.gh.common.view.VerticalItemDecoration;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.OnCommentCallBackListener;
import com.gh.gamecenter.ask.viewmodel.AnswerCommentViewModel;
import com.gh.gamecenter.baselist.ListAdapter;
import com.gh.gamecenter.baselist.ListFragment;
import com.gh.gamecenter.entity.CommentEntity;
import com.lightgame.utils.Util_System_Keyboard;
import com.lightgame.utils.Utils;
import org.json.JSONObject;
import butterknife.BindView;
import butterknife.OnClick;
import butterknife.Optional;
import retrofit2.HttpException;
public class AnswerCommentFragment extends ListFragment<CommentEntity, AnswerCommentViewModel> implements OnCommentCallBackListener {
@BindView(R.id.answer_comment_et)
protected EditText mCommentDetailCommentEt;
@BindView(R.id.answer_comment_send_btn)
protected TextView mCommentSend;
protected Dialog mSendingDialog;
protected String mAnswerId;
protected CommentEntity mCommentEntity; // 回复评论的实体 用完马上清空
protected AnswerCommentAdapter mAdapter;
protected boolean mShowSoftKeyboardOnStartUp;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mListViewModel.getPostCommentLiveData().observe(this, apiResponse -> {
if (apiResponse == null) return;
if (apiResponse.getData() != null) {
mSendingDialog.dismiss();
toast("发表成功");
mCommentDetailCommentEt.setText("");
setSoftInput(false);
} else if (apiResponse.getHttpException() != null) {
mSendingDialog.dismiss();
HttpException exception = apiResponse.getHttpException();
if (exception.code() == 403) {
try {
JSONObject errorJson = new JSONObject(exception.response().errorBody().string());
int errorCode = errorJson.getInt("code");
switch (errorCode) {
case 403018:
toast("内容可能已被删除");
setSoftInput(false);
break;
case 403019:
toast("你已被禁言");
break;
case 403020:
toast(R.string.comment_failed_toofrequent);
break;
case 403201:
toast(R.string.comment_failed_illegal);
break;
default:
toast(R.string.comment_failed_unknown);
break;
}
} catch (Exception ex) {
ex.printStackTrace();
toast("评论异常");
}
} else if (exception.code() == 404){
toast(R.string.post_failure_hint);
}
} else {
toast(R.string.post_failure_hint);
}
});
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (mShowSoftKeyboardOnStartUp) {
mCommentDetailCommentEt.postDelayed(() -> {
mCommentDetailCommentEt.setFocusable(true);
mCommentDetailCommentEt.setFocusableInTouchMode(true);
mCommentDetailCommentEt.requestFocus();
InputMethodManager keyboard = (InputMethodManager)
getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
keyboard.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}, 200);
}
mCommentDetailCommentEt.addTextChangedListener(watcher);
}
@Override
protected RecyclerView.ItemDecoration getItemDecoration() {
return new VerticalItemDecoration(getContext(), 0, true);
}
@Override
protected AnswerCommentViewModel provideListViewModel() {
return ViewModelProviders.of(this, new AnswerCommentViewModel.Factory((Application) getContext().getApplicationContext(), mAnswerId, null)).get(AnswerCommentViewModel.class);
}
@Override
protected ListAdapter provideListAdapter() {
return mAdapter == null ? mAdapter = new AnswerCommentAdapter(getContext(), mAnswerId, false, this) : mAdapter;
}
@Override
protected int getLayoutId() {
return R.layout.fragment_answer_comment;
}
public static AnswerCommentFragment getInstance(String answerId, boolean showSoftKeyboardOnStartUp) {
AnswerCommentFragment fragment = new AnswerCommentFragment();
fragment.mShowSoftKeyboardOnStartUp = showSoftKeyboardOnStartUp;
fragment.mAnswerId = answerId;
return fragment;
}
private TextWatcher watcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.toString().trim().length() > 0) {
mCommentSend.setEnabled(true);
if (s.length() > 140) {
mCommentDetailCommentEt.setText("");
String newText = s.toString().substring(0, 140);
mCommentDetailCommentEt.setText(newText);
mCommentDetailCommentEt.setSelection(mCommentDetailCommentEt.getText().length());
Utils.toast(getContext(), "评论不能多于140字");
}
} else {
mCommentSend.setEnabled(false);
}
}
@Override
public void afterTextChanged(Editable s) {
}
};
@Override
public void onCommentCallback(CommentEntity entity) {
mCommentEntity = entity;
setSoftInput(true);
}
@Optional
@OnClick({R.id.answer_comment_send_btn, R.id.answer_comment_close_iv})
public void onClick(View view) {
switch (view.getId()) {
case R.id.answer_comment_send_btn:
postComment();
break;
case R.id.answer_comment_close_iv:
setSoftInput(false);
Fragment fragment = getParentFragment();
if (fragment instanceof BaseDialogWrapperFragment) {
((BaseDialogWrapperFragment) fragment).dismiss();
}
break;
}
}
private void postComment() {
final String content = mCommentDetailCommentEt.getText().toString();
if (content.length() == 0) {
toast("评论内容不能为空!");
return;
}
mSendingDialog = DialogUtils.showWaitDialog(getContext(), getString(R.string.post_dialog_hint));
if (mCommentEntity != null && mCommentEntity.getId() == null) {
toast("评论异常 id null");
mSendingDialog.cancel();
return;
}
mListViewModel.postComment(content, mAnswerId, mCommentEntity);
}
//软键盘控制
protected void setSoftInput(boolean isShow) {
if (isShow) {
CheckLoginUtils.checkLogin(getContext(), () -> {
Util_System_Keyboard.showSoftKeyboard(getContext(), mCommentDetailCommentEt);
mCommentDetailCommentEt.setFocusable(true);
mCommentDetailCommentEt.setFocusableInTouchMode(true);
mCommentDetailCommentEt.requestFocus();
if (mCommentEntity != null && mCommentEntity.getUser() != null) {
mCommentDetailCommentEt.setHint(getString(R.string.comment_repty_hint, mCommentEntity.getUser().getName()));
} else {
mCommentDetailCommentEt.setHint(getString(R.string.message_detail_comment_hint));
}
});
} else {
Util_System_Keyboard.hideSoftKeyboard(getContext(), mCommentDetailCommentEt);
if (mCommentEntity != null) {
mCommentEntity = null; // 清空当前评论实体
mCommentDetailCommentEt.setHint(getString(R.string.message_detail_comment_hint));
mCommentDetailCommentEt.setText("");
}
}
}
}

View File

@ -1,23 +1,34 @@
package com.gh.gamecenter.ask;
import android.app.Activity;
import android.app.Dialog;
import android.arch.lifecycle.Lifecycle;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.databinding.BindingAdapter;
import android.databinding.DataBindingUtil;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.JavascriptInterface;
import android.widget.ImageView;
import android.widget.TextView;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.common.util.AskLogUtils;
import com.gh.base.fragment.BaseDialogWrapperFragment;
import com.gh.common.util.AskUtils;
import com.gh.common.util.CheckLoginUtils;
import com.gh.common.util.CollectionUtils;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.ImageUtils;
import com.gh.common.util.NewsUtils;
@ -25,15 +36,16 @@ import com.gh.common.util.ShareUtils;
import com.gh.common.view.RichEditor;
import com.gh.gamecenter.NormalActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.SuggestionActivity;
import com.gh.gamecenter.ViewImageActivity;
import com.gh.gamecenter.ask.entity.AnswerDetailEntity;
import com.gh.gamecenter.ask.entity.MeEntity;
import com.gh.gamecenter.ask.questionsdetail.AnswerEditFragment;
import com.gh.gamecenter.ask.questionsdetail.QuestionsDetailFragment;
import com.gh.gamecenter.ask.viewmodel.AnswerDetailViewModel;
import com.gh.gamecenter.databinding.FragmentAnswerDetailBinding;
import com.gh.gamecenter.entity.UserEntity;
import com.gh.gamecenter.normal.NormalFragment;
import com.gh.gamecenter.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.lightgame.utils.Utils;
import org.json.JSONObject;
@ -43,15 +55,12 @@ import java.util.ArrayList;
import butterknife.BindView;
import butterknife.OnClick;
import okhttp3.ResponseBody;
import retrofit2.HttpException;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
/**
* Created by khy on 17/12/17.
* Modified by juntao on 18/3/21.
*/
public class AnswerDetailFragment extends NormalFragment {
@BindView(R.id.answer_detail_title)
@ -60,8 +69,6 @@ public class AnswerDetailFragment extends NormalFragment {
RichEditor mRichEditor;
@BindView(R.id.answer_detail_time)
TextView mTime;
@BindView(R.id.answer_detail_edit)
TextView mEditBtn;
@BindView(R.id.answer_detail_vote)
ImageView mVote;
@BindView(R.id.answer_detail_vote_count)
@ -80,10 +87,9 @@ public class AnswerDetailFragment extends NormalFragment {
View mNoData;
@BindView(R.id.reuse_tv_none_data)
TextView mNoDataTv;
MenuItem mMenuCollect;
public static final String TAG = "ask.AnswerDetailFragment";
private static final int ANSWER_PATCH_REQUEST = 100;
public static final String TAG = "ask.AnswerDetailFragment";
private ArrayList<String> mAnswersImgs = new ArrayList<>();
@ -91,9 +97,49 @@ public class AnswerDetailFragment extends NormalFragment {
private String mAnswerId;
private MenuItem mCollectMenuItem;
private AnswerDetailViewModel mViewModel;
private FragmentAnswerDetailBinding mBinding;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewModel = ViewModelProviders.of(this).get(AnswerDetailViewModel.class);
initObserver();
if (getArguments() != null) {
mAnswerId = getArguments().getString(EntranceUtils.KEY_ANSWER_ID);
mViewModel.getAnswerDetail(mAnswerId, mEntrance);
}
initMenu(R.menu.menu_answer);
mRichEditor.setInputEnabled(false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
mRichEditor.addJavascriptInterface(new JsInterface(), "imagelistener");
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setNavigationTitle(getString(R.string.answer_detail_title));
}
@Override
protected int getLayoutId() {
return R.layout.fragment_answer_detail;
return 0;
}
@Override
protected View getInflatedLayout() {
mBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.fragment_answer_detail, null, false);
return mBinding.getRoot();
}
@Override
@ -102,36 +148,274 @@ public class AnswerDetailFragment extends NormalFragment {
if (resultCode == Activity.RESULT_OK && requestCode == ANSWER_PATCH_REQUEST && data != null && getActivity() != null) {
if (mDetailEntity != null) {
mDetailEntity.setContent(data.getStringExtra(EntranceUtils.KEY_ANSWER_CONTENT));
initView();
updateView();
}
getActivity().setResult(Activity.RESULT_OK, new Intent()); // 编辑答案问题详情页面已存在Id只需要一个空Intent
}
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setNavigationTitle(getString(R.string.answer_detail_title));
initMenu(R.menu.menu_web);
mMenuCollect = getItemMenu(R.id.menu_collect);
private void initObserver() {
mViewModel.getAnswerLiveData().observe(this, apiResponse -> {
if (apiResponse == null) return;
if (apiResponse.getData() != null) {
mDetailEntity = apiResponse.getData();
mBinding.setDetail(mDetailEntity);
updateView();
} else if (apiResponse.getHttpException() != null) {
HttpException e = apiResponse.getHttpException();
try {
if (e != null && e.code() == 404 && e.response().errorBody().string().length() > 0) {
mNoDataTv.setText(R.string.content_delete_hint);
mNoData.setVisibility(View.VISIBLE);
mNoConn.setVisibility(View.GONE);
mLoading.setVisibility(View.GONE);
mContent.setVisibility(View.GONE);
Utils.toast(getContext(), R.string.content_delete_toast);
} else {
mNoConn.setVisibility(View.VISIBLE);
mLoading.setVisibility(View.GONE);
mContent.setVisibility(View.GONE);
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
mViewModel.getVoteLiveData().observe(this, apiResponse -> {
if (apiResponse == null) return;
if (apiResponse.getData() != null) {
MeEntity me = mDetailEntity.getMe();
me.setAnswerVoted(true);
mDetailEntity.setMe(me);
int vote = mDetailEntity.getVote() + 1;
mDetailEntity.setVote(vote);
updateVote();
} else if (apiResponse.getHttpException() != null) {
HttpException e = apiResponse.getHttpException();
if (e == null || e.code() != 403) {
toast(R.string.request_failure_normal_hint);
} else {
try {
JSONObject object = new JSONObject(e.response().errorBody().string());
int errorCode = object.getInt("code");
if (errorCode == 403008) {
toast(R.string.ask_vote_hint);
MeEntity me = mDetailEntity.getMe();
me.setAnswerVoted(true);
updateVote();
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
});
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mAnswerId = getArguments().getString(EntranceUtils.KEY_ANSWER_ID);
initData();
public void onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.menu_more:
showMoreItemDialog();
break;
case R.id.menu_collect:
if (mDetailEntity == null) return;
CheckLoginUtils.checkLogin(getContext(), () -> {
if (!mDetailEntity.getMe().isAnswerFavorite()) {
CollectionUtils.INSTANCE.postCollection(getContext(), mAnswerId
, CollectionUtils.CollectionType.answer, new CollectionUtils.OnCollectionListener() {
@Override
public void onSuccess() {
mCollectMenuItem.setIcon(R.drawable.menu_ic_collect_select);
toast(R.string.collection_success);
MeEntity me = mDetailEntity.getMe();
me.setAnswerFavorite(true);
mDetailEntity.setMe(me);
}
@Override
public void onError() {
toast(R.string.collection_failure);
}
});
} else {
CollectionUtils.INSTANCE.deleteCollection(getContext(), mAnswerId
, CollectionUtils.CollectionType.answer, new CollectionUtils.OnCollectionListener() {
@Override
public void onSuccess() {
mCollectMenuItem.setIcon(R.drawable.menu_ic_collect_unselect);
MeEntity me = mDetailEntity.getMe();
me.setAnswerFavorite(false);
mDetailEntity.setMe(me);
toast(R.string.collection_cancel);
}
@Override
public void onError() {
toast(R.string.collection_cancel_failure);
}
});
}
});
}
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
mRichEditor.addJavascriptInterface(new JsInterface(), "imagelistener");
private void showMoreItemDialog() {
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED) || mDetailEntity != null) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.menu_answer_detail_more, null);
Dialog dialog = new Dialog(getActivity());
dialog.setContentView(view);
Window window = dialog.getWindow();
if (window != null) {
window.setGravity(Gravity.RIGHT | Gravity.TOP);
window.setBackgroundDrawable(new ColorDrawable(0));
window.setDimAmount(0.2f);
WindowManager.LayoutParams lp = window.getAttributes();
lp.x = DisplayUtils.dip2px(getContext(), 17);
lp.y = DisplayUtils.dip2px(getContext(), 45); // 减去卡片高度
window.setAttributes(lp);
}
dialog.show();
ImageView icon = view.findViewById(R.id.more_item_icon1);
TextView title = view.findViewById(R.id.more_item_title1);
if (mDetailEntity.getMe().isAnswerOwn()) {
icon.setImageResource(R.drawable.menu_more_edit);
title.setText("编辑");
}
View item1 = view.findViewById(R.id.more_item1);
View item2 = view.findViewById(R.id.more_item2);
item1.setOnClickListener(v -> {
dialog.dismiss();
if ("编辑".equals(title.getText().toString())) {
// 跳转编辑问题页面
editContent();
} else {
// 跳转意见反馈
SuggestionActivity.startSuggestionActivity(getContext(), 1, "report", "问题举报:");
}
});
item2.setOnClickListener(v -> {
dialog.dismiss();
if (mDetailEntity == null) return;
String shareIcon;
String shareSummary = mRichEditor.getText();
if (mAnswersImgs.size() > 0) {
shareIcon = mAnswersImgs.get(0);
} else {
shareIcon = getString(R.string.share_ghzs_logo);
}
if (TextUtils.isEmpty(shareSummary)) {
shareSummary = getString(R.string.ask_share_default_summary);
}
ShareUtils.getInstance(getContext()).showShareWindows(getActivity(), getView()
, getString(R.string.share_answers_url, mDetailEntity.getQuestion().getId(), mAnswerId)
, shareIcon
, getString(R.string.ask_share_answers_title, mDetailEntity.getUser().getName(), mDetailEntity.getQuestion().getTitle(), mDetailEntity.getVote())
, shareSummary, ShareUtils.ShareType.askNormal);
});
}
}
@OnClick({R.id.answer_detail_vote, R.id.reuse_no_connection, R.id.answer_detail_title, R.id.answer_detail_do_comment_container, R.id.answer_detail_comment_count_container})
public void onClick(View view) {
switch (view.getId()) {
case R.id.answer_detail_vote:
CheckLoginUtils.checkLogin(getContext(), () -> {
if (mDetailEntity != null && !mDetailEntity.getMe().isAnswerVoted()) {
mViewModel.postVote(mAnswerId);
} else {
toast(R.string.ask_vote_hint);
}
});
break;
case R.id.reuse_no_connection:
mNoConn.setVisibility(View.GONE);
mLoading.setVisibility(View.VISIBLE);
mViewModel.getAnswerDetail(mAnswerId, mEntrance);
break;
case R.id.answer_detail_title:
if (mDetailEntity != null) {
Bundle bundle = new Bundle();
bundle.putString(EntranceUtils.KEY_QUESTIONS_ID, mDetailEntity.getQuestion().getId());
bundle.putString(EntranceUtils.KEY_ENTRANCE, mEntrance);
NormalActivity.startFragment(getContext(), QuestionsDetailFragment.class, bundle);
}
break;
case R.id.answer_detail_do_comment_container:
BaseDialogWrapperFragment dialog = BaseDialogWrapperFragment.getInstance(AnswerCommentFragment.getInstance(mAnswerId, true));
dialog.show(getFragmentManager(), "CommentDialog");
break;
case R.id.answer_detail_comment_count_container:
BaseDialogWrapperFragment dialogFragment = BaseDialogWrapperFragment.getInstance(AnswerCommentFragment.getInstance(mAnswerId, false));
dialogFragment.show(getFragmentManager(), "CommentDialog");
// TODO Display count in it's textview.
break;
}
}
private void editContent() {
if (mDetailEntity != null) {
Bundle bundle = new Bundle();
bundle.putString(EntranceUtils.KEY_ANSWER_ID, mAnswerId);
bundle.putString(EntranceUtils.KEY_QUESTIONS_TITLE, mDetailEntity.getQuestion().getTitle());
bundle.putString(EntranceUtils.KEY_ANSWER_CONTENT, mDetailEntity.getContent());
NormalActivity.startFragmentForResult(getContext(), AnswerEditFragment.class, bundle, ANSWER_PATCH_REQUEST);
}
}
private void updateView() {
mCollectMenuItem = getItemMenu(R.id.menu_collect);
if (mDetailEntity.getMe().isAnswerFavorite()) {
mCollectMenuItem.setIcon(R.drawable.menu_ic_collect_select);
} else {
mCollectMenuItem.setIcon(R.drawable.menu_ic_collect_unselect);
}
UserEntity user = mDetailEntity.getUser();
if (user != null) {
ImageUtils.Companion.display(mUsericon, user.getIcon());
mUsername.setText(user.getName());
}
NewsUtils.setNewsDetailTime(mTime, mDetailEntity.getTime());
mNoConn.setVisibility(View.GONE);
mLoading.setVisibility(View.GONE);
mContent.setVisibility(View.VISIBLE);
updateVote();
}
private void updateVote() {
mVoteCount.setText(getString(R.string.ask_vote_count, AskUtils.voteCountFormat(mDetailEntity.getVote())));
if (getContext() == null) return;
if (mDetailEntity.getMe().isAnswerVoted()) {
mVote.setImageResource(R.drawable.answer_detail_unvote);
mVoteCount.setTextColor(ContextCompat.getColor(getContext(), R.color.theme));
} else {
mVote.setImageResource(R.drawable.answer_detail_vote);
mVoteCount.setTextColor(ContextCompat.getColor(getContext(), R.color.hint));
}
}
@BindingAdapter("setRichContent")
public static void setContent(RichEditor richEditor, String content) {
if (TextUtils.isEmpty(content)) {
richEditor.setVisibility(View.GONE);
} else {
richEditor.setHtml(content, true);
richEditor.setVisibility(View.VISIBLE);
}
}
public class JsInterface {
@JavascriptInterface
public void imageClick(String url) {
if (url.contains("web_load_dfimg_icon.png")) {
@ -159,233 +443,4 @@ public class AnswerDetailFragment extends NormalFragment {
}
}
}
@Override
public void onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.menu_share:
if (mDetailEntity == null) return;
String shareIcon;
String shareSummary = mRichEditor.getText();
if (mAnswersImgs.size() > 0) {
shareIcon = mAnswersImgs.get(0);
} else {
shareIcon = getString(R.string.share_ghzs_logo);
}
if (TextUtils.isEmpty(shareSummary)) {
shareSummary = getString(R.string.ask_share_default_summary);
}
ShareUtils.getInstance(getContext()).showShareWindows(getActivity(), getView()
, getString(R.string.share_answers_url, mDetailEntity.getQuestion().getId(), mAnswerId)
, shareIcon
, getString(R.string.ask_share_answers_title, mDetailEntity.getUser().getName(), mDetailEntity.getQuestion().getTitle(), mDetailEntity.getVote())
, shareSummary, ShareUtils.ShareType.askNormal);
break;
case R.id.menu_collect:
if (mDetailEntity == null) return;
CheckLoginUtils.checkLogin(getContext(), () -> {
if (!mDetailEntity.getMe().isAnswerFavorite()) {
CollectionUtils.INSTANCE.postCollection(getContext(), mAnswerId
, CollectionUtils.CollectionType.answer, new CollectionUtils.OnCollectionListener() {
@Override
public void onSuccess() {
mMenuCollect.setIcon(R.drawable.menu_ic_collect_select);
toast(R.string.collection_success);
MeEntity me = mDetailEntity.getMe();
me.setAnswerFavorite(true);
mDetailEntity.setMe(me);
}
@Override
public void onError() {
toast(R.string.collection_failure);
}
});
} else {
CollectionUtils.INSTANCE.deleteCollection(getContext(), mAnswerId
, CollectionUtils.CollectionType.answer, new CollectionUtils.OnCollectionListener() {
@Override
public void onSuccess() {
mMenuCollect.setIcon(R.drawable.menu_ic_collect_unselect);
MeEntity me = mDetailEntity.getMe();
me.setAnswerFavorite(false);
mDetailEntity.setMe(me);
toast(R.string.collection_cancel);
}
@Override
public void onError() {
toast(R.string.collection_cancel_failure);
}
});
}
});
break;
}
}
@OnClick({R.id.answer_detail_edit, R.id.answer_detail_vote, R.id.reuse_no_connection, R.id.answer_detail_title})
public void onClick(View view) {
switch (view.getId()) {
case R.id.answer_detail_edit:
if (mDetailEntity != null) {
Bundle bundle = new Bundle();
bundle.putString(EntranceUtils.KEY_ANSWER_ID, mAnswerId);
bundle.putString(EntranceUtils.KEY_QUESTIONS_TITLE, mDetailEntity.getQuestion().getTitle());
bundle.putString(EntranceUtils.KEY_ANSWER_CONTENT, mDetailEntity.getContent());
NormalActivity.startFragmentForResult(getContext(), AnswerEditFragment.class, bundle, ANSWER_PATCH_REQUEST);
}
break;
case R.id.answer_detail_vote:
CheckLoginUtils.checkLogin(getContext(), () -> {
if (mDetailEntity != null && !mDetailEntity.getMe().isAnswerVoted()) {
postVote();
} else {
toast(R.string.ask_vote_hint);
}
});
break;
case R.id.reuse_no_connection:
mNoConn.setVisibility(View.GONE);
mLoading.setVisibility(View.VISIBLE);
initData();
break;
case R.id.answer_detail_title:
if (mDetailEntity != null) {
Bundle bundle = new Bundle();
bundle.putString(EntranceUtils.KEY_QUESTIONS_ID, mDetailEntity.getQuestion().getId());
bundle.putString(EntranceUtils.KEY_ENTRANCE, mEntrance);
NormalActivity.startFragment(getContext(), QuestionsDetailFragment.class, bundle);
}
break;
}
}
private void initData() {
RetrofitManager.getInstance(getContext()).getApi()
.getAnswerDetail(mAnswerId, Utils.getTime(getContext()))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<AnswerDetailEntity>() {
@Override
public void onResponse(AnswerDetailEntity response) {
super.onResponse(response);
mDetailEntity = response;
initView();
AskLogUtils.uploadAnswers(getContext(), mEntrance, response.getQuestion(), mAnswerId);
}
@Override
public void onFailure(HttpException e) {
super.onFailure(e);
try {
if (e != null && e.code() == 404 && e.response().errorBody().string().length() > 0) {
mNoDataTv.setText(R.string.content_delete_hint);
mNoData.setVisibility(View.VISIBLE);
mNoConn.setVisibility(View.GONE);
mLoading.setVisibility(View.GONE);
mContent.setVisibility(View.GONE);
Utils.toast(getContext(), R.string.content_delete_toast);
} else {
mNoConn.setVisibility(View.VISIBLE);
mLoading.setVisibility(View.GONE);
mContent.setVisibility(View.GONE);
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
}
private void initView() {
UserEntity user = mDetailEntity.getUser();
if (user != null) {
ImageUtils.Companion.display(mUsericon, user.getIcon());
mUsername.setText(user.getName());
}
if (mDetailEntity.getMe().isAnswerOwn()) {
mEditBtn.setVisibility(View.VISIBLE);
} else {
mEditBtn.setVisibility(View.GONE);
}
if (mDetailEntity.getMe().isAnswerFavorite()) {
mMenuCollect.setIcon(R.drawable.menu_ic_collect_select);
} else {
mMenuCollect.setIcon(R.drawable.menu_ic_collect_unselect);
}
mTitle.setText(mDetailEntity.getQuestion().getTitle());
NewsUtils.setNewsDetailTime(mTime, mDetailEntity.getTime());
mRichEditor.setHtml(mDetailEntity.getContent(), true);
mRichEditor.setInputEnabled(false);
mNoConn.setVisibility(View.GONE);
mLoading.setVisibility(View.GONE);
mContent.setVisibility(View.VISIBLE);
initVote();
}
private void initVote() {
mVoteCount.setText(getString(R.string.ask_vote_count, AskUtils.voteCountFormat(mDetailEntity.getVote())));
if (getContext() == null) return;
if (mDetailEntity.getMe().isAnswerVoted()) {
mVote.setImageResource(R.drawable.answer_detail_unvote);
mVoteCount.setTextColor(ContextCompat.getColor(getContext(), R.color.theme));
} else {
mVote.setImageResource(R.drawable.answer_detail_vote);
mVoteCount.setTextColor(ContextCompat.getColor(getContext(), R.color.hint));
}
}
private void postVote() {
RetrofitManager.getInstance(getContext()).getApi()
.postAnswerVote(mAnswerId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<ResponseBody>() {
@Override
public void onResponse(ResponseBody response) {
super.onResponse(response);
MeEntity me = mDetailEntity.getMe();
me.setAnswerVoted(true);
mDetailEntity.setMe(me);
int vote = mDetailEntity.getVote() + 1;
mDetailEntity.setVote(vote);
initVote();
}
@Override
public void onFailure(HttpException e) {
super.onFailure(e);
if (e == null || e.code() != 403) {
toast(R.string.request_failure_normal_hint);
} else {
try {
JSONObject object = new JSONObject(e.response().errorBody().string());
int errorCode = object.getInt("code");
if (errorCode == 403008) {
toast(R.string.ask_vote_hint);
MeEntity me = mDetailEntity.getMe();
me.setAnswerVoted(true);
initVote();
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
// AskErrorResponseUtils.errorResponseControl(getContext(), e);
}
});
}
}

View File

@ -0,0 +1,64 @@
package com.gh.gamecenter.ask.viewmodel;
import android.annotation.SuppressLint;
import android.app.Application;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;
import com.gh.common.util.EntranceUtils;
import com.gh.gamecenter.R;
import com.gh.gamecenter.ask.AnswerCommentFragment;
import com.gh.gamecenter.entity.CommentEntity;
import butterknife.BindView;
public class AnswerCommentConversationFragment extends AnswerCommentFragment {
@BindView(R.id.answer_comment_content_container)
View mCommentContainer;
private String mCommentId;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCommentId = getArguments().getString(EntranceUtils.KEY_COMMENTID);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mCommentContainer.setVisibility(View.GONE);
setNavigationTitle("查看对话");
mListRv.setOnTouchListener((v, event) -> {
if (mCommentContainer.getVisibility() == View.VISIBLE) {
mCommentContainer.setVisibility(View.GONE);
}
return false;
});
}
@Override
protected int getLayoutId() {
return R.layout.fragment_answer_comment_conversation;
}
@Override
protected AnswerCommentViewModel provideListViewModel() {
return ViewModelProviders.of(this, new AnswerCommentViewModel.Factory((Application) getContext().getApplicationContext(), mAnswerId, mCommentId)).get(AnswerCommentViewModel.class);
}
@Override
public void onCommentCallback(CommentEntity entity) {
mCommentContainer.setVisibility(View.VISIBLE);
mCommentEntity = entity;
setSoftInput(true);
}
}

View File

@ -0,0 +1,102 @@
package com.gh.gamecenter.ask.viewmodel;
import android.app.Application;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.ViewModel;
import android.arch.lifecycle.ViewModelProvider;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import com.gh.common.util.PostCommentUtils;
import com.gh.gamecenter.baselist.ListViewModel;
import com.gh.gamecenter.entity.CommentEntity;
import com.gh.gamecenter.login.ApiResponse;
import com.gh.gamecenter.retrofit.RetrofitManager;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.List;
import retrofit2.HttpException;
import rx.Observable;
public class AnswerCommentViewModel extends ListViewModel<CommentEntity, CommentEntity> {
private String mAnswerId;
private String mCommentId;
private MutableLiveData<ApiResponse<JSONObject>> mPostCommentLiveData = new MutableLiveData<>();
public AnswerCommentViewModel(@NonNull Application application, String answerId, @Nullable String commentId) {
super(application);
mResultLiveData.addSource(mListLiveData, mResultLiveData::postValue);
mAnswerId = answerId;
mCommentId = commentId;
}
@Override
public Observable<List<CommentEntity>> provideDataObservable(int offset) {
if (TextUtils.isEmpty(mCommentId)) {
return RetrofitManager.getInstance(getApplication()).getApi().getAnswerCommentList(mAnswerId, 0, offset);
} else {
return RetrofitManager.getInstance(getApplication()).getApi().getAnswerCommentConversationList(mAnswerId, mCommentId, 0, offset);
}
// return RetrofitManager.getInstance(getApplication()).getApi().getComment("59c0b965e9a64abe2a423544", 0, offset);
}
public void postComment(String content, String answerId, CommentEntity commentEntity) {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("content", content);
} catch (JSONException e) {
e.printStackTrace();
}
PostCommentUtils.addAnswerComment(getApplication(), answerId, jsonObject.toString(), commentEntity,
new PostCommentUtils.PostCommentListener() {
@Override
public void postSuccess(JSONObject response) {
ApiResponse<JSONObject> apiResponse = new ApiResponse<>();
apiResponse.setData(response);
mPostCommentLiveData.postValue(apiResponse);
}
@Override
public void postFailed(Throwable e) {
ApiResponse<JSONObject> apiResponse = new ApiResponse<>();
if (e instanceof HttpException) {
apiResponse.setHttpException((HttpException) e);
mPostCommentLiveData.postValue(apiResponse);
} else {
mPostCommentLiveData.postValue(apiResponse);
}
}
});
}
public LiveData<ApiResponse<JSONObject>> getPostCommentLiveData() {
return mPostCommentLiveData;
}
public static class Factory extends ViewModelProvider.NewInstanceFactory {
private Application mApplication;
private String mAnswerId;
private String mCommentId;
public Factory(Application application, String answerId, String commentId) {
mApplication = application;
mAnswerId = answerId;
mCommentId = commentId;
}
@Override
public <T extends ViewModel> T create(Class<T> modelClass) {
return (T) new AnswerCommentViewModel(mApplication, mAnswerId, mCommentId);
}
}
}

View File

@ -0,0 +1,83 @@
package com.gh.gamecenter.ask.viewmodel;
import android.app.Application;
import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.support.annotation.NonNull;
import com.gh.common.util.AskLogUtils;
import com.gh.gamecenter.ask.entity.AnswerDetailEntity;
import com.gh.gamecenter.login.ApiResponse;
import com.gh.gamecenter.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.lightgame.utils.Utils;
import okhttp3.ResponseBody;
import retrofit2.HttpException;
import rx.schedulers.Schedulers;
public class AnswerDetailViewModel extends AndroidViewModel {
private MutableLiveData<ApiResponse<AnswerDetailEntity>> mAnswerLiveData = new MutableLiveData<>();
private MutableLiveData<ApiResponse<ResponseBody>> mVoteLiveData = new MutableLiveData<>();
public AnswerDetailViewModel(@NonNull Application application) {
super(application);
}
public void getAnswerDetail(String answerId, String entrance) {
RetrofitManager.getInstance(getApplication()).getApi()
.getAnswerDetail(answerId, Utils.getTime(getApplication()))
.subscribeOn(Schedulers.io())
.subscribe(new Response<AnswerDetailEntity>() {
@Override
public void onResponse(AnswerDetailEntity response) {
ApiResponse<AnswerDetailEntity> apiResponse = new ApiResponse<>();
apiResponse.setData(response);
mAnswerLiveData.postValue(apiResponse);
AskLogUtils.uploadAnswers(getApplication(), entrance, response.getQuestion(), answerId);
}
@Override
public void onFailure(HttpException e) {
ApiResponse<AnswerDetailEntity> apiResponse = new ApiResponse<>();
apiResponse.setHttpException(e);
mAnswerLiveData.postValue(apiResponse);
}
});
}
public void postVote(String answerId) {
RetrofitManager.getInstance(getApplication()).getApi()
.postAnswerVote(answerId)
.subscribeOn(Schedulers.io())
.subscribe(new Response<ResponseBody>() {
@Override
public void onResponse(ResponseBody response) {
ApiResponse<ResponseBody> apiResponse = new ApiResponse<>();
apiResponse.setData(response);
mVoteLiveData.postValue(apiResponse);
}
@Override
public void onFailure(HttpException e) {
ApiResponse<ResponseBody> apiResponse = new ApiResponse<>();
apiResponse.setHttpException(e);
mVoteLiveData.postValue(apiResponse);
// AskErrorResponseUtils.errorResponseControl(getApplication(), e);
}
});
}
public LiveData<ApiResponse<AnswerDetailEntity>> getAnswerLiveData() {
return mAnswerLiveData;
}
public LiveData<ApiResponse<ResponseBody>> getVoteLiveData() {
return mVoteLiveData;
}
}

View File

@ -5,13 +5,16 @@ import android.os.Parcelable
class CommentParentEntity() : Parcelable {
var user: UserEntity? = null
var content: String? = null
constructor(parcel: Parcel) : this() {
user = parcel.readParcelable(UserEntity::class.java.classLoader)
content = parcel.readString()
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeParcelable(user, flags)
parcel.writeString(content)
}
override fun describeContents(): Int {

View File

@ -886,4 +886,34 @@ public interface ApiService {
@GET("support/setting/download")
Observable<List<ControlEntity>> getGhzsControlData(@Query("version") String version, @Query("channel") String channel);
/**
* 给一个回答新增评论
*/
@POST("answers/{answer_id}/comments")
Observable<ResponseBody> postNewCommentToAnswer(@Path("answer_id") String answerId, @Body RequestBody body);
/**
* 在评论列表回复某一条评论
*/
@POST("answers/{answer_id}/comments/{comment_id}:reply")
Observable<ResponseBody> postReplyToAnswerComment(@Path("answer_id") String answerId, @Path("comment_id") String commentId, @Body RequestBody body);
/**
* 对评论的点赞
*/
@POST("answers/{answer_id}/comments/{comment_id}:vote")
Observable<ResponseBody> postVoteAnswerComment(@Path("answer_id") String answerId, @Path("comment_id") String commentId);
/**
* 获取评论列表.可以分页
*/
@GET("answers/{answer_id}/comments")
Observable<List<CommentEntity>> getAnswerCommentList(@Path("answer_id") String answerId, @Query("limit") int limit, @Query("offset") int offset);
/**
* 获取评论的对话列表.
*/
@GET("answers/{answer_id}/comments/{comment_id}/trace")
Observable<List<CommentEntity>> getAnswerCommentConversationList(@Path("answer_id") String answerId, @Path("comment_id") String commentId, @Query("limit") int limit, @Query("offset") int offset);
}