将 ListViewModel 所对应的 ListRepository 合并到 ListViewModel 中,BaseList重新整理分层结构

This commit is contained in:
kehaoyuan
2018-07-18 17:32:51 +08:00
parent c5d79a014b
commit 37bca1ee1c
22 changed files with 904 additions and 43 deletions

View File

@ -2,10 +2,7 @@ package com.gh.gamecenter;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.gh.common.util.DataUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.gamecenter.subject.SubjectWrapperFragment;
@ -23,18 +20,16 @@ public class SubjectActivity extends NormalActivity {
* 启动专题页面
*/
public static void startSubjectActivity(Context context, String id, String name, boolean isOrder, String entrance) {
DataUtils.onMtaEvent(context, "详情页面", "专题详情", name);
Bundle args = new Bundle();
args.putString(EntranceUtils.KEY_ID, id);
args.putString(EntranceUtils.KEY_NAME, name);
args.putBoolean(EntranceUtils.KEY_ORDER, isOrder);
args.putString(EntranceUtils.KEY_ENTRANCE, entrance);
// DataUtils.onMtaEvent(context, "详情页面", "专题详情", name);
// Bundle args = new Bundle();
// args.putString(EntranceUtils.KEY_ID, id);
// args.putString(EntranceUtils.KEY_NAME, name);
// args.putBoolean(EntranceUtils.KEY_ORDER, isOrder);
// args.putString(EntranceUtils.KEY_ENTRANCE, entrance);
//
// context.startActivity(getTargetIntent(context, SubjectActivity.class, SubjectWrapperFragment.class, args));
// new IntentFactory.Builder(context)
// .setArgs(args)
// .setActivity(SubjectActivity.class)
// .setFragment(SubjectWrapperFragment.class).start();
context.startActivity(getTargetIntent(context, SubjectActivity.class, SubjectWrapperFragment.class, args));
com.gh.gamecenter.subject.refactor.SubjectActivity.Companion.startSubjectActivity(context, id,name,isOrder,entrance);
}
}

View File

@ -4,7 +4,11 @@ import android.app.Application;
import android.arch.lifecycle.MutableLiveData;
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.Response;
import com.halo.assistant.HaloApp;
import java.util.ArrayList;
import java.util.List;
@ -63,6 +67,17 @@ public abstract class ListViewModel<LD /*ListData*/, ID /*ItemData*/> extends Ba
if (previousData == null || 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);
}

View File

