Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev

# Conflicts:
#	app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt
This commit is contained in:
kehaoyuan
2018-06-13 17:26:31 +08:00
24 changed files with 1419 additions and 2 deletions

View File

@ -74,6 +74,9 @@ public class EntranceUtils {
public static final String KEY_CHECK_QUESTION_CONCERN = "check_question_concern";
public static final String KEY_DRAFT_ID = "draft_id";
public static final String KEY_KAIFU_LIST = "kaifuList";
public static final String KEY_CATEGORY_ID = "category_id";
public static final String KEY_CATEGORY_TITLE = "category_title";
public static final String KEY_CATEGORY_INIT_TITLE = "category_init_title";
public static final String KEY_BLOCK_DATA = "blockData";
public static void jumpActivity(Context context, Bundle bundle) {

View File

@ -6,6 +6,9 @@ import android.content.Intent;
import android.net.Uri;
import android.support.annotation.NonNull;
import com.gh.gamecenter.category.CategoryListActivity;
import com.gh.gamecenter.entity.CategoryEntity;
/**
* @author CsHeng
* @Date 17/05/2017
@ -53,4 +56,8 @@ public class IntentUtils {
"http://www.ghzs.com/link?source=appshare333");
return data;
}
public static void startCategoryListActivity(Context context, CategoryEntity category) {
context.startActivity(CategoryListActivity.Companion.getIntent(context, category, "全部"));
}
}

View File

@ -0,0 +1,45 @@
package com.gh.common.view
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.widget.LinearLayout
import android.widget.TextView
import com.gh.gamecenter.R
import com.gh.gamecenter.category.CategoryListActivity
import com.gh.gamecenter.entity.CategoryEntity
class SubCategoryView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : LinearLayout(context, attrs, defStyleAttr) {
var leftTv: TextView
var centerTv: TextView
var rightTv: TextView
var primeCategory: CategoryEntity? = null
init {
View.inflate(context, R.layout.layout_sub_category, this)
leftTv = findViewById(R.id.tv_left_sub_category)
centerTv = findViewById(R.id.tv_center_sub_category)
rightTv = findViewById(R.id.tv_right_sub_category)
}
fun setLeftCategory(category: CategoryEntity) {
setCategory(leftTv, category)
}
fun setCenterCategory(category: CategoryEntity) {
setCategory(centerTv, category)
}
fun setRightCategory(category: CategoryEntity) {
setCategory(rightTv, category)
}
private fun setCategory(tv: TextView, category: CategoryEntity) {
tv.text = category.name
tv.setOnClickListener { tv.context.startActivity(CategoryListActivity.getIntent(tv.context, primeCategory!!, category.name!!)) }
}
}

View File

@ -36,6 +36,14 @@ public class SubjectTypeAdapter extends BaseRecyclerAdapter<GameTypeViewHolder>
mCurType = "全部";
}
public SubjectTypeAdapter(Context context, OnSelectTypeListener listener, List<String> gameType, String initTitle) {
super(context);
this.mListener = listener;
mGameType = gameType;
mCurType = initTitle;
}
@Override
public GameTypeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RelativeLayout relativeLayout = new RelativeLayout(mContext);

View File

@ -0,0 +1,20 @@
package com.gh.gamecenter.category
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.gh.common.util.EntranceUtils
import com.gh.gamecenter.NormalActivity
class CategoryDirectoryActivity : NormalActivity() {
companion object {
fun getIntent(context: Context, categoryId: String, categoryTitle: String): Intent {
val bundle = Bundle()
bundle.putString(EntranceUtils.KEY_CATEGORY_ID, categoryId)
bundle.putString(EntranceUtils.KEY_CATEGORY_TITLE, categoryTitle)
return NormalActivity.getTargetIntent(context, CategoryDirectoryActivity::class.java, CategoryDirectoryFragment::class.java, bundle)
}
}
}

View File

@ -0,0 +1,124 @@
package com.gh.gamecenter.category
import android.app.Activity
import android.content.Context
import android.databinding.DataBindingUtil
import android.support.v7.widget.RecyclerView
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import com.gh.common.util.DisplayUtils
import com.gh.common.view.SubCategoryView
import com.gh.gamecenter.R
import com.gh.gamecenter.baselist.ListAdapter
import com.gh.gamecenter.databinding.ItemCategoryBinding
import com.gh.gamecenter.entity.CategoryEntity
class CategoryDirectoryAdapter(context: Context) : ListAdapter<CategoryEntity>(context) {
var expandStatusMap: HashMap<Int, Boolean> = HashMap()
private var sixteenDp: Int = 0
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
if (sixteenDp == 0) sixteenDp = DisplayUtils.dip2px(parent.context, 16f)
return CategoryViewHolder(DataBindingUtil.inflate((parent.context as Activity).layoutInflater, R.layout.item_category, parent, false))
}
override fun getItemCount(): Int {
return mEntityList.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is CategoryViewHolder -> {
holder.binding.category = mEntityList[position]
holder.bindCategory(
category = mEntityList[position],
expandableStatusMap = expandStatusMap,
isExpended = expandStatusMap[position] != null && expandStatusMap[position] == true,
marginTop = sixteenDp)
}
}
}
internal class CategoryViewHolder(var binding: ItemCategoryBinding) : RecyclerView.ViewHolder(binding.root) {
fun bindCategory(category: CategoryEntity, expandableStatusMap: HashMap<Int, Boolean>, isExpended: Boolean, marginTop: Int) {
category.data?.let {
var subCategoryView: SubCategoryView? = null
binding.containerUnexpandable.removeAllViews()
val unexpandableSize = if (it.size > 6) 6 else it.size
val unexpandableCategoryList = it.subList(0, unexpandableSize)
unexpandableCategoryList.forEachIndexed({ index, c ->
when (index % 3) {
0 -> {
val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT)
if (subCategoryView != null) params.setMargins(0, marginTop, 0, 0)
subCategoryView = SubCategoryView(binding.root.context)
subCategoryView?.primeCategory = category
subCategoryView?.layoutParams = params
binding.containerUnexpandable.addView(subCategoryView)
subCategoryView?.setLeftCategory(c)
}
1 -> subCategoryView?.setCenterCategory(c)
2 -> subCategoryView?.setRightCategory(c)
}
})
if (it.size > 7) {
val extraCategoryList = it.subList(6, it.size)
val subCategoryViewLinearLayout = LinearLayout(binding.root.context)
subCategoryViewLinearLayout.orientation = LinearLayout.VERTICAL
subCategoryView = SubCategoryView(binding.root.context)
binding.containerExpandable.removeAllViews()
binding.containerExpandable.addView(subCategoryViewLinearLayout)
binding.containerExpandable.setExpanded(isExpended, false)
binding.containerExpandable.setOnExpansionUpdateListener { _, state ->
when (state) {
0 -> {
binding.ivToggle.setImageResource(R.drawable.ic_category_arrow_down)
expandableStatusMap[adapterPosition] = false
}
3 -> {
binding.ivToggle.setImageResource(R.drawable.ic_category_arrow_up)
expandableStatusMap[adapterPosition] = true
}
}
}
binding.ivToggle.visibility = View.VISIBLE
binding.ivToggle.setOnClickListener { binding.containerExpandable.toggle() }
when {
isExpended -> binding.ivToggle.setImageResource(R.drawable.ic_category_arrow_up)
else -> binding.ivToggle.setImageResource(R.drawable.ic_category_arrow_down)
}
extraCategoryList.forEachIndexed({ index, c ->
when (index % 3) {
0 -> {
subCategoryView = SubCategoryView(binding.root.context)
val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT)
params.setMargins(0, marginTop, 0, 0)
subCategoryView?.primeCategory = category
subCategoryView?.layoutParams = params
subCategoryViewLinearLayout.addView(subCategoryView)
subCategoryView?.setLeftCategory(c)
}
1 -> subCategoryView?.setCenterCategory(c)
2 -> subCategoryView?.setRightCategory(c)
}
})
}
}
}
}
}

View File

@ -0,0 +1,44 @@
package com.gh.gamecenter.category
import android.arch.lifecycle.ViewModelProviders
import android.graphics.Color
import android.os.Bundle
import android.support.v7.widget.RecyclerView
import android.view.View
import com.gh.common.util.EntranceUtils
import com.gh.common.view.VerticalItemDecoration
import com.gh.gamecenter.baselist.ListAdapter
import com.gh.gamecenter.baselist.ListFragment
import com.gh.gamecenter.entity.CategoryEntity
class CategoryDirectoryFragment : ListFragment<CategoryEntity, CategoryDirectoryListViewModel>() {
private lateinit var mViewModel: CategoryDirectoryListViewModel
private lateinit var mAdapter: CategoryDirectoryAdapter
override fun onCreate(savedInstanceState: Bundle?) {
mViewModel = ViewModelProviders.of(this).get(CategoryDirectoryListViewModel::class.java)
mViewModel.categoryId = arguments?.getString(EntranceUtils.KEY_CATEGORY_ID)!!
mAdapter = CategoryDirectoryAdapter(context!!)
super.onCreate(savedInstanceState)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setNavigationTitle(arguments?.getString(EntranceUtils.KEY_CATEGORY_TITLE))
mListRv.setBackgroundColor(Color.WHITE)
}
override fun provideListAdapter(): ListAdapter<*> {
return mAdapter
}
override fun provideListViewModel(): CategoryDirectoryListViewModel {
return mViewModel
}
override fun getItemDecoration(): RecyclerView.ItemDecoration {
return VerticalItemDecoration(context, 8, false)
}
}

View File

@ -0,0 +1,20 @@
package com.gh.gamecenter.category
import android.app.Application
import com.gh.gamecenter.baselist.ListViewModel
import com.gh.gamecenter.entity.CategoryEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import rx.Observable
class CategoryDirectoryListViewModel(application: Application) : ListViewModel<CategoryEntity, CategoryEntity>(application) {
var categoryId = ""
init {
mResultLiveData.addSource(mListLiveData, mResultLiveData::postValue)
}
override fun <T : Any?> provideDataObservable(page: Int): Observable<MutableList<T>> {
return RetrofitManager.getInstance(getApplication()).api.getCategories(categoryId, page) as Observable<MutableList<T>>
}
}

View File

@ -0,0 +1,26 @@
package com.gh.gamecenter.category
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.gh.common.util.EntranceUtils
import com.gh.gamecenter.NormalActivity
import com.gh.gamecenter.entity.CategoryEntity
class CategoryListActivity : NormalActivity() {
companion object {
fun getIntent(context: Context, category: CategoryEntity, initTitle: String): Intent {
val bundle = Bundle()
if (category.data!![0].name != "全部") {
val plainCategory = CategoryEntity(id = category.id, name = "全部")
((category.data) as ArrayList).add(0, plainCategory)
}
bundle.putParcelable(EntranceUtils.KEY_DATA, category)
bundle.putString(EntranceUtils.KEY_NAME, category.name)
bundle.putString(EntranceUtils.KEY_CATEGORY_INIT_TITLE, initTitle)
return NormalActivity.getTargetIntent(context, CategoryListActivity::class.java, CategoryListWrapperFragment::class.java, bundle)
}
}
}

View File

@ -0,0 +1,415 @@
package com.gh.gamecenter.category;
import android.content.Context;
import android.content.Intent;
import android.support.v4.util.ArrayMap;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import com.gh.base.OnRequestCallBackListener;
import com.gh.common.constant.ItemViewType;
import com.gh.common.util.ApkActiveUtils;
import com.gh.common.util.DataCollectionUtils;
import com.gh.common.util.DataUtils;
import com.gh.common.util.DownloadItemUtils;
import com.gh.common.util.GameViewUtils;
import com.gh.common.util.ImageUtils;
import com.gh.common.util.KaiFuUtils;
import com.gh.common.util.NewsUtils;
import com.gh.common.util.StringUtils;
import com.gh.download.DownloadManager;
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.GameNormalViewHolder;
import com.gh.gamecenter.adapter.viewholder.GameTestViewHolder;
import com.gh.gamecenter.entity.ApkEntity;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.manager.GameManager;
import com.gh.gamecenter.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.lightgame.adapter.BaseRecyclerAdapter;
import com.lightgame.utils.Utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import retrofit2.HttpException;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public class CategoryListAdapter extends BaseRecyclerAdapter<RecyclerView.ViewHolder> {
private OnRequestCallBackListener mOnRequestCallBackListener;
private List<GameEntity> mSubjectList;
private ArrayMap<String, ArrayList<Integer>> mLocationMap;
private String mId;
private String mName;
private String mEntrance;
private String mType;
private String mOrder;
private String mTagType;
private boolean mIsRemove;
private boolean mIsNetworkError;
private boolean mIsOrder;
private boolean mIsLoaded;
public CategoryListAdapter(Context context, OnRequestCallBackListener listener, String type, String id
, String name, String entrance, String order, String tagType, boolean isOrder) {
super(context);
this.mOnRequestCallBackListener = listener;
this.mType = type;
this.mId = id;
this.mName = name;
this.mEntrance = entrance;
this.mIsOrder = isOrder;
this.mOrder = order;
this.mTagType = tagType;
mLocationMap = new ArrayMap<>();
mSubjectList = new ArrayList<>();
mIsLoaded = false;
mIsNetworkError = false;
mIsRemove = false;
initList(1);
}
public void initList(final int page) {
mIsLoaded = false;
RetrofitManager.getInstance(mContext).getApi().getGamesInCategory(mId, mOrder, page)
.map(list -> removeDuplicateData(mSubjectList, list))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<List<GameEntity>>() {
@Override
public void onResponse(List<GameEntity> response) {
GameManager manager = new GameManager(mContext);
if (response.size() != 0) {
for (GameEntity entity : response) {
// 黄壮华 初始化游戏状态 修改2015/8/15
entity.setEntryMap(DownloadManager.getInstance(mContext).getEntryMap(entity.getName()));
manager.addOrUpdate(entity);
ApkActiveUtils.filterHideApk(entity); // 过滤隐藏apk
}
mSubjectList.addAll(response);
notifyItemRangeInserted(mSubjectList.size() - response.size(), response.size());
if (response.size() < 20 && page != 1 || response.size() < 19) {
mIsRemove = true;
notifyItemChanged(getItemCount() - 1);
}
} else {
mIsRemove = true;
notifyDataSetChanged();
}
initLocationMap();
if (mOnRequestCallBackListener != null) {
if (mSubjectList.size() == 0) {
mOnRequestCallBackListener.loadEmpty();
} else {
mOnRequestCallBackListener.loadDone();
}
}
mIsLoaded = true;
}
@Override
public void onFailure(HttpException e) {
mIsLoaded = true;
if (page == 1) {
if (mOnRequestCallBackListener != null) {
mOnRequestCallBackListener.loadError();
}
} else {
Utils.toast(mContext, R.string.loading_failed_hint);
mIsNetworkError = true;
notifyDataSetChanged();
}
}
});
}
private List<GameEntity> removeDuplicateData(List<GameEntity> sourceList, List<GameEntity> rawList) {
if (sourceList == null || sourceList.isEmpty()
|| rawList == null || rawList.isEmpty()) {
return rawList;
}
String id;
for (int i = 0; i < rawList.size(); i++) {
id = rawList.get(i).getId();
for (GameEntity gameEntity : sourceList) {
if (id.equals(gameEntity.getId())) {
rawList.remove(i);
i--;
break;
}
}
}
return rawList;
}
private void initLocationMap() {
ArrayList<Integer> list;
GameEntity gameEntity;
for (int i = 0, size = mSubjectList.size(); i < size; i++) {
gameEntity = mSubjectList.get(i);
if (gameEntity.getApk() != null && gameEntity.getApk().size() != 0) {
for (ApkEntity apkEntity : gameEntity.getApk()) {
list = mLocationMap.get(apkEntity.getPackageName());
if (list == null) {
list = new ArrayList<>();
mLocationMap.put(apkEntity.getPackageName(), list);
}
list.add(i);
}
}
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view;
switch (viewType) {
case ItemViewType.LOADING:
view = mLayoutInflater.inflate(R.layout.refresh_footerview, viewGroup, false);
return new FooterViewHolder(view);
case ItemViewType.GAME_TEST:
view = mLayoutInflater.inflate(R.layout.game_test_item, viewGroup, false);
return new GameTestViewHolder(view);
case ItemViewType.GAME_NORMAL:
view = mLayoutInflater.inflate(R.layout.game_normal_item, viewGroup, false);
return new GameNormalViewHolder(view);
case ItemViewType.GAME_IMAGE:
view = mLayoutInflater.inflate(R.layout.game_image_item, viewGroup, false);
return new GameImageViewHolder(view);
default:
return null;
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
if (viewHolder instanceof GameNormalViewHolder) {
initGameNormalViewHolder((GameNormalViewHolder) viewHolder, position);
} else if (viewHolder instanceof GameTestViewHolder) {
initGameTestViewHolder((GameTestViewHolder) viewHolder, position);
} else if (viewHolder instanceof FooterViewHolder) {
initFooterViewHolder((FooterViewHolder) viewHolder);
} else if (viewHolder instanceof GameImageViewHolder) {
GameImageViewHolder holder = ((GameImageViewHolder) viewHolder);
holder.line.setVisibility(View.GONE);
int widthPixels = mContext.getResources().getDisplayMetrics().widthPixels;
final GameEntity gameEntity = mSubjectList.get(position);
ImageUtils.Companion.getInstance().display(holder.image, gameEntity.getImage(), widthPixels);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Map<String, Object> kv = new HashMap<>();
kv.put("名字", gameEntity.getName());
kv.put("位置", "头图");
DataUtils.onEvent(mContext, "点击", mName, kv);
DataCollectionUtils.uploadClick(mContext, "头图", mName);
switch (gameEntity.getType()) {
case "game":
GameDetailActivity.startGameDetailActivity(mContext, gameEntity.getLink(), mEntrance + "(" + mName + ":大图)");
break;
case "news":
// 统计阅读量
NewsUtils.statNewsViews(mContext, gameEntity.getLink());
Intent intent = NewsDetailActivity.getIntentById(mContext, gameEntity.getLink(), mEntrance + "(" + mName + ":大图)");
mContext.startActivity(intent);
break;
case "column":
SubjectActivity.startSubjectActivity(mContext, gameEntity.getLink(), gameEntity.getName(), false
, mEntrance + "(" + mName + ":大图)");
break;
}
}
});
}
}
@Override
public int getItemViewType(int position) {
if (position == mSubjectList.size()) {
return ItemViewType.LOADING;
}
if (position == 0 && mSubjectList.size() > 0 && !TextUtils.isEmpty(mSubjectList.get(0).getImage())) {
return ItemViewType.GAME_IMAGE;
} else if (mSubjectList.get(position).getTest() != null) {
return ItemViewType.GAME_TEST;
} else {
return ItemViewType.GAME_NORMAL;
}
}
@Override
public int getItemCount() {
if (mSubjectList.size() < 1) {
return 0;
}
return mSubjectList.size() + 1;
}
private void initGameNormalViewHolder(final GameNormalViewHolder holder, final int position) {
if (mIsOrder) {
int index = 1;
if (!TextUtils.isEmpty(mSubjectList.get(0).getImage())) {
index = 0;
}
holder.gameOrder.setVisibility(View.VISIBLE);
holder.gameOrder.setText(String.valueOf(position + index));
} else {
holder.gameOrder.setVisibility(View.GONE);
}
final GameEntity gameEntity = mSubjectList.get(position);
// holder.gameThumb.setImageURI(gameEntity.getIcon());
ImageUtils.Companion.display(holder.gameThumb, gameEntity.getIcon());
holder.gameName.setText(gameEntity.getName());
if (gameEntity.getApk() == null || gameEntity.getApk().isEmpty()) {
holder.gameDes.setText(gameEntity.getBrief());
} else {
holder.gameDes.setText(String.format("%s %s", gameEntity.getApk().get(0).getSize(), gameEntity.getBrief()));
}
holder.initServerType(gameEntity, mContext);
GameViewUtils.setLabelList(mContext, holder.gameLabelList, gameEntity.getTag(), mTagType);
holder.itemView.setOnClickListener(v -> {
Map<String, Object> kv = new HashMap<>();
kv.put("名字", gameEntity.getName());
kv.put("位置", String.valueOf(position + 1));
DataUtils.onEvent(mContext, "点击", mName, kv);
DataCollectionUtils.uploadClick(mContext, "列表", mName, gameEntity.getName());
GameDetailActivity.startGameDetailActivity(mContext, gameEntity,
StringUtils.buildString(mEntrance, "+(", mName, ":列表[", mType, "=", ("latest".equals(mOrder) ? "最新" : "最热"), "=", String.valueOf(position + 1), "])"));
});
DownloadItemUtils.setOnClickListener(mContext, holder.gameDownloadBtn,
gameEntity, position, this,
StringUtils.buildString(mEntrance, "+(", mName, ":列表[", mType, "=", ("latest".equals(mOrder) ? "最新" : "最热"), "=", String.valueOf(position + 1), "])"),
StringUtils.buildString(mName, ":", gameEntity.getName()));
DownloadItemUtils.updateItem(mContext, gameEntity, holder, true);
}
private void initGameTestViewHolder(final GameTestViewHolder holder, final int position) {
if (mIsOrder) {
int index = 1;
if (!TextUtils.isEmpty(mSubjectList.get(0).getImage())) {
index = 0;
}
holder.gameOrder.setVisibility(View.VISIBLE);
holder.gameOrder.setText(String.valueOf(position + index));
} else {
holder.gameOrder.setVisibility(View.GONE);
}
final GameEntity gameEntity = mSubjectList.get(position);
ImageUtils.Companion.display(holder.gameThumb, gameEntity.getIcon());
holder.gameName.setText(gameEntity.getName());
if (gameEntity.getApk() == null || gameEntity.getApk().isEmpty()) {
holder.gameDes.setText(gameEntity.getBrief());
} else {
holder.gameDes.setText(String.format("%s %s", gameEntity.getApk().get(0).getSize(), gameEntity.getBrief()));
}
if (gameEntity.getTest().getStart() == 0) {
holder.gameTestTime.setVisibility(View.GONE);
} else {
holder.gameTestTime.setText(GameViewUtils.getGameTestDate(gameEntity.getTest().getStart()));
}
String type = gameEntity.getTest().getType();
KaiFuUtils.setKaiFuType(holder.gameTestType, type);
holder.itemView.setOnClickListener(v -> {
Map<String, Object> kv = new HashMap<>();
kv.put("名字", gameEntity.getName());
kv.put("位置", String.valueOf(holder.getPosition() + 1));
DataUtils.onEvent(mContext, "点击", mName, kv);
DataCollectionUtils.uploadClick(mContext, "列表", mName, gameEntity.getName());
GameDetailActivity.startGameDetailActivity(mContext, gameEntity,
StringUtils.buildString(mEntrance, "+(", mName, ":列表[", mType, "=", ("latest".equals(mOrder) ? "最新" : "最热"), "=", String.valueOf(position + 1), "])"));
});
DownloadItemUtils.setOnClickListener(mContext,
holder.gameDownloadBtn, gameEntity, position, CategoryListAdapter.this,
StringUtils.buildString(mEntrance, "+(", mName, ":列表[", mType, "=", ("latest".equals(mOrder) ? "最新" : "最热"), "=", String.valueOf(position + 1), "])"),
StringUtils.buildString(mName, ":", gameEntity.getName()));
DownloadItemUtils.updateItem(mContext, gameEntity, holder, true);
}
private void initFooterViewHolder(FooterViewHolder viewHolder) {
viewHolder.initItemPadding();
if (mIsNetworkError) {
viewHolder.loading.setVisibility(View.GONE);
viewHolder.hint.setText(R.string.loading_failed_retry);
viewHolder.itemView.setClickable(true);
viewHolder.itemView.setOnClickListener(v -> {
mIsNetworkError = false;
notifyDataSetChanged();
initList((mSubjectList.size() / 20) + 1);
});
} else if (mIsRemove) {
viewHolder.loading.setVisibility(View.GONE);
viewHolder.hint.setText(R.string.loading_complete);
viewHolder.itemView.setClickable(false);
viewHolder.lineLeft.setVisibility(View.VISIBLE);
viewHolder.lineRight.setVisibility(View.VISIBLE);
} else {
viewHolder.loading.setVisibility(View.VISIBLE);
viewHolder.hint.setText(R.string.loading);
viewHolder.itemView.setClickable(false);
}
}
public List<GameEntity> getSubjectList() {
return mSubjectList;
}
public ArrayMap<String, ArrayList<Integer>> getLocationMap() {
return mLocationMap;
}
public boolean isLoaded() {
return mIsLoaded;
}
public boolean isRemove() {
return mIsRemove;
}
}

View File

@ -0,0 +1,246 @@
package com.gh.gamecenter.category
import android.os.Bundle
import android.support.v7.widget.DefaultItemAnimator
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.View
import butterknife.BindView
import com.gh.base.fragment.BaseFragment
import com.gh.common.util.ApkActiveUtils
import com.gh.common.util.DownloadItemUtils
import com.gh.common.util.EntranceUtils
import com.gh.common.view.VerticalItemDecoration
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.eventbus.*
import com.gh.gamecenter.info.InfoToolWrapperFragment
import com.gh.gamecenter.subject.SubjectListFragment
import com.gh.gamecenter.subject.SubjectTileFragment
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 CategoryListFragment : BaseFragment<String>(), OnTitleClickListener {
@BindView(R.id.subject_list)
lateinit var mRvSubject: RecyclerView
@BindView(R.id.subject_pb_loading)
lateinit var mPbSubject: View
@BindView(R.id.reuse_no_connection)
lateinit var reuse_no_connection: View
@BindView(R.id.reuse_none_data)
lateinit var mNoData: View
private var mSubjectAdapter: CategoryListAdapter? = null
private var mLayoutManager: LinearLayoutManager? = null
private var mId: String? = ""
private var mName: String? = ""
private var mType: String? = ""
private var mTagType: String? = ""
private var mListOrder: String? = "" // 列表排序 最新/最热
private var mIsOrder: Boolean = false
private var mScrollTop = false
private var page = 1
// 黄壮华 添加观察者 修改2015/8/15
private val dataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
val locationList = mSubjectAdapter!!.locationMap[downloadEntity.packageName]
if (locationList != null) {
var gameEntity: GameEntity?
for (location in locationList) {
gameEntity = mSubjectAdapter!!.subjectList[location]
if (gameEntity != null) {
DownloadItemUtils.processDate(context, gameEntity, downloadEntity, mSubjectAdapter, location)
}
}
}
}
}
fun newInstance(bundle: Bundle): SubjectListFragment {
val fragment = SubjectListFragment()
fragment.arguments = bundle
return fragment
}
override fun getLayoutId(): Int {
return R.layout.fragment_subject
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val arguments = arguments
mId = arguments?.getString(EntranceUtils.KEY_ID)
mName = arguments?.getString(EntranceUtils.KEY_NAME)
mIsOrder = arguments?.getBoolean(EntranceUtils.KEY_ORDER)!!
mType = arguments.getString(EntranceUtils.KEY_TYPE)
mListOrder = arguments.getString(SubjectTileFragment.KEY_LISTORDER)
mTagType = arguments.getString(EntranceUtils.KEY_TAGTYPE)
mEntrance = arguments.getString(EntranceUtils.KEY_ENTRANCE)
reuse_no_connection.setOnClickListener {
mPbSubject.visibility = View.VISIBLE
mRvSubject.visibility = View.VISIBLE
reuse_no_connection.visibility = View.GONE
mSubjectAdapter = CategoryListAdapter(context, this, mType, mId, mName, mEntrance, mListOrder, mTagType, mIsOrder)
mRvSubject.adapter = mSubjectAdapter
}
mLayoutManager = LinearLayoutManager(context)
(mRvSubject.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
mRvSubject.addItemDecoration(VerticalItemDecoration(context, 8, true))
mRvSubject.setHasFixedSize(true)
mRvSubject.layoutManager = mLayoutManager
mSubjectAdapter = CategoryListAdapter(context, this, mType, mId, mName, mEntrance, mListOrder, mTagType, mIsOrder)
mRvSubject.adapter = mSubjectAdapter
mRvSubject.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))
}
if (!mSubjectAdapter!!.isRemove && mSubjectAdapter!!.isLoaded && newState == RecyclerView.SCROLL_STATE_IDLE
&& mSubjectAdapter!!.itemCount == mLayoutManager!!.findLastVisibleItemPosition() + 1) {
mSubjectAdapter!!.initList(page)
}
}
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 onResume() {
if (isEverPause && mSubjectAdapter != null) {
mSubjectAdapter!!.notifyDataSetChanged()
}
DownloadManager.getInstance(context).addObserver(dataWatcher)
super.onResume()
}
override fun onPause() {
super.onPause()
DownloadManager.getInstance(context).removeObserver(dataWatcher)
}
override fun loadDone() {
mNoData.visibility = View.GONE
if (mPbSubject.visibility == View.VISIBLE) {
mPbSubject.visibility = View.GONE
}
page++
}
override fun loadError() {
if (mPbSubject.visibility == View.VISIBLE) {
mPbSubject.visibility = View.GONE
}
mRvSubject.visibility = View.GONE
reuse_no_connection.visibility = View.VISIBLE
mNoData.visibility = View.GONE
}
override fun loadEmpty() {
super.loadEmpty()
mNoData.visibility = View.VISIBLE
reuse_no_connection.visibility = View.GONE
}
// 下载被删除事件
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(status: EBDownloadStatus) {
if ("delete" == status.status) {
DownloadManager.getInstance(context).removePlatform(status.name, status.platform)
val locationList = mSubjectAdapter!!.locationMap[status.packageName]
if (locationList != null) {
var gameEntity: GameEntity?
for (location in locationList) {
gameEntity = mSubjectAdapter!!.subjectList[location]
if (gameEntity != null) {
gameEntity.getEntryMap().remove(status.platform)
}
mSubjectAdapter!!.notifyItemChanged(location)
}
}
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busFour: EBPackage) {
val locationList = mSubjectAdapter!!.locationMap[busFour.packageName]
if (locationList != null) {
var gameEntity: GameEntity
for (location in locationList) {
gameEntity = mSubjectAdapter!!.subjectList[location]
ApkActiveUtils.filterHideApk(gameEntity)
if ("安装" == busFour.type) {
for (apkEntity in gameEntity.getApk()) {
if (apkEntity.packageName == busFour.packageName) {
gameEntity.getEntryMap().remove(apkEntity.getPlatform())
mSubjectAdapter!!.notifyItemChanged(location)
break
}
}
} else if ("卸载" == busFour.type) {
mSubjectAdapter!!.notifyItemChanged(location)
}
}
}
}
//连接上网络事件
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busNetworkState: EBNetworkState) {
if (busNetworkState.isNetworkConnected) {
if (reuse_no_connection.visibility == View.VISIBLE) {
mRvSubject.visibility = View.VISIBLE
mPbSubject.visibility = View.VISIBLE
reuse_no_connection.visibility = View.GONE
mSubjectAdapter = CategoryListAdapter(context, this, mType, mId, mName, mEntrance, mListOrder, mTagType, mIsOrder)
mRvSubject.adapter = mSubjectAdapter
}
}
}
// 资讯Fragment界面切换事件
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busNine: EBUISwitch) {
if (InfoToolWrapperFragment.EB_NEWSFRAGMENT_TAG == busNine.from) {
if (busNine.position == 0) {
if (mPbSubject.visibility == View.VISIBLE) {
mSubjectAdapter!!.initList(1)
}
}
}
}
override fun onTitleClick() {
if (mLayoutManager!!.findFirstCompletelyVisibleItemPosition() == 0 || mSubjectAdapter!!.itemCount == 0) {
EventBus.getDefault().post(EBReuse(SubjectTileFragment.OPEN_APPBAR))
} else {
mLayoutManager!!.smoothScrollToPosition(mRvSubject, null, 0)
mScrollTop = true
}
}
}

View File

@ -0,0 +1,184 @@
package com.gh.gamecenter.category
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
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.DefaultItemAnimator
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.TextView
import butterknife.BindView
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.adapter.SubjectTypeAdapter
import com.gh.gamecenter.entity.CategoryEntity
import com.gh.gamecenter.eventbus.EBReuse
import com.gh.gamecenter.normal.ToolbarController
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
class CategoryListTabFragment : BaseFragment<String>(), SubjectTypeAdapter.OnSelectTypeListener {
@BindView(R.id.subject_type_list)
lateinit var mSubjectRv: RecyclerView
@BindView(R.id.subject_appbar)
lateinit var mAppbar: AppBarLayout
@BindView(R.id.subject_tabbar_hot_tv)
lateinit var mTabbarHotTv: TextView
@BindView(R.id.subject_tabbar_new_tv)
lateinit var mTabbarNewTv: TextView
val OPEN_APPBAR = "openAppBar"
val KEY_LISTORDER = "listOrder"
private var mPrimeCategory: CategoryEntity? = null
private var mSubCategoryList = arrayListOf<CategoryEntity>()
private var mName: String? = ""
private var mType: String? = ""
private var mListOrder: String? = ""
private var mTagType: String? = ""
private var mIsTouchScreen: Boolean = false
fun loadData() {
val transaction = childFragmentManager.beginTransaction()
hideFragments(transaction)
alterFragment(transaction, mType + mListOrder)
transaction.commitAllowingStateLoss()
}
private fun alterFragment(transaction: FragmentTransaction, fmTag: String) {
var fragmentByTag: Fragment? = childFragmentManager.findFragmentByTag(fmTag)
try {
if (fragmentByTag != null) {
transaction.show(fragmentByTag)
} else {
fragmentByTag = CategoryListFragment()
val clone = arguments?.clone() as Bundle
clone.putString(EntranceUtils.KEY_ID, findCategoryIdByName(mType!!))
clone.putString(EntranceUtils.KEY_TYPE, mType)
clone.putString(KEY_LISTORDER, mListOrder)
fragmentByTag.arguments = clone
transaction.add(R.id.subject_content_rl, fragmentByTag, fmTag)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun findCategoryIdByName(name: String): String {
for (subCategory in mSubCategoryList) {
if (name == subCategory.name) {
return subCategory.id!!
}
}
return ""
}
override fun getLayoutId(): Int {
return R.layout.fragment_subject_tiled
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val arguments = arguments
mName = arguments?.getString(EntranceUtils.KEY_NAME)
mEntrance = arguments?.getString(EntranceUtils.KEY_ENTRANCE)
mTagType = arguments?.getString(EntranceUtils.KEY_TAGTYPE)
mPrimeCategory = arguments?.getParcelable(EntranceUtils.KEY_DATA)
mSubCategoryList = mPrimeCategory?.data as ArrayList<CategoryEntity>
mType = "全部"
mListOrder = "download:-1"
// 设置标题
val layoutManager = object : GridLayoutManager(context, 4) {
override fun canScrollVertically(): Boolean {
return false
}
}
layoutManager.isAutoMeasureEnabled = true
mSubjectRv.isNestedScrollingEnabled = false
mSubjectRv.layoutManager = layoutManager
if (mSubCategoryList.size > 1) {
(mSubjectRv.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
val titleList = arrayListOf<String>()
for (subCategory in mSubCategoryList) {
subCategory.name?.let { titleList.add(it) }
}
val adapter = SubjectTypeAdapter(context, this, titleList, arguments?.getString(EntranceUtils.KEY_CATEGORY_INIT_TITLE))
mSubjectRv.adapter = adapter
}
mType = arguments?.getString(EntranceUtils.KEY_CATEGORY_INIT_TITLE)
loadData()
mAppbar.addOnOffsetChangedListener { appBarLayout, verticalOffset ->
if (!TextUtils.isEmpty(mName)) {
val totalScrollRange = appBarLayout.totalScrollRange
if (Math.abs(verticalOffset) < totalScrollRange / 2) {
if (activity is ToolbarController) {
(activity as ToolbarController).setNavigationTitle(mName)
}
} else if (Math.abs(verticalOffset) == totalScrollRange && totalScrollRange != 0) {
if (activity is ToolbarController) {
(activity as ToolbarController).setNavigationTitle(StringUtils.buildString(mName, "-", mType, ""))
}
}
}
}
}
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 (OPEN_APPBAR == reuse.type && !mIsTouchScreen) {
mAppbar.setExpanded(true, true)
}
}
override fun onSelectType(type: String) {
this.mType = type
loadData()
}
@OnClick(R.id.subject_tabbar_hot_tv, R.id.subject_tabbar_new_tv)
override fun onClick(view: View) {
when (view.id) {
R.id.subject_tabbar_hot_tv -> {
mTabbarHotTv.setTextColor(Color.WHITE)
mTabbarHotTv.setBackgroundResource(R.drawable.tabbar_left_bg)
mTabbarNewTv.setTextColor(Color.BLACK)
mTabbarNewTv.setBackgroundDrawable(ColorDrawable(0))
mListOrder = "download:-1"
loadData()
}
R.id.subject_tabbar_new_tv -> {
mTabbarHotTv.setTextColor(Color.BLACK)
mTabbarHotTv.setBackgroundDrawable(ColorDrawable(0))
mTabbarNewTv.setTextColor(Color.WHITE)
mTabbarNewTv.setBackgroundResource(R.drawable.tabbar_right_bg)
mListOrder = "publish:-1"
loadData()
}
}
}
}

View File

@ -0,0 +1,58 @@
package com.gh.gamecenter.category
import android.os.Bundle
import android.support.v4.view.ViewPager
import android.view.MotionEvent
import android.view.View
import android.widget.LinearLayout
import butterknife.BindView
import com.gh.common.util.EntranceUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.CategoryEntity
import com.gh.gamecenter.normal.NormalFragment
class CategoryListWrapperFragment : NormalFragment() {
@BindView(R.id.subject_viewpager)
lateinit var mViewPager: ViewPager
@BindView(R.id.reuse_ll_loading)
lateinit var mLoading: LinearLayout
@BindView(R.id.reuse_no_connection)
lateinit var mNoConn: View
private var mTabFragment: CategoryListTabFragment? = null
private var mName: String? = ""
override fun getLayoutId(): Int {
return R.layout.fragment_subject_wrapper
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val args = arguments
mName = args?.getParcelable<CategoryEntity>(EntranceUtils.KEY_DATA)?.name
setNavigationTitle(mName)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initView()
}
private fun initView() {
mLoading.visibility = View.GONE
val transaction = childFragmentManager.beginTransaction()
val clone = arguments?.clone() as Bundle
mTabFragment = CategoryListTabFragment()
mTabFragment?.arguments = clone
transaction.add(R.id.subject_tiled, mTabFragment)
transaction.commitAllowingStateLoss()
}
override fun onTouchEvent(event: MotionEvent) {
if (mTabFragment != null) mTabFragment!!.onTouchEvent(event)
}
}

View File

@ -0,0 +1,12 @@
package com.gh.gamecenter.entity
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@Parcelize
data class CategoryEntity(
@SerializedName("_id") var id: String? = "",
var icon: String? = "",
var name: String? = "",
var data: List<CategoryEntity>? = null) : Parcelable

View File

@ -21,6 +21,7 @@ import com.gh.gamecenter.*
import com.gh.gamecenter.adapter.ImagePagerAdapter
import com.gh.gamecenter.adapter.viewholder.*
import com.gh.gamecenter.baselist.LoadStatus
import com.gh.gamecenter.category.CategoryDirectoryActivity
import com.gh.gamecenter.databinding.*
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus

View File

@ -1,6 +1,7 @@
package com.gh.gamecenter.retrofit.service;
import com.gh.gamecenter.entity.AppEntity;
import com.gh.gamecenter.entity.CategoryEntity;
import com.gh.gamecenter.entity.CommentEntity;
import com.gh.gamecenter.entity.CommentnumEntity;
import com.gh.gamecenter.entity.ConcernEntity;
@ -21,9 +22,9 @@ import com.gh.gamecenter.entity.PlatformEntity;
import com.gh.gamecenter.entity.SettingsEntity;
import com.gh.gamecenter.entity.SignEntity;
import com.gh.gamecenter.entity.SlideEntity;
import com.gh.gamecenter.entity.SubjectRecommendEntity;
import com.gh.gamecenter.entity.SubjectEntity;
import com.gh.gamecenter.entity.SubjectHeadEntity;
import com.gh.gamecenter.entity.SubjectRecommendEntity;
import com.gh.gamecenter.entity.TagEntity;
import com.gh.gamecenter.entity.ToolBoxEntity;
import com.gh.gamecenter.entity.UserInfoEntity;
@ -1008,7 +1009,6 @@ public interface ApiService {
@POST("games/{game_id}/servers")
Observable<List<String>> addKaifu(@Body RequestBody body, @Path("game_id") String gameId);
/**
* 获取版块的轮播图
*/
@ -1027,4 +1027,19 @@ public interface ApiService {
*/
@GET("blocks/{block_id}/columns")
Observable<List<SubjectEntity>> getBlockColumns(@Path("block_id") String blockId, @Query("page") int page);
/**
* 获取分类目录
*/
@Headers({"Content-Type: application/json", "Accept: application/json"})
@GET("categories/{category_id}/directories")
Observable<List<CategoryEntity>> getCategories(@Path("category_id") String categoryId, @Query("page") int page);
/**
* 获取分类游戏
*/
@Headers({"Content-Type: application/json", "Accept: application/json"})
@GET("categories/{category_id}/games")
Observable<List<GameEntity>> getGamesInCategory(@Path("category_id") String categoryId, @Query("sort") String sort, @Query("page") int page);
}