diff --git a/app/build.gradle b/app/build.gradle
index 55cfb3f2b3..ca1c44dcdd 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -249,6 +249,7 @@ dependencies {
implementation "android.arch.lifecycle:extensions:${archLifecycleVersion}"
implementation "android.arch.persistence.room:runtime:${archRoomVersion}"
kapt "android.arch.persistence.room:compiler:${archRoomVersion}"
+ implementation "android.arch.persistence.room:rxjava2:${archRoomVersion}"
implementation 'com.google.android:flexbox:0.2.2'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ba970e9325..78c2162a9e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -385,6 +385,10 @@
android:name = "com.gh.gamecenter.gamedetail.rating.RatingReplyActivity"
android:screenOrientation = "portrait" />
+
+
Unit) {
+ AppExecutor.ioExecutor.execute(f)
+}
+
+fun runOnUiThread(f: () -> Unit) {
+ AppExecutor.uiExecutor.execute(f)
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/common/history/HistoryDatabase.kt b/app/src/main/java/com/gh/common/history/HistoryDatabase.kt
new file mode 100644
index 0000000000..cc478dfeea
--- /dev/null
+++ b/app/src/main/java/com/gh/common/history/HistoryDatabase.kt
@@ -0,0 +1,23 @@
+package com.gh.common.history
+
+import android.arch.persistence.room.Database
+import android.arch.persistence.room.Room
+import android.arch.persistence.room.RoomDatabase
+import com.gh.gamecenter.qa.entity.AnswerEntity
+import com.gh.gamecenter.room.dao.HistoryAnswerDao
+import com.halo.assistant.HaloApp
+
+@Database(entities = [AnswerEntity::class], version = 1, exportSchema = false)
+abstract class HistoryDatabase : RoomDatabase() {
+
+ abstract fun answerDao(): HistoryAnswerDao
+
+ companion object {
+ val instance by lazy {
+ Room.databaseBuilder(HaloApp.getInstance().application, HistoryDatabase::class.java, "USER_TRACK_HISTORY_DATABASE")
+ .fallbackToDestructiveMigration()
+ .build()
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/common/history/HistoryHelper.kt b/app/src/main/java/com/gh/common/history/HistoryHelper.kt
new file mode 100644
index 0000000000..54f8e93cb2
--- /dev/null
+++ b/app/src/main/java/com/gh/common/history/HistoryHelper.kt
@@ -0,0 +1,30 @@
+package com.gh.common.history
+
+import android.text.Html
+import com.gh.common.runOnIoThread
+import com.gh.gamecenter.qa.entity.AnswerDetailEntity
+import com.gh.gamecenter.qa.entity.AnswerEntity
+
+object HistoryHelper {
+
+ fun insertAnswerEntity(answerDetailEntity: AnswerDetailEntity) {
+ val answerEntity = convertAnswerDetailEntityToAnswerEntity(answerDetailEntity)
+ runOnIoThread { HistoryDatabase.instance.answerDao().addAnswer(answerEntity) }
+ }
+
+ private fun convertAnswerDetailEntityToAnswerEntity(answerDetailEntity: AnswerDetailEntity): AnswerEntity {
+ val answerEntity = AnswerEntity()
+
+ answerEntity.id = answerDetailEntity.id
+ answerEntity.primaryKey = answerDetailEntity.id
+ answerEntity.commentCount = answerDetailEntity.commentCount
+ answerEntity.questions = answerDetailEntity.question
+ answerEntity.vote = answerDetailEntity.vote
+ answerEntity.user = answerDetailEntity.user
+ answerEntity.orderTag = System.currentTimeMillis()
+ answerEntity.brief = Html.fromHtml(answerDetailEntity.content).toString()
+ answerEntity.time = answerDetailEntity.time
+ return answerEntity
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/common/view/ExpendTextView.java b/app/src/main/java/com/gh/common/view/ExpendTextView.java
index 29af50ad6d..f3ebf3703d 100644
--- a/app/src/main/java/com/gh/common/view/ExpendTextView.java
+++ b/app/src/main/java/com/gh/common/view/ExpendTextView.java
@@ -89,7 +89,8 @@ public class ExpendTextView extends android.support.v7.widget.AppCompatTextView
}
SpannableStringBuilder msp = new SpannableStringBuilder(content);
int length = msp.length();
- msp.replace(length - mExpendText.length(), length, mExpendText);
+ int startPosition = length - mExpendText.length();
+ msp.replace(startPosition < 0 ? 0 : startPosition, length, mExpendText);
msp.setSpan(new ClickableSpan() {
@Override
public void updateDrawState(TextPaint ds) {
diff --git a/app/src/main/java/com/gh/gamecenter/baselist/ListActivity.java b/app/src/main/java/com/gh/gamecenter/baselist/ListActivity.java
index 9551cb95ed..badf8ca0b6 100644
--- a/app/src/main/java/com/gh/gamecenter/baselist/ListActivity.java
+++ b/app/src/main/java/com/gh/gamecenter/baselist/ListActivity.java
@@ -23,6 +23,7 @@ import java.util.List;
import butterknife.BindView;
import io.reactivex.Observable;
+import io.reactivex.Single;
public abstract class ListActivity
extends BaseActivity
@@ -144,6 +145,11 @@ public abstract class ListActivity provideDataSingle(int page) {
+ return null;
+ }
+
public void onLoadRefresh() {
mReuseNoConn.setVisibility(View.GONE);
mReuseNoData.setVisibility(View.GONE);
diff --git a/app/src/main/java/com/gh/gamecenter/baselist/ListFragment.java b/app/src/main/java/com/gh/gamecenter/baselist/ListFragment.java
index a0e1ebf394..c73ccc4b9d 100644
--- a/app/src/main/java/com/gh/gamecenter/baselist/ListFragment.java
+++ b/app/src/main/java/com/gh/gamecenter/baselist/ListFragment.java
@@ -24,6 +24,7 @@ import java.util.List;
import butterknife.BindView;
import io.reactivex.Observable;
+import io.reactivex.Single;
/**
* Created by khy on 2/12/17.
@@ -161,6 +162,11 @@ public abstract class ListFragment> provideDataSingle(int page) {
+ return null;
+ }
+
public void onLoadRefresh() {
mReuseNoConn.setVisibility(View.GONE);
mReuseNoData.setVisibility(View.GONE);
diff --git a/app/src/main/java/com/gh/gamecenter/baselist/ListViewModel.java b/app/src/main/java/com/gh/gamecenter/baselist/ListViewModel.java
index ba5d3414a0..fbe8eca86d 100644
--- a/app/src/main/java/com/gh/gamecenter/baselist/ListViewModel.java
+++ b/app/src/main/java/com/gh/gamecenter/baselist/ListViewModel.java
@@ -1,5 +1,6 @@
package com.gh.gamecenter.baselist;
+import android.annotation.SuppressLint;
import android.app.Application;
import android.arch.lifecycle.MutableLiveData;
import android.support.annotation.NonNull;
@@ -7,13 +8,17 @@ import android.support.annotation.NonNull;
import com.gh.common.util.ApkActiveUtils;
import com.gh.download.DownloadManager;
import com.gh.gamecenter.entity.GameEntity;
+import com.gh.gamecenter.retrofit.BiResponse;
import com.gh.gamecenter.retrofit.Response;
import com.halo.assistant.HaloApp;
+import org.jetbrains.annotations.NotNull;
+
import java.util.ArrayList;
import java.util.List;
import io.reactivex.Observable;
+import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import retrofit2.HttpException;
@@ -42,14 +47,16 @@ public abstract class ListViewModel extends Ba
mOverLimitSize = mCurLoadParams.getLoadSize() / 2;
}
+ @SuppressLint("CheckResult")
protected void loadData() {
if (mCurLoadParams == null) initLoadParams();
LoadParams loadParams = mRetryParams != null ? mRetryParams : mCurLoadParams;
Observable> listObservable = provideDataObservable(loadParams.getLoadOffset());
+ Single> listSingle = provideDataSingle(loadParams.getLoadOffset());
LoadStatus curStatus = mLoadStatusLiveData.getValue();
- if (listObservable == null || curStatus != null &&
+ if ((listObservable == null && listSingle == null) || curStatus != null &&
curStatus != LoadStatus.INIT_LOADED &&
curStatus != LoadStatus.LIST_LOADED &&
curStatus != LoadStatus.INIT) return;
@@ -60,43 +67,84 @@ public abstract class ListViewModel extends Ba
mLoadStatusLiveData.setValue(LoadStatus.LIST_LOADING);
}
- listObservable
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(new Response>() {
- @Override
- public void onResponse(List response) {
- List previousData = mListLiveData.getValue();
- if (previousData == null || mCurLoadParams.getLoadOffset() == LoadParams.DEFAULT_OFFSET ||
- curStatus == LoadStatus.INIT) {
- previousData = new ArrayList<>();
+ if (listObservable != null) {
+ listObservable
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(new Response>() {
+ @Override
+ public void onResponse(List response) {
+ List previousData = mListLiveData.getValue();
+ if (previousData == null || mCurLoadParams.getLoadOffset() == LoadParams.DEFAULT_OFFSET ||
+ curStatus == LoadStatus.INIT) {
+ previousData = new ArrayList<>();
+ }
+
+ // 针对游戏的一些操作(过滤隐藏APK,增加下载数据)
+ if (response.size() > 0 && response.get(0) instanceof GameEntity) {
+ for (LD entity : response) {
+ GameEntity game = (GameEntity) entity;
+ game.setEntryMap(DownloadManager.getInstance(HaloApp.getInstance()
+ .getApplication()).getEntryMap(game.getName()));
+ ApkActiveUtils.filterHideApk(game);
+ }
+ }
+
+ previousData.addAll(response);
+ mListLiveData.postValue(previousData);
+ loadStatusControl(response.size());
}
- // 针对游戏的一些操作(过滤隐藏APK,增加下载数据)
- if (response.size() > 0 && response.get(0) instanceof GameEntity) {
- for (LD entity : response) {
- GameEntity game = (GameEntity) entity;
- game.setEntryMap(DownloadManager.getInstance(HaloApp.getInstance()
- .getApplication()).getEntryMap(game.getName()));
- ApkActiveUtils.filterHideApk(game);
+ @Override
+ public void onFailure(HttpException e) {
+ if (e != null && e.code() == 404) {
+ loadStatusControl(0);
+ } else {
+ loadStatusControl(REQUEST_FAILURE_SIZE);
+ mLoadExceptionLiveData.postValue(e);
+ }
+ }
+ });
+ } else if (listSingle != null) {
+ listSingle.subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(new BiResponse>() {
+ @Override
+ public void onFailure(@NotNull Exception exception) {
+ if (exception instanceof HttpException && ((HttpException) exception).code() == 404) {
+ loadStatusControl(0);
+ } else {
+ loadStatusControl(REQUEST_FAILURE_SIZE);
+ if (exception instanceof HttpException) {
+ mLoadExceptionLiveData.postValue((HttpException) exception);
+ }
}
}
- previousData.addAll(response);
- mListLiveData.postValue(previousData);
- loadStatusControl(response.size());
- }
+ @Override
+ public void onSuccess(List response) {
+ List previousData = mListLiveData.getValue();
+ if (previousData == null || mCurLoadParams.getLoadOffset() == LoadParams.DEFAULT_OFFSET ||
+ curStatus == LoadStatus.INIT) {
+ previousData = new ArrayList<>();
+ }
- @Override
- public void onFailure(HttpException e) {
- if (e != null && e.code() == 404) {
- loadStatusControl(0);
- } else {
- loadStatusControl(REQUEST_FAILURE_SIZE);
- mLoadExceptionLiveData.postValue(e);
+ // 针对游戏的一些操作(过滤隐藏APK,增加下载数据)
+ if (response.size() > 0 && response.get(0) instanceof GameEntity) {
+ for (LD entity : response) {
+ GameEntity game = (GameEntity) entity;
+ game.setEntryMap(DownloadManager.getInstance(HaloApp.getInstance()
+ .getApplication()).getEntryMap(game.getName()));
+ ApkActiveUtils.filterHideApk(game);
+ }
+ }
+
+ previousData.addAll(response);
+ mListLiveData.postValue(previousData);
+ loadStatusControl(response.size());
}
- }
- });
+ });
+ }
}
protected void loadStatusControl(int size) {
@@ -147,6 +195,11 @@ public abstract class ListViewModel extends Ba
loadData();
}
+ @Override
+ public Single> provideDataSingle(int page) {
+ return null;
+ }
+
protected abstract void mergeResultLiveData();
public MutableLiveData getLoadExceptionLiveData() {
diff --git a/app/src/main/java/com/gh/gamecenter/baselist/NormalListViewModel.java b/app/src/main/java/com/gh/gamecenter/baselist/NormalListViewModel.java
index 3b5496f713..4b6aa75ef5 100644
--- a/app/src/main/java/com/gh/gamecenter/baselist/NormalListViewModel.java
+++ b/app/src/main/java/com/gh/gamecenter/baselist/NormalListViewModel.java
@@ -8,6 +8,7 @@ import android.support.annotation.NonNull;
import java.util.List;
import io.reactivex.Observable;
+import io.reactivex.Single;
/**
* Created by khy on 21/03/18.
@@ -35,6 +36,11 @@ public class NormalListViewModel extends ListViewModel {
return mDataObservable.provideDataObservable(offset);
}
+ @Override
+ public Single> provideDataSingle(int page) {
+ return mDataObservable.provideDataSingle(page);
+ }
+
public static class Factory extends ViewModelProvider.NewInstanceFactory {
@NonNull
private final Application mApplication;
diff --git a/app/src/main/java/com/gh/gamecenter/baselist/OnDataObservable.java b/app/src/main/java/com/gh/gamecenter/baselist/OnDataObservable.java
index 93a847a888..52ce8a75a0 100644
--- a/app/src/main/java/com/gh/gamecenter/baselist/OnDataObservable.java
+++ b/app/src/main/java/com/gh/gamecenter/baselist/OnDataObservable.java
@@ -3,6 +3,7 @@ package com.gh.gamecenter.baselist;
import java.util.List;
import io.reactivex.Observable;
+import io.reactivex.Single;
/**
@@ -11,4 +12,8 @@ import io.reactivex.Observable;
public interface OnDataObservable {
Observable> provideDataObservable(int page);
+
+ // 一般的网络请求只有成功或失败两种情况,并不会有 onNext 所以主流是使用 single ,
+ // 譬如 room 的 rxjava 支持就只支持 single 不支持 observable 所以这里增加了个 single 来供那些既兼容网络数据又兼容 room 数据的页面
+ Single> provideDataSingle(int page);
}
diff --git a/app/src/main/java/com/gh/gamecenter/collection/AnswerFragment.java b/app/src/main/java/com/gh/gamecenter/collection/AnswerFragment.java
index ca1e243025..c51637c948 100644
--- a/app/src/main/java/com/gh/gamecenter/collection/AnswerFragment.java
+++ b/app/src/main/java/com/gh/gamecenter/collection/AnswerFragment.java
@@ -2,6 +2,7 @@ package com.gh.gamecenter.collection;
import android.view.View;
+import com.gh.common.history.HistoryDatabase;
import com.gh.common.util.CollectionUtils;
import com.gh.common.util.DialogUtils;
import com.gh.gamecenter.R;
@@ -22,7 +23,7 @@ import org.greenrobot.eventbus.ThreadMode;
import java.util.List;
-import io.reactivex.Observable;
+import io.reactivex.Single;
/**
* Created by khy on 22/12/17.
@@ -31,6 +32,13 @@ import io.reactivex.Observable;
public class AnswerFragment extends ListFragment {
private AnswerAdapter mAdapter;
+ private Type mType;
+
+ public static AnswerFragment getInstance(Type type) {
+ AnswerFragment fragment = new AnswerFragment();
+ fragment.mType = type;
+ return fragment;
+ }
@Override
protected ListAdapter provideListAdapter() {
@@ -38,8 +46,12 @@ public class AnswerFragment extends ListFragment> provideDataObservable(int page) {
- return RetrofitManager.getInstance(getContext()).getApi().getCollectionAnswer(UserManager.getInstance().getUserId(), page);
+ public Single> provideDataSingle(int page) {
+ if (mType == Type.COLLECTION) {
+ return Single.fromObservable(RetrofitManager.getInstance(getContext()).getApi().getCollectionAnswer(UserManager.getInstance().getUserId(), page));
+ } else {
+ return HistoryDatabase.Companion.getInstance().answerDao().getAnswersWithOffset(20, (page - 1) * 20);
+ }
}
@Override
@@ -95,4 +107,10 @@ public class AnswerFragment extends ListFragment fragments) {
- fragments.add(new AnswerFragment());
+ fragments.add(AnswerFragment.getInstance(AnswerFragment.Type.COLLECTION));
fragments.add(new CommunityArticleFragment());
fragments.add(new ToolsFragment());
fragments.add(new ArticleFragment());
diff --git a/app/src/main/java/com/gh/gamecenter/history/HistoryActivity.kt b/app/src/main/java/com/gh/gamecenter/history/HistoryActivity.kt
new file mode 100644
index 0000000000..ba2b90d0b6
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/history/HistoryActivity.kt
@@ -0,0 +1,20 @@
+package com.gh.gamecenter.history
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import com.gh.common.util.EntranceUtils
+import com.gh.gamecenter.NormalActivity
+
+class HistoryActivity: NormalActivity() {
+
+ companion object {
+ @JvmStatic
+ fun getHistoryIntent(context: Context, entrance: String): Intent {
+ val bundle = Bundle()
+ bundle.putString(EntranceUtils.KEY_ENTRANCE, entrance)
+ return NormalActivity.getTargetIntent(context, HistoryActivity::class.java, HistoryWrapperFragment::class.java, bundle)
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/history/HistoryWrapperFragment.kt b/app/src/main/java/com/gh/gamecenter/history/HistoryWrapperFragment.kt
new file mode 100644
index 0000000000..05153a9382
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/history/HistoryWrapperFragment.kt
@@ -0,0 +1,47 @@
+package com.gh.gamecenter.history
+
+import android.os.Bundle
+import android.support.v4.app.Fragment
+import com.gh.base.fragment.BaseFragment_TabLayout
+import com.gh.gamecenter.R
+import com.gh.gamecenter.collection.*
+
+class HistoryWrapperFragment: BaseFragment_TabLayout() {
+
+ fun newInstance(checkedIndex: Int): CollectionWrapperFragment {
+ val fragment = CollectionWrapperFragment()
+ val args = Bundle(1)
+ args.putInt(BaseFragment_TabLayout.PAGE_INDEX, checkedIndex)
+ fragment.arguments = args
+ return fragment
+ }
+
+ override fun initTabTitleList(tabTitleList: MutableList) {
+ tabTitleList.add(getString(R.string.answer))
+ tabTitleList.add(getString(R.string.collection_article))
+ tabTitleList.add(getString(R.string.collection_info))
+ tabTitleList.add(getString(R.string.collection_toolkit))
+ }
+
+ override fun initFragmentList(fragments: MutableList) {
+ fragments.add(AnswerFragment.getInstance(AnswerFragment.Type.HISTORY))
+ fragments.add(CommunityArticleFragment())
+ fragments.add(ArticleFragment())
+ fragments.add(ToolsFragment())
+ for (fragment in mFragmentsList) {
+ fragment.arguments = arguments
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setNavigationTitle("浏览记录")
+ }
+
+ companion object {
+ const val INDEX_ANSWER = 0
+ const val INDEX_ARTICLE = 1
+ const val INDEX_NEWS = 2
+ const val INDEX_GAME = 3
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.java b/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.java
index ae165f9c37..98f8e45619 100644
--- a/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.java
+++ b/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.java
@@ -48,6 +48,7 @@ import com.gh.gamecenter.eventbus.EBConcernChanged;
import com.gh.gamecenter.eventbus.EBNetworkState;
import com.gh.gamecenter.eventbus.EBReuse;
import com.gh.gamecenter.eventbus.EBSkip;
+import com.gh.gamecenter.history.HistoryActivity;
import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.message.MessageUnreadRepository;
import com.gh.gamecenter.message.MessageUnreadViewModel;
@@ -293,8 +294,8 @@ public class PersonalFragment extends BaseFragment implements Observer? = null
private val mAnswersImgs: ArrayList? = arrayListOf()
@@ -146,9 +148,10 @@ class AnswerDetailFragment : NormalFragment() {
private var mElapsedHelper: TimeElapsedHelper? = null
private var mDetailEntity: AnswerDetailEntity? = null
private var mCollectMenuItem: MenuItem? = null
- private lateinit var mViewModel: AnswerDetailViewModel
private lateinit var mBinding: FragmentAnswerDetailBinding
+ private lateinit var mViewModel: AnswerDetailViewModel
+
private var mSpecialColumn: SpecialColumn? = null
private var mRefreshHeader: AnswerDetailRefreshHeader? = null
@@ -178,6 +181,8 @@ class AnswerDetailFragment : NormalFragment() {
mRichEditor.setInputEnabled(false)
mRichEditor.setPadding(20, 15, 20, 15)
+
+ // TODO 应该只对显示在屏幕上的 fragment 计时
mElapsedHelper = TimeElapsedHelper(this)
initDrag()
@@ -195,8 +200,6 @@ class AnswerDetailFragment : NormalFragment() {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setNavigationTitle(getString(R.string.answer_detail_title))
- (requireActivity() as BaseToolBarActivity).clearMenu()
- initMenu(R.menu.menu_answer)
}
override fun onStart() {
@@ -215,6 +218,17 @@ class AnswerDetailFragment : NormalFragment() {
}
}
+ override fun setUserVisibleHint(isVisibleToUser: Boolean) {
+ super.setUserVisibleHint(isVisibleToUser)
+ mIsVisibleToUser = isVisibleToUser
+ if (!isVisibleToUser && isResumed) {
+ mElapsedHelper?.pauseCounting()
+ updateMenu()
+ } else if (isVisibleToUser && isResumed) {
+ mElapsedHelper?.resumeCounting()
+ }
+ }
+
override fun onDestroyView() {
super.onDestroyView()
if (mDetailEntity != null) {
@@ -269,13 +283,14 @@ class AnswerDetailFragment : NormalFragment() {
mContainerViewModel.appendAnswer(nextAnswerId)
}
- updateDragAbility()
+ updateAnswerStatus()
updateDragHintAndListener()
- GdtHelper.logAction(ActionType.PAGE_VIEW, GdtHelper.CONTENT_TYPE, "ANSWER", GdtHelper.CONTENT_ID, mAnswerId)
-
mBinding.detail = mDetailEntity
updateView()
+ updateMenu()
+
+ GdtHelper.logAction(ActionType.PAGE_VIEW, GdtHelper.CONTENT_TYPE, "ANSWER", GdtHelper.CONTENT_ID, mAnswerId)
// 没点赞过,作者不是自己,正文长度不少于20个字。 开启停留一定时长(字数/10 + 5)秒)后的动画
if (!mDetailEntity!!.me.isAnswerOwn && !mDetailEntity!!.me.isAnswerVoted) {
@@ -318,7 +333,7 @@ class AnswerDetailFragment : NormalFragment() {
mBottomContainer.visibility = View.GONE
}
- if (activity is NormalActivity) {
+ if (activity is NormalActivity && mIsVisibleToUser) {
val menu = (activity as NormalActivity).menu
if (menu != null) {
for (i in 0 until menu.size()) {
@@ -432,6 +447,19 @@ class AnswerDetailFragment : NormalFragment() {
}
}
+ // 更新回答状态
+ private fun updateAnswerStatus() {
+ mAnswerStatus = if (!TextUtils.isEmpty(mDetailEntity!!.me.myAnswerId)) {
+ if (mDetailEntity!!.me.isAnswerOwn) {
+ ANSWERED_MY_ANSWER
+ } else {
+ ANSWERED_NOT_MY_ANSWER
+ }
+ } else {
+ NOT_ANSWERED_YET
+ }
+ }
+
private fun toggleComment(enable: Boolean) {
if (enable) {
mAnswerCommentCountTv.text = String.format("%d 评论", mDetailEntity!!.commentCount)
@@ -453,11 +481,11 @@ class AnswerDetailFragment : NormalFragment() {
mRefreshLayout.setEnableAutoLoadMore(false)
updateDragHintAndListener()
-
- updateDragAbility()
}
private fun updateDragHintAndListener() {
+ showDragHintDialog()
+
if (mContainerViewModel.answerIdList.first() == mAnswerId) {
mRefreshHeader?.REFRESH_HEADER_PULLING = "不能向上翻页了"
mRefreshHeader?.REFRESH_HEADER_RELEASE = "不能向上翻页了"
@@ -477,8 +505,9 @@ class AnswerDetailFragment : NormalFragment() {
if (UserManager.getInstance().isLoggedIn
&& mDetailEntity != null
&& mAnswerStatus == NOT_ANSWERED_YET) {
- mRefreshFooter?.REFRESH_FOOTER_PULLING = "我来回答"
- mRefreshFooter?.REFRESH_FOOTER_RELEASE = "我来回答"
+ mRefreshFooter?.REFRESH_FOOTER_PULLING = "没有更多内容了,上拉我来回答"
+ mRefreshFooter?.REFRESH_FOOTER_RELEASE = "没有更多内容了,松开我来回答"
+ mRefreshFooter?.restoreArrow()
mRefreshLayout.setOnLoadMoreListener {
mRefreshLayout.finishLoadMore(0)
val question = mDetailEntity!!.question
@@ -512,10 +541,13 @@ class AnswerDetailFragment : NormalFragment() {
mSpecialColumn)
}
+ HistoryHelper.insertAnswerEntity(mDetailEntity!!)
+
mElapsedHelper?.resetCounting()
}
// 开启超时统计(显示点赞动画)
+ // TODO 避免内存泄漏
private fun startTimeElapsedCount(timeout: Int) {
mElapsedHelper?.timeout = timeout
mElapsedHelper?.timeoutCallback = object : TimeoutCallback {
@@ -609,7 +641,7 @@ class AnswerDetailFragment : NormalFragment() {
R.id.menu_collect -> {
if (mDetailEntity == null) return
- CheckLoginUtils.checkLogin(context, "回答详情-收藏") {
+ ifLogin("回答详情-收藏") {
if (!mDetailEntity!!.me.isAnswerFavorite) {
CollectionUtils.postCollection(context!!, mAnswerId!!, CollectionUtils.CollectionType.answer, object : CollectionUtils.OnCollectionListener {
override fun onSuccess() {
@@ -765,7 +797,7 @@ class AnswerDetailFragment : NormalFragment() {
startActivity(QuestionsDetailActivity.getIntent(context, mDetailEntity!!.question.id, mEntrance, "回答详情"))
}
- R.id.answer_detail_like_container -> CheckLoginUtils.checkLogin(context, "回答详情-赞同") {
+ R.id.answer_detail_like_container -> ifLogin("回答详情-赞同") {
if (mDetailEntity != null && !mDetailEntity!!.me.isAnswerVoted) {
mViewModel.postVote(mAnswerId!!)
@@ -805,7 +837,7 @@ class AnswerDetailFragment : NormalFragment() {
ANSWERED_NOT_MY_ANSWER -> {
startActivityForResult(AnswerDetailActivity.getIntent(context, mDetailEntity!!.me.myAnswerId, mEntrance, "答案详情"), ANSWER_PATCH_REQUEST)
}
- NOT_ANSWERED_YET -> CheckLoginUtils.checkLogin(context, "回答详情-[我来回答]") {
+ NOT_ANSWERED_YET -> ifLogin("回答详情-[我来回答]") {
val question = mDetailEntity!!.question
startActivity(AnswerEditActivity.getIntent(context!!, question.id, question.title, true, question.communityName))
}
@@ -817,7 +849,7 @@ class AnswerDetailFragment : NormalFragment() {
R.id.answer_detail_username -> PersonalHomeActivity.startTargetActivity(context!!, mDetailEntity!!.user.id, mEntrance, "回答详情")
R.id.answer_detail_follow -> {
- CheckLoginUtils.checkLogin(context, "回答详情-[关注]用户") {
+ ifLogin("回答详情-[关注]用户") {
if (mBinding.answerDetailFollow.text == "关注") {
mViewModel.follow(mDetailEntity!!.user.id!!)
}
@@ -861,14 +893,6 @@ class AnswerDetailFragment : NormalFragment() {
@SuppressLint("DefaultLocale")
private fun updateView() {
- mCollectMenuItem = getItemMenu(R.id.menu_collect)
-
- if (mDetailEntity!!.me.isAnswerFavorite) {
- mCollectMenuItem!!.setIcon(R.drawable.menu_ic_collect_select)
- } else {
- mCollectMenuItem!!.setIcon(R.drawable.menu_ic_collect_unselect)
- }
-
val user = mDetailEntity?.user
if (user != null) {
ImageUtils.displayIcon(mUsericon, user.icon)
@@ -909,23 +933,22 @@ class AnswerDetailFragment : NormalFragment() {
}
// 是否已回答
- if (!TextUtils.isEmpty(mDetailEntity!!.me.myAnswerId)) {
- if (mDetailEntity!!.me.isAnswerOwn) {
- mAnswerStatus = ANSWERED_MY_ANSWER
+ when (mAnswerStatus) {
+ ANSWERED_MY_ANSWER -> {
mAnswerStatusTv.text = "编辑回答"
mAnswerStatusTv.setTextColor(resources.getColor(R.color.title))
mAnswerStatusIv.setImageResource(R.drawable.questionsdetail_myanswer_icon)
- } else {
- mAnswerStatus = ANSWERED_NOT_MY_ANSWER
+ }
+ ANSWERED_NOT_MY_ANSWER -> {
mAnswerStatusTv.text = "我的回答"
mAnswerStatusTv.setTextColor(resources.getColor(R.color.theme))
mAnswerStatusIv.setImageResource(R.drawable.ic_answer_detail_edit_full)
}
- } else {
- mAnswerStatus = NOT_ANSWERED_YET
- mAnswerStatusTv.text = "我来回答"
- mAnswerStatusTv.setTextColor(resources.getColor(R.color.theme))
- mAnswerStatusIv.setImageResource(R.drawable.ic_answer_detail_edit_empty)
+ NOT_ANSWERED_YET -> {
+ mAnswerStatusTv.text = "我来回答"
+ mAnswerStatusTv.setTextColor(resources.getColor(R.color.theme))
+ mAnswerStatusIv.setImageResource(R.drawable.ic_answer_detail_edit_empty)
+ }
}
if (mDetailEntity!!.publishTime == mDetailEntity!!.updateTime) {
@@ -983,6 +1006,28 @@ class AnswerDetailFragment : NormalFragment() {
updateVote()
}
+ private fun updateMenu() {
+ if (isFragmentVisible()) {
+// (requireActivity() as BaseToolBarActivity).clearMenu()
+
+ initMenu(R.menu.menu_answer)
+
+ mCollectMenuItem = getItemMenu(R.id.menu_collect)
+
+ mDetailEntity?.let {
+ if (it.me.isAnswerFavorite) {
+ mCollectMenuItem?.setIcon(R.drawable.menu_ic_collect_select)
+ } else {
+ mCollectMenuItem?.setIcon(R.drawable.menu_ic_collect_unselect)
+ }
+ }
+ }
+ }
+
+ private fun isFragmentVisible(): Boolean {
+ return isResumed && mIsVisibleToUser
+ }
+
private fun updateFollowBtn(isFollowed: Boolean) {
if (isFollowed) {
if (mBinding.answerDetailFollow.visibility == View.GONE) return
@@ -1022,14 +1067,7 @@ class AnswerDetailFragment : NormalFragment() {
}
}
- /**
- * 更新上下可拖动切换答案的能力
- */
- private fun updateDragAbility() {
- showHintDialog()
- }
-
- private fun showHintDialog() {
+ private fun showDragHintDialog() {
val hasShownDragHint = SPUtils.getBoolean(SHOWN_DRAG_HINT, false)
if (hasShownDragHint) {
return
@@ -1110,11 +1148,6 @@ class AnswerDetailFragment : NormalFragment() {
}
}
- interface CommentListener {
- fun onCountChange(count: Int)
- fun onCommentDraftChange(draft: String)
- }
-
// 登录事件
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(reuse: EBReuse) {
@@ -1123,6 +1156,11 @@ class AnswerDetailFragment : NormalFragment() {
}
}
+ interface CommentListener {
+ fun onCountChange(count: Int)
+ fun onCommentDraftChange(draft: String)
+ }
+
companion object {
private const val ANSWER_STATUS_UNKNOWN = 0
private const val ANSWERED_MY_ANSWER = 1
diff --git a/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailRefreshFooter.java b/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailRefreshFooter.java
index fbff3efc47..0e7175bbe2 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailRefreshFooter.java
+++ b/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailRefreshFooter.java
@@ -145,6 +145,12 @@ public class AnswerDetailRefreshFooter extends InternalClassics>
+
+}
diff --git a/app/src/main/res/layout/fragment_personal.xml b/app/src/main/res/layout/fragment_personal.xml
index 3e9e7d520e..8e5e2c396c 100644
--- a/app/src/main/res/layout/fragment_personal.xml
+++ b/app/src/main/res/layout/fragment_personal.xml
@@ -334,9 +334,8 @@
-
@@ -394,7 +393,7 @@
+
+
+
+
+
+
+
+
+
这里还没有东西哦
推荐关注
关注
+ 浏览记录
分享
礼包中心
反馈