@ -32,9 +32,9 @@ class CategoryListTabFragment : BaseFragment<String>(), SubjectTypeAdapter.OnSel
lateinit var mSubjectRv: RecyclerView
@BindView(R.id.subject_appbar)
lateinit var mAppbar: AppBarLayout
@BindView(R.id.subject_tabbar_hot_tv)
@BindView(R.id.subject_tabbar_hottest)
lateinit var mTabbarHotTv: TextView
@BindView(R.id.subject_tabbar_new_tv)
@BindView(R.id.subject_tabbar_newest)
lateinit var mTabbarNewTv: TextView
val OPEN_APPBAR = "openAppBar"
@ -160,10 +160,10 @@ class CategoryListTabFragment : BaseFragment<String>(), SubjectTypeAdapter.OnSel
loadData()
}
@OnClick(R.id.subject_tabbar_hot_tv, R.id.subject_tabbar_new_tv)
@OnClick(R.id.subject_tabbar_hottest, R.id.subject_tabbar_newest)
override fun onClick(view: View) {
when (view.id) {
R.id.subject_tabbar_hot_tv -> {
R.id.subject_tabbar_hottest -> {
mTabbarHotTv.setTextColor(Color.WHITE)
mTabbarHotTv.setBackgroundResource(R.drawable.tabbar_left_bg)
mTabbarNewTv.setTextColor(Color.BLACK)
@ -171,7 +171,7 @@ class CategoryListTabFragment : BaseFragment<String>(), SubjectTypeAdapter.OnSel
mListOrder = "download:-1"
loadData()
}
R.id.subject_tabbar_new_tv -> {
R.id.subject_tabbar_newest -> {
mTabbarHotTv.setTextColor(Color.BLACK)
mTabbarHotTv.setBackgroundDrawable(ColorDrawable(0))
mTabbarNewTv.setTextColor(Color.WHITE)

View File

@ -0,0 +1,13 @@
package com.gh.gamecenter.entity
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
@Parcelize
data class SubjectData(var subjectId: String?,
var subjectName: String?,
var isOrder: Boolean?,
var listOrder: String?,
var tagType: String?,
var mTileType: String?,
var typeList: List<String>?) : Parcelable

View File

@ -6,16 +6,16 @@ import com.google.gson.annotations.SerializedName
* Created by khy on 28/05/17.
*/
class SubjectHeadEntity {
class SubjectSettingEntity {
@SerializedName("type")
var typeEntity: TypeEntity? = null
var typeEntity: TypeEntity = TypeEntity()
var tag: String? = null
inner class TypeEntity {
var content: List<String>? = null
var content: MutableList<String> = ArrayList()
var layout: String? = null
}

View File

@ -44,7 +44,7 @@ public class HtmlUriHandler implements KcUriHandler {
}
homeHtml = baos.toString("UTF-8");
} catch (IOException e) {
} catch (Exception e) {
Utils.log("===加载asset HTML文件异常" + e.toString());
e.printStackTrace();
}

View File

@ -23,7 +23,7 @@ import com.gh.gamecenter.entity.SettingsEntity;
import com.gh.gamecenter.entity.SignEntity;
import com.gh.gamecenter.entity.SlideEntity;
import com.gh.gamecenter.entity.SubjectEntity;
import com.gh.gamecenter.entity.SubjectHeadEntity;
import com.gh.gamecenter.entity.SubjectSettingEntity;
import com.gh.gamecenter.entity.SubjectRecommendEntity;
import com.gh.gamecenter.entity.TagEntity;
import com.gh.gamecenter.entity.ToolBoxEntity;
@ -236,7 +236,7 @@ public interface ApiService {
* 获取专题数据标题
*/
@GET("columns/{column_id}/setting")
Observable<SubjectHeadEntity> getColumnSettings(@Path("column_id") String column_id);
Observable<SubjectSettingEntity> getColumnSettings(@Path("column_id") String column_id);
// /**
// * 获取界面设置参数

View File

@ -41,9 +41,9 @@ public class SubjectTileFragment extends BaseFragment implements SubjectTypeAdap
RecyclerView mSubjectRv;
@BindView(R.id.subject_appbar)
AppBarLayout mAppbar;
@BindView(R.id.subject_tabbar_hot_tv)
@BindView(R.id.subject_tabbar_hottest)
TextView mTabbarHotTv;
@BindView(R.id.subject_tabbar_new_tv)
@BindView(R.id.subject_tabbar_newest)
TextView mTabbarNewTv;
public final static String OPEN_APPBAR = "openAppBar";
@ -160,10 +160,10 @@ public class SubjectTileFragment extends BaseFragment implements SubjectTypeAdap
loadData();
}
@OnClick({R.id.subject_tabbar_hot_tv, R.id.subject_tabbar_new_tv})
@OnClick({R.id.subject_tabbar_hottest, R.id.subject_tabbar_newest})
public void onClick(View view) {
switch (view.getId()) {
case R.id.subject_tabbar_hot_tv:
case R.id.subject_tabbar_hottest:
mTabbarHotTv.setTextColor(Color.WHITE);
mTabbarHotTv.setBackgroundResource(R.drawable.tabbar_left_bg);
mTabbarNewTv.setTextColor(Color.BLACK);
@ -171,7 +171,7 @@ public class SubjectTileFragment extends BaseFragment implements SubjectTypeAdap
mListOrder = "";
loadData();
break;
case R.id.subject_tabbar_new_tv:
case R.id.subject_tabbar_newest:
mTabbarHotTv.setTextColor(Color.BLACK);
mTabbarHotTv.setBackgroundDrawable(new ColorDrawable(0));
mTabbarNewTv.setTextColor(Color.WHITE);

View File

@ -13,7 +13,7 @@ import android.widget.LinearLayout;
import com.gh.common.constant.Config;
import com.gh.common.util.EntranceUtils;
import com.gh.gamecenter.R;
import com.gh.gamecenter.entity.SubjectHeadEntity;
import com.gh.gamecenter.entity.SubjectSettingEntity;
import com.gh.gamecenter.normal.NormalFragment;
import com.gh.gamecenter.retrofit.JSONObjectResponse;
import com.gh.gamecenter.retrofit.Response;
@ -124,9 +124,9 @@ public class SubjectWrapperFragment extends NormalFragment {
.getColumnSettings(mId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<SubjectHeadEntity>() {
.subscribe(new Response<SubjectSettingEntity>() {
@Override
public void onResponse(SubjectHeadEntity response) {
public void onResponse(SubjectSettingEntity response) {
super.onResponse(response);
mLoading.setVisibility(View.GONE);
List<String> content = response.getTypeEntity().getContent();
@ -143,8 +143,8 @@ public class SubjectWrapperFragment extends NormalFragment {
});
}
private void initView(SubjectHeadEntity headEntity) {
SubjectHeadEntity.TypeEntity typeEntity = headEntity.getTypeEntity();
private void initView(SubjectSettingEntity headEntity) {
SubjectSettingEntity.TypeEntity typeEntity = headEntity.getTypeEntity();
if (typeEntity == null) {
return;
}

View File

@ -0,0 +1,86 @@
package com.gh.gamecenter.subject.refactor
import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.View
import com.gh.base.BaseActivity
import com.gh.common.util.DataUtils
import com.gh.common.util.EntranceUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.SubjectData
import com.gh.gamecenter.entity.SubjectSettingEntity
import com.gh.gamecenter.subject.refactor.tab.SubjectTabFragment
import com.gh.gamecenter.subject.refactor.tile.SubjectTileFragment
import com.halo.assistant.HaloApp
import kotterknife.bindView
class SubjectActivity : BaseActivity() {
private val mLoading by bindView<View>(R.id.list_loading)
private val mNoConn by bindView<View>(R.id.list_loading)
private var mViewModel: SubjectViewModel? = null
override fun getLayoutId(): Int {
return R.layout.activity_subject
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val factory = SubjectViewModel.Factory(HaloApp.getInstance().application, intent.getParcelableExtra(EntranceUtils.KEY_SUBJECT_DATA))
mViewModel = ViewModelProviders.of(this, factory).get(SubjectViewModel::class.java)
mViewModel?.subjectSettingLD?.observe(this, Observer {
mLoading.visibility = View.GONE
if (it == null) {
mNoConn.visibility = View.VISIBLE
} else {
initContentView(it)
}
})
mViewModel?.subjectNameLD?.observe(this, Observer {
setNavigationTitle(it)
})
mNoConn.setOnClickListener({
mLoading.visibility = View.VISIBLE
mViewModel?.initData()
})
}
private fun initContentView(entity: SubjectSettingEntity) {
val transaction = supportFragmentManager.beginTransaction()
val fragment: Fragment = if ("tile" == entity.typeEntity.layout) {
SubjectTileFragment()
} else {
SubjectTabFragment()
}
val bundle = Bundle()
bundle.putParcelable(EntranceUtils.KEY_SUBJECT_DATA, mViewModel?.subjectData)
fragment.arguments = bundle
transaction.replace(R.id.subject_content, fragment)
transaction.commitAllowingStateLoss()
}
companion object {
/**
* 启动专题页面
*/
fun startSubjectActivity(context: Context, id: String?, name: String?, isOrder: Boolean, entrance: String?) {
DataUtils.onMtaEvent(context, "详情页面", "专题详情", name)
val intent = Intent(context, SubjectActivity::class.java)
intent.putExtra(EntranceUtils.KEY_SUBJECT_DATA, SubjectData(id, name, isOrder, null, null, null, null))
intent.putExtra(EntranceUtils.KEY_ENTRANCE, entrance)
context.startActivity(intent)
}
}
}

View File

@ -0,0 +1,190 @@
package com.gh.gamecenter.subject.refactor
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.text.TextUtils
import android.util.SparseArray
import android.view.View
import android.view.ViewGroup
import com.gh.common.constant.ItemViewType
import com.gh.common.exposure.ExposureEvent
import com.gh.common.exposure.ExposureSource
import com.gh.common.exposure.ExposureType
import com.gh.common.exposure.IExposable
import com.gh.common.util.*
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.NewsDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.SubjectActivity
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
import com.gh.gamecenter.adapter.viewholder.GameImageViewHolder
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
import com.gh.gamecenter.baselist.ListAdapter
import com.gh.gamecenter.databinding.GameItemBinding
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.SubjectData
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.game.GameItemViewHolder
import com.lightgame.download.DownloadEntity
import java.util.*
class SubjectAdapter(context: Context,
private val subjectData: SubjectData,
private val mEntrance: String?) : ListAdapter<GameEntity>(context), IExposable {
private val mExposureEventSparseArray: SparseArray<ExposureEvent> = SparseArray()
private val positionAndPackageMap = HashMap<String, Int>()
override fun setListData(updateData: MutableList<GameEntity>?) {
if (updateData != null) {
for (i in 0 until updateData.size) {
var packages = ""
for (apkEntity in updateData[i].getApk()) {
packages += apkEntity.packageName
}
positionAndPackageMap[packages + i] = i
}
}
super.setListData(updateData)
}
override fun areItemsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean {
return oldItem?.id == newItem?.id
}
override fun getItemViewType(position: Int): Int {
if (position == itemCount - 1) {
return ItemViewType.ITEM_FOOTER
}
if (position == 0 && mEntityList != null && mEntityList.size > 0
&& !TextUtils.isEmpty(mEntityList[0].image)) {
return ItemViewType.GAME_IMAGE
}
return ItemViewType.GAME_NORMAL
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
ItemViewType.GAME_NORMAL -> {
GameItemViewHolder(GameItemBinding.bind(mLayoutInflater.inflate(R.layout.game_item, parent, false)))
}
ItemViewType.GAME_IMAGE -> {
GameImageViewHolder(mLayoutInflater.inflate(R.layout.game_image_item, parent, false))
}
else -> {
FooterViewHolder(mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false))
}
}
}
override fun getItemCount(): Int {
return if (mEntityList == null || mEntityList.isEmpty()) return 0 else mEntityList.size + 1
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is GameItemViewHolder) {
val gameEntity = mEntityList[position]
holder.binding.game = gameEntity
holder.binding.subjectTag = subjectData.tagType
holder.initServerType(gameEntity, mContext)
holder.binding.executePendingBindings()
if (subjectData.isOrder!!) {
var index = 1
if (!TextUtils.isEmpty(mEntityList[0].image)) index = 0
holder.binding.gameOrder.visibility = View.VISIBLE
holder.binding.gameOrder.text = (position + index).toString()
} else {
holder.binding.gameOrder.visibility = View.GONE
}
val exposureSources = ArrayList<ExposureSource>()
exposureSources.add(ExposureSource("专题", subjectData.subjectName.toString()))
exposureSources.add(ExposureSource("专题详情", subjectData.mTileType + "+" +
if ("-1" == subjectData.listOrder) "最新" else "最热"))
gameEntity.sequence = position + 1
val event = ExposureEvent.createEvent(gameEntity, exposureSources, null, ExposureType.EXPOSURE)
mExposureEventSparseArray.put(position, event)
holder.itemView.setOnClickListener { v ->
DataCollectionUtils.uploadClick(mContext, "列表", subjectData.subjectName, gameEntity.name)
GameDetailActivity.startGameDetailActivity(mContext, gameEntity,
StringUtils.buildString(mEntrance,
"+(", subjectData.subjectName, ":列表[", subjectData.mTileType, "=",
if ("-1" == subjectData.listOrder) "最新"
else "最热", "=", (position + 1).toString(), "])"), event)
}
DownloadItemUtils.setOnClickListener(mContext, holder.binding.downloadBtn,
gameEntity, position, this,
StringUtils.buildString(mEntrance, "+(", subjectData.subjectName,
":列表[", subjectData.mTileType, "=",
if ("-1" == subjectData.subjectName) "最新"
else "最热", "=", (position + 1).toString(), "])"),
StringUtils.buildString(subjectData.subjectName, ":", gameEntity.name), event)
DownloadItemUtils.updateItem(mContext, gameEntity, GameViewHolder(holder.binding), true)
} else if (holder is GameImageViewHolder) {
holder.line.visibility = View.GONE
val widthPixels = mContext.resources.displayMetrics.widthPixels
val gameEntity = mEntityList[position]
ImageUtils.getInstance().display(holder.image, gameEntity.image, widthPixels)
if (!TextUtils.isEmpty(gameEntity.des)) {
holder.gameDes.visibility = View.VISIBLE
holder.gameDes.text = gameEntity.des
}
holder.itemView.setOnClickListener {
DataCollectionUtils.uploadClick(mContext, "头图", subjectData.subjectName)
when (gameEntity.type) {
"game" -> GameDetailActivity.startGameDetailActivity(mContext, gameEntity.link,
mEntrance + "(" + subjectData.subjectName + ":大图)")
"news" -> {
// 统计阅读量
NewsUtils.statNewsViews(mContext, gameEntity.link)
val intent = NewsDetailActivity.getIntentById(mContext, gameEntity.link,
mEntrance + "(" + subjectData.subjectName + ":大图)")
mContext.startActivity(intent)
}
"column" -> SubjectActivity.startSubjectActivity(mContext, gameEntity.link
, gameEntity.name, false, mEntrance + "(" + subjectData.subjectName + ":大图)")
}
}
} else if (holder is FooterViewHolder) {
holder.initItemPadding()
holder.initFooterViewHolder(mIsLoading, mIsNetworkError, mIsOver, R.string.ask_loadover_hint)
}
}
override fun getEventByPosition(pos: Int): ExposureEvent? {
return mExposureEventSparseArray.get(pos)
}
override fun getEventListByPosition(pos: Int): List<ExposureEvent>? {
return null
}
fun notifyItemByDownload(download: DownloadEntity) {
for (key in positionAndPackageMap.keys) {
if (key.contains(download.packageName)) {
val position = positionAndPackageMap[key]
if (position != null) {
mEntityList[position].getEntryMap()[download.platform] = download
notifyItemChanged(position)
}
}
}
}
fun notifyItemAndRemoveDownload(status: EBDownloadStatus) {
for (key in positionAndPackageMap.keys) {
if (key.contains(status.packageName)) {
val position = positionAndPackageMap[key]
if (position != null) {
mEntityList[position].getEntryMap().remove(status.platform)
notifyItemChanged(position)
}
}
}
}
}

View File

@ -0,0 +1,106 @@
package com.gh.gamecenter.subject.refactor
import android.arch.lifecycle.ViewModelProviders
import android.os.Bundle
import android.support.v7.widget.RecyclerView
import android.view.View
import com.gh.common.util.EntranceUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.baselist.ListFragment
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.eventbus.EBReuse
import com.gh.gamecenter.subject.SubjectTileFragment
import com.halo.assistant.HaloApp
import com.lightgame.OnTitleClickListener
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
class SubjectListFragment : ListFragment<GameEntity, SubjectListViewModel>(), OnTitleClickListener {
private var mAdapter: SubjectAdapter? = null
private var mScrollTop = false
private val dataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
mAdapter?.notifyItemByDownload(downloadEntity)
}
}
override fun provideListAdapter(): SubjectAdapter {
if (mAdapter == null) {
mAdapter = SubjectAdapter(context!!,
arguments?.getParcelable(EntranceUtils.KEY_SUBJECT_DATA)!!,
arguments?.getString(EntranceUtils.KEY_ENTRANCE))
}
return mAdapter as SubjectAdapter
}
override fun provideListViewModel(): SubjectListViewModel {
val factory = SubjectListViewModel.Factory(HaloApp.getInstance().application
, arguments?.getParcelable(EntranceUtils.KEY_SUBJECT_DATA)!!)
return ViewModelProviders.of(this, factory).get(SubjectListViewModel::class.java)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mListRv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
val position = mLayoutManager.findFirstCompletelyVisibleItemPosition()
if (mScrollTop && position == 0 && newState == RecyclerView.SCROLL_STATE_IDLE) {
mScrollTop = false
EventBus.getDefault().post(EBReuse(SubjectTileFragment.OPEN_APPBAR))
}
}
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val position = mLayoutManager.findFirstCompletelyVisibleItemPosition()
if (position == 0 && Math.abs(dy) > 10) {
EventBus.getDefault().post(EBReuse(SubjectTileFragment.OPEN_APPBAR))
}
}
})
}
override fun onTitleClick() {
if (mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0 || provideListAdapter().itemCount == 0) {
EventBus.getDefault().post(EBReuse(SubjectTileFragment.OPEN_APPBAR))
} else {
mLayoutManager.smoothScrollToPosition(mListRv, null, 0)
mScrollTop = true
}
}
override fun onResume() {
if (isEverPause && mAdapter != null) mAdapter?.notifyDataSetChanged()
super.onResume()
DownloadManager.getInstance(context).addObserver(dataWatcher)
}
override fun onPause() {
super.onPause()
DownloadManager.getInstance(context).removeObserver(dataWatcher)
}
// 下载被删除事件
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(status: EBDownloadStatus) {
if ("delete" == status.status) {
mAdapter?.notifyItemAndRemoveDownload(status)
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busFour: EBPackage) {
if ("安装" == busFour.type || "卸载" == busFour.type) {
mAdapter?.notifyDataSetChanged()
}
}
}

View File

@ -0,0 +1,34 @@
package com.gh.gamecenter.subject.refactor
import android.app.Application
import android.arch.lifecycle.ViewModel
import android.arch.lifecycle.ViewModelProvider
import com.gh.common.util.UrlFilterUtils
import com.gh.gamecenter.baselist.ListViewModel
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.SubjectData
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.Observable
class SubjectListViewModel(application: Application,
private val subjectData: SubjectData) : ListViewModel<GameEntity, GameEntity>(application) {
override fun provideDataObservable(page: Int): Observable<List<GameEntity>> {
return RetrofitManager.getInstance(getApplication()).api.getColumn(subjectData.subjectId
, UrlFilterUtils.getFilterQuery("publish", subjectData.listOrder)
, UrlFilterUtils.getFilterQuery("type", subjectData.mTileType), page)
}
override fun mergeResultLiveData() {
mResultLiveData.addSource(mListLiveData, { mResultLiveData.postValue(it) })
}
class Factory(private val mApplication: Application, private val subjectData: SubjectData) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return SubjectListViewModel(mApplication, subjectData) as T
}
}
}

View File

@ -0,0 +1,95 @@
package com.gh.gamecenter.subject.refactor
import android.app.Application
import android.arch.lifecycle.AndroidViewModel
import android.arch.lifecycle.MutableLiveData
import android.arch.lifecycle.ViewModel
import android.arch.lifecycle.ViewModelProvider
import android.text.TextUtils
import com.gh.common.constant.Config
import com.gh.gamecenter.entity.SubjectData
import com.gh.gamecenter.entity.SubjectSettingEntity
import com.gh.gamecenter.retrofit.JSONObjectResponse
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import org.json.JSONObject
import retrofit2.HttpException
class SubjectViewModel(application: Application, var subjectData: SubjectData?) : AndroidViewModel(application) {
val subjectNameLD = MutableLiveData<String>()
val subjectSettingLD = MutableLiveData<SubjectSettingEntity>()
init {
initData()
}
fun initData() {
if (subjectData != null) {
if (subjectData?.subjectName.isNullOrEmpty()) {
loadSubjectName()
} else {
subjectNameLD.postValue(subjectData?.subjectName)
loadSubjectType()
}
} else {
subjectSettingLD.postValue(null)
}
}
private fun loadSubjectName() {
RetrofitManager.getInstance(getApplication()).api
.getSubjectName(subjectData?.subjectId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : JSONObjectResponse() {
override fun onResponse(response: JSONObject) {
var name = response.getString("name")
if (!TextUtils.isEmpty(name) && !Config.isShowPlugin()) {
name = name.replace("插件", "游戏")
}
subjectData?.subjectName = name
subjectNameLD.postValue(name)
loadSubjectType()
}
override fun onFailure(e: HttpException?) {
super.onFailure(e)
subjectNameLD.postValue("专题")
subjectData?.subjectName = "专题"
loadSubjectType()
}
})
}
private fun loadSubjectType() {
RetrofitManager.getInstance(getApplication()).api
.getColumnSettings(subjectData?.subjectId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<SubjectSettingEntity>() {
override fun onResponse(response: SubjectSettingEntity?) {
super.onResponse(response)
val content = response!!.typeEntity.content
content.add(0, "全部")
subjectData?.typeList = content
subjectData?.tagType = response.tag
subjectSettingLD.postValue(response)
}
override fun onFailure(e: HttpException?) {
super.onFailure(e)
subjectSettingLD.postValue(null)
}
})
}
class Factory(private val mApplication: Application, private val subjectData: SubjectData?) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return SubjectViewModel(mApplication, subjectData) as T
}
}
}

View File

@ -0,0 +1,47 @@
package com.gh.gamecenter.subject.refactor.tab
import android.os.Bundle
import android.support.design.widget.TabLayout
import android.support.v4.app.Fragment
import android.support.v4.view.ViewPager
import android.view.View
import com.gh.base.fragment.BaseFragment
import com.gh.common.util.EntranceUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.SubjectData
import com.gh.gamecenter.subject.refactor.SubjectListFragment
import com.lightgame.adapter.BaseFragmentPagerAdapter
import kotterknife.bindView
import java.util.*
class SubjectTabFragment : BaseFragment<Any>() {
private val mTabLayout by bindView<TabLayout>(R.id.subject_tab)
private val mViewPager by bindView<ViewPager>(R.id.subject_viewpager)
override fun getLayoutId(): Int {
return R.layout.fragment_subject_tab
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val subjectData = arguments?.getParcelable<SubjectData>(EntranceUtils.KEY_SUBJECT_DATA)
val tagList = subjectData?.typeList ?: return
if (tagList.size > 1) {
mTabLayout.visibility = View.VISIBLE
}
val fragments = ArrayList<Fragment>()
for (tag in tagList) {
mTabLayout.addTab(mTabLayout.newTab().setText(tag))
val element = SubjectListFragment()
element.arguments = arguments?.clone() as Bundle?
fragments.add(element)
}
val adapter = BaseFragmentPagerAdapter.newInstance(childFragmentManager, fragments, tagList)
mViewPager.adapter = adapter
mTabLayout.setupWithViewPager(mViewPager)
}
}

View File

@ -0,0 +1,145 @@
package com.gh.gamecenter.subject.refactor.tile
import android.os.Bundle
import android.support.design.widget.AppBarLayout
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentTransaction
import android.support.v7.widget.GridLayoutManager
import android.support.v7.widget.RecyclerView
import android.text.TextUtils
import android.view.MotionEvent
import android.view.View
import android.widget.CheckedTextView
import butterknife.OnClick
import com.gh.base.fragment.BaseFragment
import com.gh.common.util.EntranceUtils
import com.gh.common.util.StringUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.SubjectData
import com.gh.gamecenter.eventbus.EBReuse
import com.gh.gamecenter.normal.ToolbarController
import com.gh.gamecenter.subject.SubjectTileFragment
import com.gh.gamecenter.subject.refactor.SubjectListFragment
import kotterknife.bindView
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
class SubjectTileFragment : BaseFragment<Any>() {
private val mAppbar by bindView<AppBarLayout>(R.id.subject_appbar)
private val mTypeList by bindView<RecyclerView>(R.id.subject_type_list)
private val mBarHottest by bindView<CheckedTextView>(R.id.subject_tabbar_hottest)
private val mBarNewest by bindView<CheckedTextView>(R.id.subject_tabbar_newest)
private var mSubjectData: SubjectData? = null
// private val OPEN_APPBAR = "openAppBar"
private var mIsTouchScreen: Boolean = false
override fun getLayoutId(): Int {
return R.layout.fragment_subject_tiled
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mSubjectData = arguments?.getParcelable(EntranceUtils.KEY_SUBJECT_DATA)
mSubjectData?.mTileType = "全部"
mSubjectData?.listOrder = ""
// 初始化顶部类型列表
val layoutManager = object : GridLayoutManager(context, 4) {
override fun canScrollVertically(): Boolean {
return false
}
}
mTypeList.isNestedScrollingEnabled = false
mTypeList.layoutManager = layoutManager
if (mSubjectData?.typeList != null && mSubjectData?.typeList!!.size > 1) {
val adapter = SubjectTypeListAdapter(context!!, mItemClickListener = {
mSubjectData?.mTileType = it
loadData()
}, mGameType = mSubjectData?.typeList!!)
mTypeList.adapter = adapter
}
// Appbar 交互
mAppbar.addOnOffsetChangedListener { appBarLayout, verticalOffset ->
if (!TextUtils.isEmpty(mSubjectData?.subjectName)) {
val totalScrollRange = appBarLayout.totalScrollRange
if (Math.abs(verticalOffset) < totalScrollRange / 2) {
if (activity is ToolbarController) {
(activity as ToolbarController).setNavigationTitle(mSubjectData?.subjectName)
}
} else if (Math.abs(verticalOffset) == totalScrollRange && totalScrollRange != 0) {
if (activity is ToolbarController) {
(activity as ToolbarController).setNavigationTitle(StringUtils.buildString(mSubjectData?.subjectName, "-", mSubjectData?.mTileType, ""))
}
}
}
}
loadData()
}
fun onTouchEvent(motionEvent: MotionEvent) {
when (motionEvent.action) {
MotionEvent.ACTION_DOWN -> mIsTouchScreen = true
MotionEvent.ACTION_UP -> mIsTouchScreen = false
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(reuse: EBReuse) {
if (SubjectTileFragment.OPEN_APPBAR == reuse.type && !mIsTouchScreen) {
mAppbar.setExpanded(true, true)
}
}
@OnClick(R.id.subject_tabbar_hottest, R.id.subject_tabbar_newest)
override fun onClick(view: View) {
when (view.id) {
R.id.subject_tabbar_hottest -> {
mBarHottest.isChecked = true
mBarNewest.isChecked = false
mSubjectData?.listOrder = ""
loadData()
}
R.id.subject_tabbar_newest -> {
mBarHottest.isChecked = false
mBarNewest.isChecked = true
mSubjectData?.listOrder = "-1"
loadData()
}
}
}
fun loadData() {
val transaction = childFragmentManager.beginTransaction()
hideFragments(transaction)
alterFragment(transaction, mSubjectData?.mTileType + mSubjectData?.listOrder)
transaction.commitAllowingStateLoss()
}
private fun alterFragment(transaction: FragmentTransaction, fmTag: String) {
var fragmentByTag: Fragment? = childFragmentManager.findFragmentByTag(fmTag)
try {
if (fragmentByTag != null) {
transaction.show(fragmentByTag)
} else {
fragmentByTag = SubjectListFragment()
val bundle = Bundle()
bundle.putParcelable(EntranceUtils.KEY_SUBJECT_DATA, mSubjectData)
fragmentByTag.arguments = bundle
transaction.add(R.id.subject_content_rl, fragmentByTag, fmTag)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}

View File

@ -0,0 +1,67 @@
package com.gh.gamecenter.subject.refactor.tile
import android.content.Context
import android.graphics.Color
import android.support.v4.content.ContextCompat
import android.support.v7.widget.RecyclerView
import android.text.TextUtils
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.TextView
import com.gh.common.util.DisplayUtils
import com.gh.gamecenter.R
import com.lightgame.adapter.BaseRecyclerAdapter
class SubjectTypeListAdapter(context: Context,
private val mItemClickListener: (type: String) -> Unit,
private val mGameType: List<String>) : BaseRecyclerAdapter<SubjectTypeListAdapter.SubjectTypeViewHolder>(context) {
private var mCurType = "全部"
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SubjectTypeViewHolder {
val relativeLayout = RelativeLayout(mContext)
relativeLayout.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, DisplayUtils.dip2px(mContext, 35f))
relativeLayout.gravity = Gravity.CENTER
val textView = TextView(mContext)
textView.textSize = 14f
textView.setBackgroundResource(R.drawable.subject_tab_style)
textView.setTextColor(ContextCompat.getColor(mContext, R.color.title))
textView.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, DisplayUtils.dip2px(mContext, 25f))
textView.gravity = Gravity.CENTER
textView.setPadding(DisplayUtils.dip2px(mContext, 10f), 0, DisplayUtils.dip2px(mContext, 10f), 0)
relativeLayout.addView(textView)
return SubjectTypeViewHolder(relativeLayout)
}
override fun onBindViewHolder(holder: SubjectTypeViewHolder, position: Int) {
holder.type.text = mGameType[position]
if (!TextUtils.isEmpty(mCurType) && mCurType == mGameType[position]) {
holder.type.isSelected = true
holder.type.setTextColor(Color.WHITE)
} else {
holder.type.isSelected = false
holder.type.setTextColor(ContextCompat.getColor(mContext, R.color.title))
}
holder.type.setOnClickListener {
holder.type.isSelected = true
mCurType = mGameType[holder.adapterPosition]
mItemClickListener.invoke(mGameType[holder.adapterPosition])
notifyDataSetChanged()
}
}
override fun getItemCount(): Int {
return mGameType.size
}
inner class SubjectTypeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val type: TextView = (itemView as RelativeLayout).getChildAt(0) as TextView
}
}