diff --git a/app/src/main/java/com/gh/common/constant/ItemViewType.java b/app/src/main/java/com/gh/common/constant/ItemViewType.java index 7d28789e60..7117d0d930 100644 --- a/app/src/main/java/com/gh/common/constant/ItemViewType.java +++ b/app/src/main/java/com/gh/common/constant/ItemViewType.java @@ -24,4 +24,12 @@ public class ItemViewType { public static final int KC_HINT = 17; public static final int GAME_PULGIN = 18; // 游戏插件模块 + /** + * 普通列表 + */ + public static final int ITEM_BODY = 100; + public static final int ITEM_FOOTER = 101; + public static final int ITEM_TOP = 102; + + } diff --git a/app/src/main/java/com/gh/common/view/VerticalItemDecoration.java b/app/src/main/java/com/gh/common/view/VerticalItemDecoration.java index 9980323a2a..c1e1f05cdc 100644 --- a/app/src/main/java/com/gh/common/view/VerticalItemDecoration.java +++ b/app/src/main/java/com/gh/common/view/VerticalItemDecoration.java @@ -15,13 +15,13 @@ public class VerticalItemDecoration extends RecyclerView.ItemDecoration { private Paint paint; private int mInterval = 0; - private boolean isShowIntervalTop; + private boolean mIsShowIntervalTop; public VerticalItemDecoration(Context context, int interval, boolean isShowIntervalTop) { paint = new Paint(); paint.setColor(ContextCompat.getColor(context, R.color.background)); mInterval = DisplayUtils.dip2px(context, interval); - this.isShowIntervalTop = isShowIntervalTop; + mIsShowIntervalTop = isShowIntervalTop; } @Override @@ -35,7 +35,7 @@ public class VerticalItemDecoration extends RecyclerView.ItemDecoration { int top = child.getBottom() + layoutParams.bottomMargin; int bottom = top + mInterval; - if (i == 0 && isShowIntervalTop) { + if (i == 0 && mIsShowIntervalTop) { c.drawRect(left, 0, right, bottom, paint); } else { c.drawRect(left, top, right, bottom, paint); @@ -47,7 +47,7 @@ public class VerticalItemDecoration extends RecyclerView.ItemDecoration { public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { int position = parent.getChildPosition(view); - if (position == 0 && isShowIntervalTop) { + if (position == 0 && mIsShowIntervalTop) { outRect.set(0, mInterval, 0, mInterval); } else { outRect.set(0, 0, 0, mInterval); diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/FooterViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/FooterViewHolder.java index bd10106f8e..4ac0836700 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/FooterViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/FooterViewHolder.java @@ -6,6 +6,7 @@ import android.widget.ProgressBar; import android.widget.TextView; import com.gh.base.BaseRecyclerViewHolder; +import com.gh.base.OnListClickListener; import com.gh.gamecenter.R; import butterknife.BindView; @@ -35,11 +36,36 @@ public class FooterViewHolder extends BaseRecyclerViewHolder { super(itemView); } + public FooterViewHolder(View itemView, Object data, OnListClickListener listClickListener) { + super(itemView, data, listClickListener); + itemView.setOnClickListener(this); + } + // 减去recyclerView item间隔(个别列表间隔很大) public void initItemPadding() { itemView.setPadding(0, 0, 0, 0); } + public void initFooterViewHolder(boolean isNetworkError, boolean isOver) { + if (isNetworkError) { + lineLeft.setVisibility(View.GONE); + lineRight.setVisibility(View.GONE); + loading.setVisibility(View.GONE); + hint.setText(R.string.loading_failed_retry); + } else if (isOver) { + lineLeft.setVisibility(View.VISIBLE); + lineRight.setVisibility(View.VISIBLE); + loading.setVisibility(View.GONE); + hint.setText(R.string.loading_complete); + } else { + lineLeft.setVisibility(View.GONE); + lineRight.setVisibility(View.GONE); + loading.setVisibility(View.VISIBLE); + hint.setText(R.string.loading); + } + } + + public void initFooterViewHolder(boolean mIsNetworkError, boolean mIsOver, OnClickListener onClickListener) { if (mIsNetworkError) { lineLeft.setVisibility(View.GONE); diff --git a/app/src/main/java/com/gh/gamecenter/ask/AskFragment.java b/app/src/main/java/com/gh/gamecenter/ask/AskFragment.java new file mode 100644 index 0000000000..9b3671242a --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/ask/AskFragment.java @@ -0,0 +1,93 @@ +package com.gh.gamecenter.ask; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.View; +import android.widget.CheckedTextView; +import android.widget.ImageView; +import android.widget.TextView; + +import com.gh.base.adapter.FragmentAdapter; +import com.gh.base.fragment.BaseFragment; +import com.gh.gamecenter.R; +import com.lightgame.view.NoScrollableViewPager; + +import java.util.ArrayList; + +import butterknife.BindView; +import butterknife.OnClick; + +/** + * Created by khy on 2/12/17. + */ + +public class AskFragment extends BaseFragment { + + @BindView(R.id.ask_selectgame) + ImageView mAskSelectgame; + @BindView(R.id.ask_gamename) + TextView mAskGamename; + @BindView(R.id.ask_search) + ImageView mAskSearch; + @BindView(R.id.ask_hot) + CheckedTextView mAskHot; + @BindView(R.id.ask_questions) + CheckedTextView mAskQuestions; + @BindView(R.id.ask_viewpager) + NoScrollableViewPager mAskViewpager; + + public static final int INDEX_HOT = 0; + public static final int INDEX_QUESTIONS = 1; + + @Override + protected int getLayoutId() { + return R.layout.fragment_ask; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initViewPager(); + setTabbarPosition(INDEX_HOT); + } + + @OnClick({R.id.ask_selectgame, R.id.ask_search, R.id.ask_hot, R.id.ask_questions}) + public void onViewClicked(View view) { + switch (view.getId()) { + case R.id.ask_selectgame: + break; + case R.id.ask_search: + break; + case R.id.ask_hot: + setTabbarPosition(INDEX_HOT); + break; + case R.id.ask_questions: + setTabbarPosition(INDEX_QUESTIONS); + break; + } + } + + private void initViewPager() { + ArrayList fragmentList = new ArrayList<>(); + fragmentList.add(new AskHotFragment()); + fragmentList.add(new AskQuestionsFragment()); + mAskViewpager.setAdapter(new FragmentAdapter(getChildFragmentManager(), fragmentList)); + mAskViewpager.setScrollable(false); + } + + private void setTabbarPosition(int index) { + switch (index) { + case INDEX_HOT: + mAskHot.setChecked(true); + mAskQuestions.setChecked(false); + break; + case INDEX_QUESTIONS: + mAskHot.setChecked(false); + mAskQuestions.setChecked(true); + break; + } + mAskViewpager.setCurrentItem(index); + } +} diff --git a/app/src/main/java/com/gh/gamecenter/ask/AskHotAdapter.java b/app/src/main/java/com/gh/gamecenter/ask/AskHotAdapter.java new file mode 100644 index 0000000000..feabf2c96c --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/ask/AskHotAdapter.java @@ -0,0 +1,98 @@ +package com.gh.gamecenter.ask; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.view.ViewGroup; + +import com.gh.base.OnListClickListener; +import com.gh.common.constant.ItemViewType; +import com.gh.gamecenter.R; +import com.gh.gamecenter.adapter.viewholder.FooterViewHolder; +import com.gh.gamecenter.baselist.BaseListAdapter; +import com.gh.gamecenter.baselist.LoadStatus; +import com.gh.gamecenter.entity.NewsEntity; + +import java.util.List; + +/** + * Created by khy on 2/12/17. + */ + +public class AskHotAdapter extends BaseListAdapter { + + private OnListClickListener mListClickListener; + + private List mEntityList; + + public AskHotAdapter(Context context, OnListClickListener listClickListener) { + super(context); + mListClickListener = listClickListener; + } + + @NonNull + @Override + protected void provideListData(List listData) { + mEntityList = (List) listData; + notifyDataSetChanged(); + } + + @Override + protected void loadChange(LoadStatus status) { + switch (status) { + case over: + mIsOver = true; + break; + case error: + mIsNetworkError = true; + break; + case retry: + mIsNetworkError = false; + break; + } + notifyItemChanged(getItemCount() - 1); + } + + @Override + public int getItemViewType(int position) { + if (position == getItemCount() - 1) return ItemViewType.ITEM_FOOTER; + return ItemViewType.ITEM_BODY; + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view; + switch (viewType) { + case ItemViewType.ITEM_FOOTER: + view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false); + return new FooterViewHolder(view, null, mListClickListener); + case ItemViewType.ITEM_BODY: + view = mLayoutInflater.inflate(R.layout.ask_item, parent, false); + return new AskItemViewHolder(view, mEntityList, mListClickListener); + default: + return null; + } + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + switch (getItemViewType(position)) { + case ItemViewType.ITEM_BODY: + NewsEntity newsEntity = mEntityList.get(position); + AskItemViewHolder askHolder = (AskItemViewHolder) holder; + askHolder.mAskUsername.setText(newsEntity.getTitle()); + break; + case ItemViewType.ITEM_FOOTER: + FooterViewHolder footerViewHolder = (FooterViewHolder) holder; + footerViewHolder.initItemPadding(); + footerViewHolder.initFooterViewHolder(mIsNetworkError, mIsOver); + break; + } + } + + @Override + public int getItemCount() { + return mEntityList == null || mEntityList.isEmpty() ? 0 : mEntityList.size() + FOOTER_ITEM_COUNT; + } +} diff --git a/app/src/main/java/com/gh/gamecenter/ask/AskHotFragment.java b/app/src/main/java/com/gh/gamecenter/ask/AskHotFragment.java new file mode 100644 index 0000000000..b804e685de --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/ask/AskHotFragment.java @@ -0,0 +1,48 @@ +package com.gh.gamecenter.ask; + +import android.view.View; + +import com.gh.gamecenter.R; +import com.gh.gamecenter.baselist.BaseListAdapter; +import com.gh.gamecenter.baselist.ListFragment; +import com.gh.gamecenter.baselist.LoadStatus; +import com.gh.gamecenter.baselist.LoadType; +import com.gh.gamecenter.entity.NewsEntity; +import com.gh.gamecenter.retrofit.RetrofitManager; + +import java.util.List; + +import rx.Observable; + +/** + * Created by khy on 2/12/17. + */ + +public class AskHotFragment extends ListFragment { + + private AskHotAdapter mAdapter; + + @SuppressWarnings("unchecked") + @Override + public Observable> provideDataObservable() { + return RetrofitManager.getInstance(getContext()).getApi().getZiXun(getListOffset()); + } + + @Override + protected BaseListAdapter provideListAdapter() { + return mAdapter == null ? mAdapter = new AskHotAdapter(getContext(), this) : mAdapter; + } + + @Override + public void onListClick(View view, int position, Object data) { + switch (view.getId()) { + case R.id.footerview_item: + if (mAdapter.isNetworkError()) { + mAdapter.loadChange(LoadStatus.retry); + mListViewModel.load(LoadType.retry); + } + break; + } + + } +} diff --git a/app/src/main/java/com/gh/gamecenter/ask/AskItemViewHolder.java b/app/src/main/java/com/gh/gamecenter/ask/AskItemViewHolder.java new file mode 100644 index 0000000000..a87ca99370 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/ask/AskItemViewHolder.java @@ -0,0 +1,37 @@ +package com.gh.gamecenter.ask; + +import android.view.View; +import android.widget.TextView; + +import com.facebook.drawee.view.SimpleDraweeView; +import com.gh.base.BaseRecyclerViewHolder; +import com.gh.base.OnListClickListener; +import com.gh.gamecenter.R; + +import butterknife.BindView; + +/** + * Created by khy on 4/12/17. + */ + +public class AskItemViewHolder extends BaseRecyclerViewHolder { + + + @BindView(R.id.ask_item_usericon) + SimpleDraweeView mAskUsericon; + @BindView(R.id.ask_item_username) + TextView mAskUsername; + @BindView(R.id.ask_item_title) + TextView mAskTitle; + @BindView(R.id.ask_item_content) + TextView mAskContent; + @BindView(R.id.ask_item_img) + SimpleDraweeView mAskImg; + @BindView(R.id.ask_item_votecount) + TextView mAskVotecount; + + public AskItemViewHolder(View itemView, Object data, OnListClickListener listClickListener) { + super(itemView, data, listClickListener); + itemView.setOnClickListener(this); + } +} diff --git a/app/src/main/java/com/gh/gamecenter/ask/AskQuestionsFragment.java b/app/src/main/java/com/gh/gamecenter/ask/AskQuestionsFragment.java new file mode 100644 index 0000000000..4d18f6f3f8 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/ask/AskQuestionsFragment.java @@ -0,0 +1,15 @@ +package com.gh.gamecenter.ask; + +import com.gh.base.fragment.BaseFragment; +import com.gh.gamecenter.R; + +/** + * Created by khy on 2/12/17. + */ + +public class AskQuestionsFragment extends BaseFragment { + @Override + protected int getLayoutId() { + return R.layout.game_normal_item; + } +} diff --git a/app/src/main/java/com/gh/gamecenter/baselist/BaseListAdapter.java b/app/src/main/java/com/gh/gamecenter/baselist/BaseListAdapter.java index f4a57cc68f..b7d495daf4 100644 --- a/app/src/main/java/com/gh/gamecenter/baselist/BaseListAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/baselist/BaseListAdapter.java @@ -12,13 +12,21 @@ import java.util.List; public abstract class BaseListAdapter extends BaseRecyclerAdapter { + protected static final int FOOTER_ITEM_COUNT = 1; + + protected boolean mIsOver; + + protected boolean mIsNetworkError; + public BaseListAdapter(Context context) { super(context); } protected abstract void provideListData(List listData); - protected abstract void loadError(Throwable e); + protected abstract void loadChange(LoadStatus status); - protected abstract void refreshData(); + public boolean isNetworkError() { + return mIsNetworkError; + } } diff --git a/app/src/main/java/com/gh/gamecenter/baselist/BaseListContrat.java b/app/src/main/java/com/gh/gamecenter/baselist/BaseListContrat.java deleted file mode 100644 index b067a4ab15..0000000000 --- a/app/src/main/java/com/gh/gamecenter/baselist/BaseListContrat.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.gh.gamecenter.baselist; - -import android.view.View; - -import java.util.List; - -import rx.Observable; - -/** - * Created by khy on 6/11/17. - */ -class BaseListContrat { - - interface ListAppView { - - /** - * 加载完成(不是结束) - * - * @param dataList 当前加载数据(不是全部) - * @param - */ - void LoadFinish(List dataList); - - /** - * 加载失败,注意首次加载和分页加载 - * - * @param e - */ - void LoadError(Throwable e); - - /** - * 提供数据源头 - * - * @param - * @return - */ - Observable> provideDataObservable(); - - /** - * 列表 RecyclerView Adapter - * - * @return - */ - BaseListAdapter provideRecyclerAdapter(); - - } - - interface BaseListPresenter { - - /** - * 加载数据, 无论是初始化还是分页都只用一个(注意控制 ListSize-offset) - */ - void load(); - - /** - * 加载重试 - */ - void retryLoad(); - - /** - * 提供 Fragment View 可以不传, 不传的话自己搞 - * - * @param view Fragment View - */ - void provideView(View view); - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/baselist/BaseListFragment.java b/app/src/main/java/com/gh/gamecenter/baselist/BaseListFragment.java deleted file mode 100644 index 749bf949e3..0000000000 --- a/app/src/main/java/com/gh/gamecenter/baselist/BaseListFragment.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.gh.gamecenter.baselist; - -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.view.View; - -import com.gh.base.fragment.BaseFragment; -import com.gh.gamecenter.R; - -import java.util.List; - -/** - * Created by khy on 11/11/17. - */ - -public abstract class BaseListFragment extends BaseFragment implements BaseListContrat.ListAppView { - - protected BaseListPresenterImpl mListPresenter; - - @Override - protected int getLayoutId() { - return R.layout.fragment_list_base; - } - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mListPresenter = new BaseListPresenterImpl(this, getContext()); - } - - @Override - public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - mListPresenter.provideView(view); - } - - protected abstract BaseListAdapter provideAdapter(); - - @Override - public void LoadFinish(List dataList) { - provideAdapter().provideListData(dataList); - } - - @Override - public void LoadError(Throwable e) { - provideAdapter().loadError(e); - } - - @Override - public BaseListAdapter provideRecyclerAdapter() { - return provideAdapter(); - } -} diff --git a/app/src/main/java/com/gh/gamecenter/baselist/BaseListPresenterImpl.java b/app/src/main/java/com/gh/gamecenter/baselist/BaseListPresenterImpl.java deleted file mode 100644 index f7f91fbb5b..0000000000 --- a/app/src/main/java/com/gh/gamecenter/baselist/BaseListPresenterImpl.java +++ /dev/null @@ -1,206 +0,0 @@ -package com.gh.gamecenter.baselist; - -import android.content.Context; -import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.View; - -import com.gh.gamecenter.R; -import com.gh.gamecenter.retrofit.Response; -import com.lightgame.utils.Utils; - -import java.util.List; - -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; - -/** - * Created by khy on 6/11/17. - */ - -public class BaseListPresenterImpl implements BaseListContrat.BaseListPresenter { - - public final static int PAGE_SIZE = 20; - - private final static String TAG = "BaseListPresenterImpl"; - - private Context mContext; - - private BaseListContrat.ListAppView mListAppView; - - private RecyclerView mListRv; - private SwipeRefreshLayout mRefreshLayout; - private View mLoadingView; - private View mNoConnView; - private View mNoDataView; - - private LinearLayoutManager mLayoutManager; - - private int mListSize; // 相当于load offset - - private boolean mIsLoading; - private boolean mIsNetworkError; - private boolean mIsOver; - - public BaseListPresenterImpl(BaseListContrat.ListAppView listAppView, Context context) { - this.mListAppView = listAppView; - this.mContext = context; - this.mListSize = 0; - } - - @Override - public void provideView(View view) { - if (view == null) { - Utils.log(TAG, "provideView View 为空, Fragment自己处理"); - return; - } - - if (mListAppView.provideRecyclerAdapter() == null) { - throw new NullPointerException("recycler is null - 请注意初始化先后顺序"); - } - - mLayoutManager = new LinearLayoutManager(mContext); - - mLoadingView = view.findViewById(R.id.list_loading); - mNoConnView = view.findViewById(R.id.reuse_no_connection); - mNoDataView = view.findViewById(R.id.reuse_none_data); - mRefreshLayout = view.findViewById(R.id.list_refresh); - mRefreshLayout.setColorSchemeResources(R.color.theme); - mListRv = view.findViewById(R.id.list_rv); - mListRv.setLayoutManager(mLayoutManager); - mListRv.setAdapter(mListAppView.provideRecyclerAdapter()); - - mListRv.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrollStateChanged(RecyclerView recyclerView, int newState) { - super.onScrollStateChanged(recyclerView, newState); - if (newState == RecyclerView.SCROLL_STATE_IDLE - && mLayoutManager.findLastVisibleItemPosition() + 1 == mLayoutManager.getItemCount()) { - if (!mIsOver && !mIsNetworkError && !mIsLoading) { - load(); - } - } - } - }); - - mRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - initListStatus(); - mListAppView.provideRecyclerAdapter().refreshData(); - load(); - } - }); - - mNoConnView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - initListStatus(); - initLoadView(true, false, -1, -1); - load(); - } - }); - } - - @Override - public void load() { - if (mListAppView.provideDataObservable() == null) { - throw new NullPointerException("List data Observable is null"); - } - - mIsLoading = true; - - mListAppView - .provideDataObservable() - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Response>() { - @Override - public void onNext(List response) { - super.onNext(response); - int size = response.size(); - - mListAppView.LoadFinish(response); - - initLoadView(false, false, mListSize, size); - - if (size < PAGE_SIZE) { - mIsOver = true; - } - - mIsLoading = false; - mIsNetworkError = false; - - mListSize += size; - } - - @Override - public void onError(Throwable e) { - super.onError(e); - - mIsLoading = false; - mIsNetworkError = true; - - mListAppView.LoadError(e); - - initLoadView(false, true, mListSize, -1); - } - }); - } - - @Override - public void retryLoad() { - mIsLoading = false; - mIsOver = false; - mIsNetworkError = false; - load(); - } - - - public int getListOffset() { - return mListSize; - } - - - private void initListStatus() { - mIsLoading = false; - mIsOver = false; - mIsNetworkError = false; - mListSize = 0; - } - - private void initLoadView(boolean isRefresh, boolean isLoadError, int offset, int curListSize) { - if (mLoadingView != null && mNoConnView != null && mNoDataView != null) { - - if (isRefresh) { // 下拉刷新 - mLoadingView.setVisibility(View.VISIBLE); - mNoDataView.setVisibility(View.GONE); - mNoConnView.setVisibility(View.GONE); - mListRv.setVisibility(View.GONE); - mRefreshLayout.setRefreshing(false); - - } else if (isLoadError && offset == 0) { // 加载失败(第一页) - mLoadingView.setVisibility(View.GONE); - mNoDataView.setVisibility(View.GONE); - mNoConnView.setVisibility(View.VISIBLE); - mListRv.setVisibility(View.GONE); - mRefreshLayout.setRefreshing(false); - - } else if (offset == 0 && curListSize == 0) { // 数据数据为空 - mLoadingView.setVisibility(View.GONE); - mNoDataView.setVisibility(View.VISIBLE); - mNoConnView.setVisibility(View.GONE); - mListRv.setVisibility(View.GONE); - mRefreshLayout.setRefreshing(false); - - } else { // 正常加载 - mLoadingView.setVisibility(View.GONE); - mNoDataView.setVisibility(View.GONE); - mNoConnView.setVisibility(View.GONE); - mListRv.setVisibility(View.VISIBLE); - mRefreshLayout.setRefreshing(false); - } - } - } -} diff --git a/app/src/main/java/com/gh/gamecenter/baselist/ListFragment.java b/app/src/main/java/com/gh/gamecenter/baselist/ListFragment.java new file mode 100644 index 0000000000..a07c947fce --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/baselist/ListFragment.java @@ -0,0 +1,144 @@ +package com.gh.gamecenter.baselist; + +import android.arch.lifecycle.Observer; +import android.arch.lifecycle.ViewModelProviders; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.LinearLayout; + +import com.gc.materialdesign.views.ProgressBarCircularIndeterminate; +import com.gh.base.fragment.BaseFragment; +import com.gh.common.view.VerticalItemDecoration; +import com.gh.gamecenter.R; + +import java.util.List; + +import butterknife.BindView; +import butterknife.OnClick; + +/** + * Created by khy on 2/12/17. + */ + +public abstract class ListFragment extends BaseFragment implements + Observer>, + OnListLoadListener, + SwipeRefreshLayout.OnRefreshListener { + + @BindView(R.id.list_rv) + RecyclerView mListRv; + @BindView(R.id.list_refresh) + SwipeRefreshLayout mListRefresh; + @BindView(R.id.list_loading) + ProgressBarCircularIndeterminate mListLoading; + @BindView(R.id.reuse_no_connection) + LinearLayout mReuseNoConn; + @BindView(R.id.reuse_none_data) + LinearLayout mReuseNoData; + + private LinearLayoutManager mLayoutManager; + + protected ListViewModel mListViewModel; + + protected abstract BaseListAdapter provideListAdapter(); + + + @Override + protected int getLayoutId() { + return R.layout.fragment_list_base; + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + final ListViewModel.Factory factory = new ListViewModel.Factory(getActivity().getApplication(), this); + mListViewModel = ViewModelProviders.of(this, factory).get(ListViewModel.class); + mListViewModel.getObsListData().observe(this, this); + mListViewModel.load(LoadType.nomarl); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + mListRefresh.setOnRefreshListener(this); + mLayoutManager = new LinearLayoutManager(getContext()); + mListRv.setLayoutManager(mLayoutManager); + mListRv.setAdapter(provideListAdapter()); + mListRv.addItemDecoration(new VerticalItemDecoration(getContext(), 8, true)); + mListRv.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + if (mLayoutManager.findLastVisibleItemPosition() == provideListAdapter().getItemCount() - 1 && + RecyclerView.SCROLL_STATE_IDLE == newState) + mListViewModel.load(LoadType.nomarl); + } + }); + } + + protected int getListOffset() { + return mListViewModel == null ? 0 : mListViewModel.getListOffset(); + } + + @Override + public void onRefresh() { + mListViewModel.load(LoadType.refresh); + } + + @Override + public void onChanged(@Nullable List ts) { + provideListAdapter().provideListData(ts); + } + + @OnClick(R.id.reuse_no_connection) + public void onClick(View view) { + mReuseNoConn.setVisibility(View.GONE); + mReuseNoData.setVisibility(View.GONE); + mListLoading.setVisibility(View.VISIBLE); + mListRv.setVisibility(View.GONE); + mListRefresh.setRefreshing(false); + + mListViewModel.load(LoadType.refresh); + } + + @Override + public void onLoadDone() { + mReuseNoConn.setVisibility(View.GONE); + mReuseNoData.setVisibility(View.GONE); + mListLoading.setVisibility(View.GONE); + mListRv.setVisibility(View.VISIBLE); + mListRefresh.setRefreshing(false); + } + + @Override + public void onLoadError() { + mReuseNoConn.setVisibility(View.VISIBLE); + mReuseNoData.setVisibility(View.GONE); + mListLoading.setVisibility(View.GONE); + mListRv.setVisibility(View.GONE); + mListRefresh.setRefreshing(false); + } + + @Override + public void onLoadEmpty() { + mReuseNoConn.setVisibility(View.GONE); + mReuseNoData.setVisibility(View.VISIBLE); + mListLoading.setVisibility(View.GONE); + mListRv.setVisibility(View.GONE); + mListRefresh.setRefreshing(false); + } + + @Override + public void onLoadMoreError() { + provideListAdapter().loadChange(LoadStatus.error); + } + + @Override + public void onLoadOver() { + provideListAdapter().loadChange(LoadStatus.over); + } +} diff --git a/app/src/main/java/com/gh/gamecenter/baselist/ListRepository.java b/app/src/main/java/com/gh/gamecenter/baselist/ListRepository.java new file mode 100644 index 0000000000..4ae36d9287 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/baselist/ListRepository.java @@ -0,0 +1,123 @@ +package com.gh.gamecenter.baselist; + +import android.arch.lifecycle.LiveData; +import android.arch.lifecycle.MutableLiveData; + +import com.gh.gamecenter.retrofit.Response; + +import java.util.ArrayList; +import java.util.List; + +import retrofit2.HttpException; +import rx.Observable; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +/** + * Created by khy on 2/12/17. + */ + +public class ListRepository { + + public final static int PAGE_SIZE = 20; + + private MutableLiveData> mListLiveData; + private List mCacheListData; + + private OnListLoadListener mLoadListener; + + private boolean mIsLoading; + private boolean mIsOver; + private boolean mIsNetworkError; + + private int mListOffset; + + + public ListRepository(OnListLoadListener loadListener) { + mListOffset = 0; + mLoadListener = loadListener; + mCacheListData = new ArrayList<>(); + mListLiveData = new MutableLiveData<>(); + } + + private void loadData() { + Observable> listObservable = mLoadListener.provideDataObservable(); + + if (mIsLoading || mIsOver || mIsNetworkError || listObservable == null) return; + + mIsLoading = true; + + listObservable + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Response>() { + @Override + public void onResponse(List response) { + super.onResponse(response); + int size = response.size(); + if (size == 0) { + mLoadListener.onLoadEmpty(); + } else { + if (size < PAGE_SIZE) { + mIsOver = true; + mLoadListener.onLoadOver(); + } + mIsLoading = false; + mIsNetworkError = false; + mListOffset += size; + mLoadListener.onLoadDone(); + cacheAndNotifyListData(response); + } + } + + @Override + public void onFailure(HttpException e) { + super.onFailure(e); + mIsLoading = false; + mIsNetworkError = true; + if (mListOffset > 0) { + mLoadListener.onLoadMoreError(); + } else { + mLoadListener.onLoadError(); + } + } + }); + } + + private void resetOffset() { + mListOffset = 0; + mIsOver = false; + mIsNetworkError = false; + mCacheListData.clear(); + } + + protected void load(LoadType loadType) { + if (loadType == null) loadType = LoadType.nomarl; + switch (loadType) { + case refresh: + resetOffset(); + break; + case retry: + mIsNetworkError = false; + break; + } + loadData(); + } + + protected int getListOffset() { + return mListOffset; + } + + + private void cacheAndNotifyListData(List listData) { + mCacheListData.addAll(listData); + mListLiveData.postValue(mCacheListData); + } + + public LiveData> getListLiveData() { + if (mCacheListData != null) { + mListLiveData.postValue(mCacheListData); + } + return mListLiveData; + } +} diff --git a/app/src/main/java/com/gh/gamecenter/baselist/ListViewModel.java b/app/src/main/java/com/gh/gamecenter/baselist/ListViewModel.java new file mode 100644 index 0000000000..8c8ca34b5e --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/baselist/ListViewModel.java @@ -0,0 +1,61 @@ +package com.gh.gamecenter.baselist; + +import android.app.Application; +import android.arch.lifecycle.AndroidViewModel; +import android.arch.lifecycle.LiveData; +import android.arch.lifecycle.ViewModel; +import android.arch.lifecycle.ViewModelProvider; +import android.support.annotation.NonNull; + +import java.util.List; + +/** + * Created by khy on 2/12/17. + */ + +public class ListViewModel extends AndroidViewModel { + + private ListRepository mRepository; + + private LiveData> mLiveListData; + + + public ListViewModel(Application application, ListRepository repository) { + super(application); + mRepository = repository; + mLiveListData = mRepository.getListLiveData(); + + } + + public LiveData> getObsListData() { + return mLiveListData; + } + + + public void load(LoadType loadType) { + mRepository.load(loadType); + } + + public int getListOffset() { + return mRepository.getListOffset(); + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + @NonNull + private final Application mApplication; + + private final ListRepository mRepository; + + public Factory(@NonNull Application application, OnListLoadListener loadListener) { + mApplication = application; + mRepository = new ListRepository(loadListener); + } + + @Override + public T create(Class modelClass) { + //noinspection unchecked + return (T) new ListViewModel(mApplication, mRepository); + } + } + +} diff --git a/app/src/main/java/com/gh/gamecenter/baselist/LoadStatus.java b/app/src/main/java/com/gh/gamecenter/baselist/LoadStatus.java new file mode 100644 index 0000000000..67205ce07c --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/baselist/LoadStatus.java @@ -0,0 +1,22 @@ +package com.gh.gamecenter.baselist; + +/** + * Created by khy on 4/12/17. + */ + +public enum LoadStatus { + + error("error"), + + over("over"), + + refresh("refresh"), + + retry("retry"); + + private String mStatus; + + LoadStatus(String status) { + mStatus = status; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/baselist/LoadType.java b/app/src/main/java/com/gh/gamecenter/baselist/LoadType.java new file mode 100644 index 0000000000..efc1508ddc --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/baselist/LoadType.java @@ -0,0 +1,20 @@ +package com.gh.gamecenter.baselist; + +/** + * Created by khy on 4/12/17. + */ + +public enum LoadType { + + nomarl("nomarl"), + + refresh("refresh"), + + retry("retry"); + + private String mStatus; + + LoadType(String status) { + mStatus = status; + } +} diff --git a/app/src/main/java/com/gh/gamecenter/baselist/OnListLoadListener.java b/app/src/main/java/com/gh/gamecenter/baselist/OnListLoadListener.java new file mode 100644 index 0000000000..191fa7da9c --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/baselist/OnListLoadListener.java @@ -0,0 +1,29 @@ +package com.gh.gamecenter.baselist; + +import java.util.List; + +import rx.Observable; + +/** + * Created by khy on 2/12/17. + */ + +public interface OnListLoadListener { + + void onLoadDone(); + + void onLoadError(); + + void onLoadMoreError(); + + void onLoadEmpty(); + + void onLoadOver(); + + /** + * 列表数据接口 先放这里吧 + * @param + * @return + */ + Observable> provideDataObservable(); +} diff --git a/app/src/main/java/com/gh/gamecenter/baselist/TestAdapter.java b/app/src/main/java/com/gh/gamecenter/baselist/TestAdapter.java deleted file mode 100644 index 8914653a57..0000000000 --- a/app/src/main/java/com/gh/gamecenter/baselist/TestAdapter.java +++ /dev/null @@ -1,259 +0,0 @@ -package com.gh.gamecenter.baselist; - -import android.content.Context; -import android.support.v7.widget.RecyclerView; -import android.util.DisplayMetrics; -import android.view.View; -import android.view.ViewGroup; -import android.widget.LinearLayout; - -import com.gh.base.OnListClickListener; -import com.gh.common.constant.ItemViewType; -import com.gh.common.util.DisplayUtils; -import com.gh.common.util.ImageUtils; -import com.gh.common.util.NewsUtils; -import com.gh.gamecenter.R; -import com.gh.gamecenter.adapter.viewholder.FooterViewHolder; -import com.gh.gamecenter.adapter.viewholder.NewsImage1ViewHolder; -import com.gh.gamecenter.adapter.viewholder.NewsImage2ViewHolder; -import com.gh.gamecenter.adapter.viewholder.NewsImage3ViewHolder; -import com.gh.gamecenter.entity.NewsEntity; -import com.gh.gamecenter.manager.VisitManager; -import com.gh.gamecenter.retrofit.JSONObjectResponse; -import com.gh.gamecenter.retrofit.RetrofitManager; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Locale; - -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; - -/** - * Created by khy on 10/11/17. - * 测试例子 - */ - -public class TestAdapter extends BaseListAdapter { - - private OnListClickListener mListListener; - - private BaseListPresenterImpl mListPresenter; - - private List mEntityList; - - private boolean mIsLoadOver; - private boolean mIsNetworkError; - - public TestAdapter(Context context, BaseListPresenterImpl objectListPresenter, OnListClickListener listListener) { - super(context); - - mEntityList = new ArrayList<>(); - this.mListPresenter = objectListPresenter; - this.mListListener = listListener; - } - - @SuppressWarnings("unchecked") - @Override - protected void provideListData(List listData) { - if (listData.size() < BaseListPresenterImpl.PAGE_SIZE) { - mIsLoadOver = true; - } - - mIsNetworkError = false; - mEntityList.addAll((Collection) listData); - notifyDataSetChanged(); - } - - @Override - protected void loadError(Throwable e) { - mIsNetworkError = true; - notifyItemChanged(getItemCount() - 1); - } - - @Override - protected void refreshData() { - mEntityList.clear(); - notifyDataSetChanged(); - } - - @Override - public int getItemViewType(int position) { - if (position == mEntityList.size()) { - return ItemViewType.LOADING; - } - NewsEntity newsEntity = mEntityList.get(position); - if ("4x3".equals(newsEntity.getThumbnail().getType()) && newsEntity.getThumbnail().getUrl().size() == 3) { - return ItemViewType.NEWS_IMAGE2; - } - if ("3x1".equals(newsEntity.getThumbnail().getType())) { - return ItemViewType.NEWS_IMAGE3; - } - return ItemViewType.NEWS_IMAGE1; - } - - @Override - public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view; - switch (viewType) { - case ItemViewType.NEWS_IMAGE1: - view = mLayoutInflater.inflate(R.layout.news_image1_item, parent, false); - return new NewsImage1ViewHolder(view, mEntityList, mListListener); - case ItemViewType.NEWS_IMAGE2: - view = mLayoutInflater.inflate(R.layout.news_image2_item, parent, false); - return new NewsImage2ViewHolder(view, mEntityList, mListListener); - case ItemViewType.NEWS_IMAGE3: - view = mLayoutInflater.inflate(R.layout.news_image3_item, parent, false); - return new NewsImage3ViewHolder(view, mEntityList, mListListener); - case ItemViewType.LOADING: - return new FooterViewHolder(mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false)); - default: - return null; - } - } - - @Override - public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { - switch (getItemViewType(position)) { - case ItemViewType.NEWS_IMAGE1: - initNewsImage1ViewHolder((NewsImage1ViewHolder) holder, position); - break; - case ItemViewType.NEWS_IMAGE2: - initNewsImage2ViewHolder((NewsImage2ViewHolder) holder, position); - break; - case ItemViewType.NEWS_IMAGE3: - initNewsImage3ViewHolder((NewsImage3ViewHolder) holder, position); - break; - case ItemViewType.LOADING: - initFooterViewHolder((FooterViewHolder) holder); - break; - } - } - - @Override - public int getItemCount() { - return mEntityList.size() + 1; - } - - - private void initNewsImage1ViewHolder(final NewsImage1ViewHolder viewHolder, int position) { - - final NewsEntity newsEntity = mEntityList.get(position); - ImageUtils.Companion.display(viewHolder.thumb, newsEntity.getThumbnail().getUrl().get(0)); - viewHolder.title.setText(newsEntity.getTitle()); - int views = newsEntity.getViews(); - if (views == 0) { - viewHolder.read.setVisibility(View.GONE); - } else { - viewHolder.read.setVisibility(View.VISIBLE); - viewHolder.read.setText(String.format(Locale.getDefault(), "阅读 %d", views)); - } - NewsUtils.setNewsType(viewHolder.type, newsEntity.getType(), newsEntity.getPriority(), position); - } - - private void initNewsImage2ViewHolder(final NewsImage2ViewHolder viewHolder, int position) { - - final NewsEntity newsEntity = mEntityList.get(position); - - DisplayMetrics outMetrics = new DisplayMetrics(); - int width = (outMetrics.widthPixels - DisplayUtils.dip2px(mContext, 56)) / 3; - int height = (int) (width * 3 / 4f); - - LinearLayout.LayoutParams lparams1 = new LinearLayout.LayoutParams(width, height); - viewHolder.thumb1.setLayoutParams(lparams1); - - LinearLayout.LayoutParams lparams2 = new LinearLayout.LayoutParams(width, height); - lparams2.leftMargin = DisplayUtils.dip2px(mContext, 8); - viewHolder.thumb2.setLayoutParams(lparams2); - - LinearLayout.LayoutParams lparams3 = new LinearLayout.LayoutParams(width, height); - lparams3.leftMargin = DisplayUtils.dip2px(mContext, 8); - viewHolder.thumb3.setLayoutParams(lparams3); - - viewHolder.title.setText(newsEntity.getTitle()); - - ImageUtils.Companion.display(viewHolder.thumb1, newsEntity.getThumbnail().getUrl().get(0)); - ImageUtils.Companion.display(viewHolder.thumb2, newsEntity.getThumbnail().getUrl().get(1)); - ImageUtils.Companion.display(viewHolder.thumb3, newsEntity.getThumbnail().getUrl().get(2)); - int views = newsEntity.getViews(); - if (views == 0) { - viewHolder.read.setVisibility(View.GONE); - } else { - viewHolder.read.setVisibility(View.VISIBLE); - viewHolder.read.setText(String.format(Locale.getDefault(), "阅读 %d", views)); - } - NewsUtils.setNewsType(viewHolder.type, newsEntity.getType(), newsEntity.getPriority(), position); - } - - private void initNewsImage3ViewHolder(final NewsImage3ViewHolder viewHolder, int position) { - - final NewsEntity newsEntity = mEntityList.get(position); - - viewHolder.title.setText(newsEntity.getTitle()); - ImageUtils.Companion.getInstance().display(viewHolder.thumb, newsEntity.getThumbnail().getUrl().get(0), - mContext.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(mContext, 40)); - int views = newsEntity.getViews(); - if (views == 0) { - viewHolder.read.setVisibility(View.GONE); - } else { - viewHolder.read.setVisibility(View.VISIBLE); - viewHolder.read.setText(String.format(Locale.getDefault(), "阅读 %d", views)); - } - NewsUtils.setNewsType(viewHolder.type, newsEntity.getType(), newsEntity.getPriority(), position); - } - - 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(new View.OnClickListener() { - @Override - public void onClick(View v) { - mIsNetworkError = false; - notifyItemChanged(getItemCount() - 1); - mListPresenter.retryLoad(); - } - }); - } else if (mIsLoadOver) { - viewHolder.loading.setVisibility(View.GONE); - viewHolder.hint.setText(R.string.loading_complete); - viewHolder.itemView.setClickable(false); - } else { - viewHolder.loading.setVisibility(View.VISIBLE); - viewHolder.hint.setText(R.string.loading); - viewHolder.itemView.setClickable(false); - } - } - - // 统计新闻阅读量 - public void statNewsViews(final NewsEntity newsEntity, final int position) { - RetrofitManager.getInstance(mContext).getData().postNewsViews(newsEntity.getId()) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new JSONObjectResponse() { - @Override - public void onResponse(JSONObject response) { - if (response.length() != 0) { - try { - if ("success".equals(response.getString("status"))) { - newsEntity.setViews(newsEntity.getViews() + 1); - - notifyItemChanged(position); - - // 更新okhttp缓存数据 - VisitManager.updateOkhttpCache(mContext, newsEntity.getId()); - } - } catch (JSONException e) { - e.printStackTrace(); - } - } - } - }); - } -} diff --git a/app/src/main/java/com/gh/gamecenter/baselist/TestFragment.java b/app/src/main/java/com/gh/gamecenter/baselist/TestFragment.java deleted file mode 100644 index 10f301a5de..0000000000 --- a/app/src/main/java/com/gh/gamecenter/baselist/TestFragment.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.gh.gamecenter.baselist; - -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v7.widget.RecyclerView; -import android.view.View; - -import com.gh.common.util.DataCollectionUtils; -import com.gh.common.util.DataUtils; -import com.gh.common.util.StringUtils; -import com.gh.common.view.VerticalItemDecoration; -import com.gh.gamecenter.NewsDetailActivity; -import com.gh.gamecenter.R; -import com.gh.gamecenter.entity.NewsEntity; -import com.gh.gamecenter.eventbus.EBNetworkState; -import com.gh.gamecenter.retrofit.RetrofitManager; - -import org.greenrobot.eventbus.Subscribe; -import org.greenrobot.eventbus.ThreadMode; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import rx.Observable; - -/** - * Created by khy on 6/11/17. - * 测试例子 - */ - -public class TestFragment extends BaseListFragment { - - private TestAdapter mAdapter; - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mAdapter = new TestAdapter(getContext(), mListPresenter, this); - mListPresenter.load(); - } - - @Override - public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - RecyclerView recyclerView = view.findViewById(R.id.list_rv); - recyclerView.addItemDecoration(new VerticalItemDecoration(getContext(), 8, true)); - } - - @Override - protected BaseListAdapter provideAdapter() { - return mAdapter; - } - - @SuppressWarnings("unchecked") - @Override - public Observable> provideDataObservable() { - return RetrofitManager.getInstance(getContext()).getApi().getZiXun(mListPresenter.getListOffset()); - } - - - @Subscribe(threadMode = ThreadMode.MAIN) - public void onEventMainThread(EBNetworkState busNetworkState) { - if (busNetworkState.isNetworkConnected()) { - - } - } - - - @SuppressWarnings("unchecked") - @Override - public void onListClick(View view, int position, Object data) { - List newsList = (List) data; - NewsEntity newsEntity = newsList.get(position); - Map kv = new HashMap<>(); - kv.put("名字", newsEntity.getTitle()); - kv.put("位置", String.valueOf(position + 1)); - DataUtils.onEvent(getContext(), "点击", "资讯-资讯", kv); - - DataCollectionUtils.uploadClick(getContext(), "列表", "资讯-资讯", newsEntity.getTitle()); - - //统计阅读量 - mAdapter.statNewsViews(newsEntity, position); - NewsDetailActivity.startNewsDetailActivity(getContext(), newsEntity, StringUtils.buildString("(资讯:资讯[" + position + "])")); - } -} diff --git a/app/src/main/java/com/gh/gamecenter/fragment/MainFragment.java b/app/src/main/java/com/gh/gamecenter/fragment/MainFragment.java index d08e4df7ca..2dd771a7b3 100644 --- a/app/src/main/java/com/gh/gamecenter/fragment/MainFragment.java +++ b/app/src/main/java/com/gh/gamecenter/fragment/MainFragment.java @@ -8,6 +8,7 @@ import android.view.View; import com.gh.base.SearchBarHint; import com.gh.base.fragment.BaseFragment_ViewPager_Checkable; import com.gh.gamecenter.R; +import com.gh.gamecenter.ask.AskFragment; import com.gh.gamecenter.eventbus.EBReuse; import com.gh.gamecenter.eventbus.EBSkip; import com.gh.gamecenter.eventbus.EBUISwitch; @@ -45,8 +46,9 @@ public class MainFragment extends BaseFragment_ViewPager_Checkable { View mMessageHintIv; public static final int INDEX_GAME = 0; - public static final int INDEX_NEWS = 1; - public static final int INDEX_PERSONAL = 2; + public static final int INDEX_ASK = 1; + public static final int INDEX_NEWS = 2; + public static final int INDEX_PERSONAL = 3; private ArrayList mSearchHintLint; @Override @@ -67,6 +69,7 @@ public class MainFragment extends BaseFragment_ViewPager_Checkable { @Override protected void initFragmentList(List fragments) { fragments.add(new GameWrapperFragment()); + fragments.add(new AskFragment()); fragments.add(new NewsWrapperFragment()); fragments.add(new PersonalFragment()); } diff --git a/app/src/main/res/drawable-xxhdpi/ic_ask_search.png b/app/src/main/res/drawable-xxhdpi/ic_ask_search.png new file mode 100644 index 0000000000..970f79ce91 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_ask_search.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_ask_select.png b/app/src/main/res/drawable-xxhdpi/ic_ask_select.png new file mode 100644 index 0000000000..e3edaa3078 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_ask_select.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_ask_selectgame.png b/app/src/main/res/drawable-xxhdpi/ic_ask_selectgame.png new file mode 100644 index 0000000000..034150ff68 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_ask_selectgame.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_ask_unselect.png b/app/src/main/res/drawable-xxhdpi/ic_ask_unselect.png new file mode 100644 index 0000000000..0214e8cc40 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_ask_unselect.png differ diff --git a/app/src/main/res/drawable/selector_ic_ask.xml b/app/src/main/res/drawable/selector_ic_ask.xml new file mode 100644 index 0000000000..b7e7bbacc4 --- /dev/null +++ b/app/src/main/res/drawable/selector_ic_ask.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/ask_item.xml b/app/src/main/res/layout/ask_item.xml new file mode 100644 index 0000000000..27c57d825c --- /dev/null +++ b/app/src/main/res/layout/ask_item.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_ask.xml b/app/src/main/res/layout/fragment_ask.xml new file mode 100644 index 0000000000..19881f0e43 --- /dev/null +++ b/app/src/main/res/layout/fragment_ask.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml index c296b80235..c1309cb9c0 100644 --- a/app/src/main/res/layout/fragment_main.xml +++ b/app/src/main/res/layout/fragment_main.xml @@ -50,6 +50,32 @@ + + + + + + + + + #1668d0 - #59d3ff + #59d3ff - #717171 + #717171 - #676767 + #676767 - #f8f8f8 + #f8f8f8 - #FF4E00 + #FF4E00 - #175aa3 + #175aa3 - #60d6d5ff + #60d6d5ff - #949494 + #949494 - #454545 + #454545 - #e9e9e9 + #e9e9e9 - #ff8814 + #ff8814 - #ecfaff + #ecfaff + + @android:color/black #ff4147 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1b60469e13..350aa5aac9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -431,5 +431,8 @@ 未填写 请输入正确的链接 登录成功 + 问答 + 精选 + 问题