From 7a1c4f435164ce588f56426712be7b1bbc8189cd Mon Sep 17 00:00:00 2001 From: Yutousama <583819556@qq.com> Date: Fri, 15 Jun 2018 16:13:28 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=A5=E5=B8=B8=E5=A4=87=E4=BB=BD=EF=BC=8C?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E5=88=97=E8=A1=A8=E5=B7=B2=E5=81=9A=E5=A5=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/caches/build_file_checksums.ser | Bin 598 -> 598 bytes .idea/modules.xml | 1 - RefreshRecyclerView/build.gradle | 14 +- .../cn/lemon/view/RefreshRecyclerView.java | 67 ++-- .../cn/lemon/view/adapter/BaseViewHolder.java | 40 ++- .../lemon/view/adapter/MultiTypeAdapter.java | 161 +++++---- .../lemon/view/adapter/RecyclerAdapter.java | 319 +++++++++++++----- .../lemon/view/adapter/ViewHolderManager.java | 46 ++- .../main/res/layout/view_refresh_recycler.xml | 5 +- .../src/main/res/layout/view_status_last.xml | 45 ++- .../src/main/res/values/attrs.xml | 6 +- app/build.gradle | 31 +- app/src/main/AndroidManifest.xml | 5 +- .../Adapters/DownloadItemAdapter.java | 69 +++- .../com/yutou/jianrmg_v2/Fragments/Home.java | 2 +- .../yutou/jianrmg_v2/Fragments/MGList.java | 2 +- .../Fragments/ModListFragmentData.java | 2 +- .../com/yutou/jianrmg_v2/Network/HttpApi.java | 4 +- .../yutou/jianrmg_v2/Network/HttpUtils.java | 1 + .../java/com/yutou/jianrmg_v2/Tools/Log.java | 2 +- .../com/yutou/jianrmg_v2/Tools/ModUtils.java | 40 ++- .../com/yutou/jianrmg_v2/Tools/Utils.java | 46 ++- .../views/DownloadListActivity.java | 24 +- .../jianrmg_v2/views/FavoritesActivity.java | 14 + .../yutou/jianrmg_v2/views/ModActivity.java | 29 +- app/src/main/res/layout/activity_mod.xml | 12 +- app/src/main/res/layout/item_download.xml | 43 ++- build.gradle | 2 +- 28 files changed, 690 insertions(+), 342 deletions(-) create mode 100644 app/src/main/java/com/yutou/jianrmg_v2/views/FavoritesActivity.java diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index d5e808453922514eeb6623f004a5dec9609d922b..7e8ad691a71f796faa3ad26cd4475be2e9e18a72 100644 GIT binary patch delta 103 zcmV-t0GR*Q1l9zQmjz@3GHfN0oOclQzK1Jxq2c$A%yEM`R1@QqBLQ=h(*YL{DY2lW z*aMo?$Wu+e3$- delta 123 zcmV->0EGY61l9zQmjz=!^T;}poOckHO)i>bZ^fW66OwFneNZoxBLQ=hzX2;bo?>$o zxA1|ImQOAfZS!`NbN~!ub!lv5E@yIKWNc-1aR7b*1^@s65G%HM^@L - diff --git a/RefreshRecyclerView/build.gradle b/RefreshRecyclerView/build.gradle index 131020c..a3a8d7f 100644 --- a/RefreshRecyclerView/build.gradle +++ b/RefreshRecyclerView/build.gradle @@ -1,14 +1,14 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 26 + compileSdkVersion 25 buildToolsVersion '27.0.3' defaultConfig { - minSdkVersion 16 - targetSdkVersion 26 - versionCode 5 - versionName "1.2.0" + minSdkVersion 15 + targetSdkVersion 25 + versionCode 6 + versionName "1.3.0" } buildTypes { release { @@ -19,7 +19,7 @@ android { } dependencies { - implementation 'com.android.support:recyclerview-v7:26+' + implementation 'com.android.support:recyclerview-v7:25.0.0' } ext { @@ -28,7 +28,7 @@ ext { publishedGroupId = 'cn.lemon' artifact = 'RefreshRecyclerView' - libraryVersion = '1.2.0' + libraryVersion = '1.4.1' siteUrl = 'https://github.com/llxdaxia/RefreshRecyclerView' gitUrl = 'https://github.com/llxdaxia/RefreshRecyclerView.git' diff --git a/RefreshRecyclerView/src/main/java/cn/lemon/view/RefreshRecyclerView.java b/RefreshRecyclerView/src/main/java/cn/lemon/view/RefreshRecyclerView.java index 3729514..70e3ad7 100644 --- a/RefreshRecyclerView/src/main/java/cn/lemon/view/RefreshRecyclerView.java +++ b/RefreshRecyclerView/src/main/java/cn/lemon/view/RefreshRecyclerView.java @@ -12,7 +12,8 @@ import android.util.Log; import android.view.View; import android.widget.FrameLayout; import android.widget.TextView; - +import java.util.ArrayList; +import java.util.List; import cn.lemon.view.adapter.Action; import cn.lemon.view.adapter.RecyclerAdapter; @@ -20,13 +21,15 @@ import cn.lemon.view.adapter.RecyclerAdapter; /** * Created by linlongxin on 2016/1/24. */ -public class RefreshRecyclerView extends FrameLayout { +public class RefreshRecyclerView extends FrameLayout implements SwipeRefreshLayout.OnRefreshListener{ private final String TAG = "RefreshRecyclerView"; private SwipeRefreshLayout mSwipeRefreshLayout; private RecyclerView mRecyclerView; private RecyclerAdapter mAdapter; - private boolean loadMoreAble; + private List mRefreshActions; + private boolean mLoadMoreEnable; + private boolean mShowNoMoreEnable; public RefreshRecyclerView(Context context) { this(context, null); @@ -39,20 +42,29 @@ public class RefreshRecyclerView extends FrameLayout { public RefreshRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); View view = inflate(context, R.layout.view_refresh_recycler, this); - mRecyclerView = view.findViewById(cn.lemon.view.R.id.recycler_view); - mSwipeRefreshLayout = view.findViewById(R.id.refresh_layout); + mRecyclerView = (RecyclerView) view.findViewById(R.id.lemon_recycler_view); + mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.lemon_refresh_layout); + TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RefreshRecyclerView); - boolean refreshAble = typedArray.getBoolean(R.styleable.RefreshRecyclerView_refresh_able, true); - loadMoreAble = typedArray.getBoolean(R.styleable.RefreshRecyclerView_load_more_able, true); - if (!refreshAble) { + mLoadMoreEnable = typedArray.getBoolean(R.styleable.RefreshRecyclerView_load_more_enable, true); + mShowNoMoreEnable = typedArray.getBoolean(R.styleable.RefreshRecyclerView_show_no_more_enable, true); + boolean refreshEnable = typedArray.getBoolean(R.styleable.RefreshRecyclerView_refresh_enable, true); + if (!refreshEnable) { mSwipeRefreshLayout.setEnabled(false); + } else { + mSwipeRefreshLayout.setOnRefreshListener(this); } + typedArray.recycle(); } public void setAdapter(RecyclerAdapter adapter) { + if (adapter == null) { + return; + } mRecyclerView.setAdapter(adapter); mAdapter = adapter; - mAdapter.loadMoreAble = loadMoreAble; + mAdapter.setLoadMoreEnable(mLoadMoreEnable); + mAdapter.setShowNoMoreEnable(mShowNoMoreEnable); } public void setLayoutManager(final RecyclerView.LayoutManager layoutManager) { @@ -74,24 +86,32 @@ public class RefreshRecyclerView extends FrameLayout { } } - public void setRefreshAction(final Action action) { - mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - action.onAction(); - } - }); + public void addRefreshAction(final Action action) { + if (action == null) { + return; + } + if (mRefreshActions == null) { + mRefreshActions = new ArrayList<>(); + } + mRefreshActions.add(action); } public void setLoadMoreAction(final Action action) { Log.d(TAG, "setLoadMoreAction"); - if (mAdapter.isShowNoMore || !loadMoreAble) { + if (mAdapter.isShowNoMoring() || !mLoadMoreEnable) { return; } - mAdapter.loadMoreAble = true; mAdapter.setLoadMoreAction(action); } + public void setLoadMoreErrorAction(final Action action) { + Log.d(TAG, "setLoadMoreErrorAction"); + if (mAdapter.isShowNoMoring() || !mLoadMoreEnable) { + return; + } + mAdapter.setLoadMoreErrorAction(action); + } + public void showNoMore() { mAdapter.showNoMore(); } @@ -112,10 +132,6 @@ public class RefreshRecyclerView extends FrameLayout { return mSwipeRefreshLayout; } - public TextView getNoMoreView() { - return mAdapter.mNoMoreView; - } - public void setSwipeRefreshColorsFromRes(@ColorRes int... colors) { mSwipeRefreshLayout.setColorSchemeResources(colors); } @@ -134,4 +150,11 @@ public class RefreshRecyclerView extends FrameLayout { public void dismissSwipeRefresh() { mSwipeRefreshLayout.setRefreshing(false); } + + @Override + public void onRefresh() { + for (Action a : mRefreshActions) { + a.onAction(); + } + } } diff --git a/RefreshRecyclerView/src/main/java/cn/lemon/view/adapter/BaseViewHolder.java b/RefreshRecyclerView/src/main/java/cn/lemon/view/adapter/BaseViewHolder.java index a04b9ec..a74b306 100644 --- a/RefreshRecyclerView/src/main/java/cn/lemon/view/adapter/BaseViewHolder.java +++ b/RefreshRecyclerView/src/main/java/cn/lemon/view/adapter/BaseViewHolder.java @@ -13,14 +13,21 @@ import android.view.ViewGroup; public class BaseViewHolder extends RecyclerView.ViewHolder{ private final String TAG = "BaseViewHolder"; + private T mData; + + public BaseViewHolder(ViewGroup parent, int layoutId) { + this(LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false)); + } public BaseViewHolder(View itemView) { super(itemView); - } - - public BaseViewHolder(ViewGroup parent, int layoutId) { - super(LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false)); onInitializeView(); + itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onItemViewClick(mData); + } + }); } public void onInitializeView() { @@ -28,24 +35,25 @@ public class BaseViewHolder extends RecyclerView.ViewHolder{ } public T findViewById(@IdRes int resId) { - return (T) itemView.findViewById(resId); + if (itemView != null) { + return (T) itemView.findViewById(resId); + } else { + return null; + } } public void setData(final T data) { - itemView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - onItemViewClick(data); - } - }); + if (data == null) { + return; + } + mData = data; + } + + public T getData() { + return mData; } public void onItemViewClick(T data) { } - - public void setTag(Object tag){ - itemView.setTag(tag); - } - } diff --git a/RefreshRecyclerView/src/main/java/cn/lemon/view/adapter/MultiTypeAdapter.java b/RefreshRecyclerView/src/main/java/cn/lemon/view/adapter/MultiTypeAdapter.java index 8548afb..ce9707e 100644 --- a/RefreshRecyclerView/src/main/java/cn/lemon/view/adapter/MultiTypeAdapter.java +++ b/RefreshRecyclerView/src/main/java/cn/lemon/view/adapter/MultiTypeAdapter.java @@ -2,18 +2,17 @@ package cn.lemon.view.adapter; import android.content.Context; import android.util.Log; -import android.util.SparseIntArray; -import android.view.View; import android.view.ViewGroup; import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * 复杂的数据类型列表 Adapter , 没有 Header , Footer 的概念,所有的 item 都对应一个 ViewHolder + * 通过反射自动处理 onCreateViewHolder 过程,如需避免反射调用请使用 CustomMultiTypeAdapter + * * Created by linlongxin on 2016/8/22. */ @@ -21,79 +20,34 @@ public class MultiTypeAdapter extends RecyclerAdapter { private final String TAG = "MultiTypeAdapter"; private List mViewsData; - private SparseIntArray mPositionViewType; //position --> ViewType private ViewHolderManager mViewHolderManager; public MultiTypeAdapter(Context context) { super(context); mViewsData = new ArrayList<>(); - mPositionViewType = new SparseIntArray(); mViewHolderManager = new ViewHolderManager(); } - public void add(Class> viewHolder, T data) { - if (isShowNoMore) { - return; - } - mViewsData.add(data); - mViewHolderManager.addViewHolder(viewHolder); - int viewType = mViewHolderManager.getViewType(viewHolder); - mPositionViewType.put(mViewCount - 1, viewType);//mViewCount从1开始 - int positionStart = mViewCount - 1; - mViewCount++; - notifyItemRangeInserted(positionStart, 1); - } - - public void addAll(Class> viewHolder, T[] data) { - addAll(viewHolder, Arrays.asList(data)); - } - - public void addAll(Class> viewHolder, List data) { - int size = data.size(); - if (isShowNoMore || size == 0) { - return; - } - mViewsData.addAll(data); - mViewHolderManager.addViewHolder(viewHolder); - int viewType = mViewHolderManager.getViewType(viewHolder); - int positionStart = mViewCount - 1; - for (int i = 0; i < size; i++) { - mPositionViewType.put(mViewCount - 1, viewType); //mViewCount从1开始 - mViewCount++; - } - notifyItemRangeInserted(positionStart, size); - } - - public void clear() { - if (mViewsData == null) { - log("clear() mData is null"); - return; - } - mViewsData.clear(); - mViewCount = 1; - isShowNoMore = false; - mLoadMoreView.setVisibility(View.GONE); - mNoMoreView.setVisibility(View.GONE); - notifyDataSetChanged(); - } - @Override public int getItemViewType(int position) { - if (position == mViewCount - 1) { + if (hasEndStatusView() && position == mViewCount - 1) { return STATUS_TYPE; } - return mPositionViewType.get(position); + return mViewHolderManager.getViewType(position); } @Override public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { log("onCreateViewHolder -- viewType : " + viewType); + if (mViewHolderManager == null) { + throw new ExceptionInInitializerError("mViewHolderManager is null , it need init"); + } if (viewType == STATUS_TYPE) { return new BaseViewHolder(mStatusView); } - Class clazzViewHolder = mViewHolderManager.getViewHolder(viewType); + Class clazzViewHolder = mViewHolderManager.getViewHolderClass(viewType); try { - //这里只适配了ViewHolder构造函数只有ViewGroup.class参数或者无参情况的构造函数 + //这里只适配了 ViewHolder 构造函数只有 ViewGroup.class 参数 或者 无参 情况的构造函数,具体请看 Demo BaseViewHolder holder; Constructor constructor = clazzViewHolder.getDeclaredConstructor(new Class[]{ViewGroup.class}); constructor.setAccessible(true); @@ -103,21 +57,10 @@ public class MultiTypeAdapter extends RecyclerAdapter { holder = (BaseViewHolder) constructor.newInstance(); } return holder; - } catch (NoSuchMethodException e) { - e.printStackTrace(); - Log.e(TAG, "onCreateBaseViewHolder : " + e.getMessage()); - } catch (IllegalAccessException e) { - e.printStackTrace(); - Log.e(TAG, "onCreateBaseViewHolder : " + e.getMessage()); - } catch (InstantiationException e) { - e.printStackTrace(); - Log.e(TAG, "onCreateBaseViewHolder : " + e.getMessage()); - } catch (InvocationTargetException e) { - e.printStackTrace(); + } catch (Exception e) { Log.e(TAG, "onCreateBaseViewHolder : " + e.getMessage()); } return null; - } @Override @@ -128,17 +71,87 @@ public class MultiTypeAdapter extends RecyclerAdapter { @Override public void onBindViewHolder(BaseViewHolder holder, int position) { log("onBindViewHolder -- position : " + position); - if (position == 0 && mViewCount == 1) { - - } else if (position == mViewCount - 1) { - // 显示加载更多 - if (loadMoreAble && mLoadMoreAction != null && !isShowNoMore) { - mLoadMoreView.setVisibility(View.VISIBLE); + // 显示加载更多 + if (!mIsNoMoring && mLoadMoreEnable && !mIsLoadMoring && isValidLoadMore(position)) { + mIsLoadMoring = true; + setViewVisible(mLoadMoreLayout, true); + setViewVisible(mLoadMoreView, true); + setViewVisible(mLoadMoreError, false); + setViewVisible(mNoMoreView, false); + log("load more"); + if (mLoadMoreAction != null ) { mLoadMoreAction.onAction(); } - } else { + } else if (mViewsData != null && holder != null && position < mViewsData.size()){ holder.setData(mViewsData.get(position)); } } + public void add(Class> viewHolder, T data) { + if (mIsNoMoring || data == null || viewHolder == null) { + return; + } + mIsLoadMoring = false; + mViewsData.add(data); + mViewHolderManager.addViewHolder(viewHolder); + int viewType = mViewHolderManager.getViewType(viewHolder); + + int positionStart; + + if (hasEndStatusView()) { + //mViewCount从1开始 + positionStart = mViewCount - 1; + } else { + positionStart = mViewCount; + } + if (positionStart >= 0) { + mViewHolderManager.putViewType(positionStart, viewType); + mViewCount++; + notifyItemRangeInserted(positionStart, 1); + } + } + + public void addAll(Class> viewHolder, T[] data) { + addAll(viewHolder, Arrays.asList(data)); + } + + public void addAll(Class> viewHolder, List data) { + if (mIsNoMoring || data == null || data.size() == 0) { + return; + } + mIsLoadMoring = false; + int size = data.size(); + mViewsData.addAll(data); + mViewHolderManager.addViewHolder(viewHolder); + int viewType = mViewHolderManager.getViewType(viewHolder); + + int positionStart; + if (hasEndStatusView()) { + positionStart = mViewCount - 1; + } else { + positionStart = mViewCount; + } + if (positionStart >= 0) { + for (int i = 0; i < size; i++) { + mViewHolderManager.putViewType(positionStart + i, viewType); + } + mViewCount += size; + notifyItemRangeInserted(positionStart, size); + } + } + + @Override + public void clear() { + if (mViewsData == null) { + log("clear() mData is null"); + return; + } + mViewsData.clear(); + mViewCount = hasEndStatusView() ? 1 : 0; + mIsNoMoring = false; + mIsLoadMoring = false; + setViewVisible(mLoadMoreLayout, false); + setViewVisible(mNoMoreView, false); + notifyDataSetChanged(); + } } diff --git a/RefreshRecyclerView/src/main/java/cn/lemon/view/adapter/RecyclerAdapter.java b/RefreshRecyclerView/src/main/java/cn/lemon/view/adapter/RecyclerAdapter.java index 24168a6..6e1b4b3 100644 --- a/RefreshRecyclerView/src/main/java/cn/lemon/view/adapter/RecyclerAdapter.java +++ b/RefreshRecyclerView/src/main/java/cn/lemon/view/adapter/RecyclerAdapter.java @@ -1,6 +1,7 @@ package cn.lemon.view.adapter; import android.content.Context; +import android.os.Message; import android.support.annotation.LayoutRes; import android.support.v7.widget.RecyclerView; import android.util.Log; @@ -8,7 +9,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; -import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; @@ -22,10 +22,16 @@ import cn.lemon.view.R; /** * Created by linlongxin on 2015/12/19. */ -public abstract class RecyclerAdapter extends RecyclerView.Adapter> { +public abstract class RecyclerAdapter extends RecyclerView.Adapter> implements IHandler { - private static final String TAG = "RecyclerAdapter"; - private boolean allowLog = false; //改成false关闭日志 + private static final String TAG = RecyclerAdapter.class.getSimpleName(); + + protected static final int MSG_SHOW_NO_MORE = 1 << 1; + protected static final int MSG_SHOW_LOAD_MORE = 1 << 2; + protected static final int MSG_SHOW_LOAD_MORE_ERROR = 1 << 3; + + //改成false关闭日志 + private boolean allowLog = true; public static final int HEADER_TYPE = 111; public static final int FOOTER_TYPE = 222; @@ -34,20 +40,32 @@ public abstract class RecyclerAdapter extends RecyclerView.Adapter mData = new ArrayList<>(); private View headerView; private View footerView; protected View mStatusView; - protected LinearLayout mLoadMoreView; - public TextView mNoMoreView; + protected View mLoadMoreLayout; + protected View mLoadMoreView; + protected TextView mLoadMoreError; + protected TextView mNoMoreView; - private Context mContext; + protected Context mContext; + + private WeakHandler mHandler = new WeakHandler(this); public void colseLog() { allowLog = false; @@ -55,9 +73,7 @@ public abstract class RecyclerAdapter extends RecyclerView.Adapter extends RecyclerView.Adapter data) { mContext = context; - initStatusView(context); this.mData = data; mViewCount += data.size(); notifyDataSetChanged(); } - public void initStatusView(Context context) { - mStatusView = LayoutInflater.from(context).inflate(R.layout.view_status_last, null); - mStatusView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); - mLoadMoreView = (LinearLayout) mStatusView.findViewById(R.id.load_more_view); - mNoMoreView = (TextView) mStatusView.findViewById(R.id.no_more_view); - mViewCount++; + private void initEndStatusView() { + if (hasEndStatusView() && mStatusView == null) { + mStatusView = LayoutInflater.from(getContext()).inflate(R.layout.view_status_last, null); + mStatusView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + mLoadMoreLayout = mStatusView.findViewById(R.id.load_more_Layout); + mLoadMoreView = mStatusView.findViewById(R.id.load_more_loading); + mLoadMoreError = (TextView) mStatusView.findViewById(R.id.load_more_error); + mNoMoreView = (TextView) mStatusView.findViewById(R.id.no_more_view); + mViewCount++; + mLoadMoreError.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mHandler.sendEmptyMessage(MSG_SHOW_LOAD_MORE); + if (mErrorAction != null) { + mErrorAction.onAction(); + } + } + }); + } + } + + public void setLoadMoreEnable(boolean b) { + mLoadMoreEnable = b; + initEndStatusView(); + } + + public void setShowNoMoreEnable(boolean b) { + mNoMoreEnable = b; + initEndStatusView(); + } + + public boolean isShowNoMoring() { + return mIsNoMoring; } @Override @@ -87,8 +129,9 @@ public abstract class RecyclerAdapter extends RecyclerView.Adapter(footerView); } else if (viewType == STATUS_TYPE) { return new BaseViewHolder<>(mStatusView); - } else + } else { return onCreateBaseViewHolder(parent, viewType); + } } public abstract BaseViewHolder onCreateBaseViewHolder(ViewGroup parent, int viewType); @@ -99,54 +142,88 @@ public abstract class RecyclerAdapter extends RecyclerView.Adapter holder, int position) { - // log("onBindViewHolder() viewCount : " + mViewCount + " position : " + position); - if (position == 0) { - // 最先加载 mStatusView 时不需要绑定数据 - if (mViewCount == 1 || hasHeader) { - return; - } else { - if (mData.size() > 0) - holder.setData(mData.get(0)); - else - return; + log("onBindViewHolder() viewCount : " + mViewCount + " position : " + position); + if (holder == null || position < 0) { + return; + } + int dataSize = mData.size(); + if (hasEndStatusView()) { + if (!hasHeader && !hasFooter && position < dataSize) { + //没有Header和Footer + holder.setData(mData.get(position)); + } else if (hasHeader && !hasFooter && position > 0 && position < mViewCount - 1 && position - 1 < dataSize) { + //有Header没有Footer + holder.setData(mData.get(position - 1)); + } else if (!hasHeader && position < mViewCount - 2 && position < dataSize) { + //没有Header,有Footer + holder.setData(mData.get(position)); + } else if (position > 0 && position < mViewCount - 2 && position - 1 < dataSize) { + //Header, Footer 都有 + holder.setData(mData.get(position - 1)); + } + } else { + if (!hasHeader && !hasFooter && position < dataSize) { + //没有Header和Footer + holder.setData(mData.get(position)); + } else if (hasHeader && !hasFooter && position > 0 && position < mViewCount && position - 1 < dataSize) { + //有Header没有Footer + holder.setData(mData.get(position - 1)); + } else if (!hasHeader && position < mViewCount - 1 && position < dataSize) { + //没有Header,有Footer + holder.setData(mData.get(position)); + } else if (position > 0 && position < mViewCount - 1 && position - 1 < dataSize) { + //Header, Footer 都有 + holder.setData(mData.get(position - 1)); } - } else if (!hasHeader && !hasFooter && position < mData.size()) { //没有Header和Footer - holder.setData(mData.get(position)); - } else if (hasHeader && !hasFooter && position > 0 && position < mViewCount - 1) { //有Header没有Footer - holder.setData(mData.get(position - 1)); - } else if (!hasHeader && position < mViewCount - 2) { //没有Header,有Footer - holder.setData(mData.get(position)); - } else if (position > 0 && position < mViewCount - 2) { //都有 - holder.setData(mData.get(position - 1)); } // 最后一个可见的 item 时 加载更多。解决 remove 时 bug - int positionEnd; - if ((hasHeader && hasFooter) || (!hasHeader && hasFooter)) { - positionEnd = mViewCount - 3; - } else { - positionEnd = mViewCount - 2; - } - if (loadMoreAble && !isShowNoMore && position == positionEnd) { - mLoadMoreView.setVisibility(View.VISIBLE); + if (mLoadMoreEnable && !mIsNoMoring && !mIsLoadMoring && isValidLoadMore(position)) { + mIsLoadMoring = true; + setViewVisible(mLoadMoreLayout, true); + setViewVisible(mLoadMoreView, true); + setViewVisible(mLoadMoreError, false); + setViewVisible(mNoMoreView, false); + log("load more"); if (mLoadMoreAction != null) { mLoadMoreAction.onAction(); } } } + /** + * load more 当前位置 view 是否有效 + */ + protected boolean isValidLoadMore(int position) { + if (hasEndStatusView()) { + // 倒数第二个 item 就load more ,提前触发。(解决一些极端 case 导致 bug 并提前加载数据,提高加载效率) + if (hasHeader) { + return position != 1 && position == mViewCount - 3 && mViewCount != 2; + } else { + return position != 0 && position == mViewCount - 2 && mViewCount != 1; + } + } else { + return false; + } + } + /** * ViewHolder 更新 Item 的位置选择 ViewType , 和 UI 是同步的 */ @Override public int getItemViewType(int position) { - if (hasHeader && position == 0) { //header + // header + if (hasHeader && position == 0) { return HEADER_TYPE; } - if (hasFooter && position == mViewCount - 2) { //footer + // footer + if (hasFooter && hasEndStatusView() && position == mViewCount - 2) { + return FOOTER_TYPE; + } else if (hasFooter && !hasEndStatusView() && position == mViewCount - 1) { return FOOTER_TYPE; } - if (position == mViewCount - 1) { //最后View的状态 + // status + if (hasEndStatusView() && position == mViewCount - 1) { return STATUS_TYPE; } @@ -162,37 +239,27 @@ public abstract class RecyclerAdapter extends RecyclerView.Adapter extends RecyclerView.Adapter extends RecyclerView.Adapter extends RecyclerView.Adapter data) { + if (data == null) { + return; + } int size = data.size(); - if (!isShowNoMore && size > 0) { + if (!mIsNoMoring && size > 0) { + mIsLoadMoring = false; mData.addAll(data); int positionStart; - if (hasFooter) { + if (hasFooter && hasEndStatusView()) { positionStart = mViewCount - 2; - } else { + } else if (hasFooter && !hasEndStatusView()) { positionStart = mViewCount - 1; + } else if (!hasFooter && hasEndStatusView()) { + positionStart = mViewCount - 1; + } else { + positionStart = mViewCount; } mViewCount += size; notifyItemRangeInserted(positionStart, size); @@ -248,7 +329,7 @@ public abstract class RecyclerAdapter extends RecyclerView.Adapter extends RecyclerView.Adapter extends RecyclerView.Adapter extends RecyclerView.Adapter extends RecyclerView.Adapter extends RecyclerView.Adapter 1) { + notifyItemRemoved(mViewCount - 2); + } else if (!hasEndStatusView() && mViewCount > 0) { + notifyItemRemoved(mViewCount - 1); + } } } @@ -378,9 +475,47 @@ public abstract class RecyclerAdapter extends RecyclerView.Adapter, Integer> mHolderType; - private Map> mTypeHolder; + private Map, Integer> mHolderToTypeMap; + private SparseArray> mTypeToHolderMap; + //position to ViewType + private SparseIntArray mPositionToTypeMap; public ViewHolderManager() { - mHolderType = new HashMap<>(); - mTypeHolder = new HashMap<>(); + mHolderToTypeMap = new HashMap<>(); + mTypeToHolderMap = new SparseArray<>(); + mPositionToTypeMap = new SparseIntArray(); + } + + public void putViewType(int position, int type){ + mPositionToTypeMap.put(position, type); + } + + public int getViewType(int position) { + return mPositionToTypeMap.get(position); } public void addViewHolder(Class viewHolder) { - if (!mHolderType.containsKey(viewHolder)) { - Class dataClass = (Class) ((ParameterizedType) viewHolder.getGenericSuperclass()).getActualTypeArguments()[0]; //获取ViewHolder的泛型数据class - mViewType++; - mHolderType.put(viewHolder, mViewType); - mTypeHolder.put(mViewType,viewHolder); + if (!mHolderToTypeMap.containsKey(viewHolder)) { + //获取ViewHolder的泛型数据class + Class dataClass = (Class) ((ParameterizedType) viewHolder.getGenericSuperclass()).getActualTypeArguments()[0]; + mViewType ++; + mHolderToTypeMap.put(viewHolder, mViewType); + mTypeToHolderMap.put(mViewType,viewHolder); Log.d(TAG, "addViewHolder dataClassType : " + dataClass.getName()); } } public int getViewType(Class holder){ - if(!mHolderType.containsKey(holder)){ - throw new NullPointerException("please invoke addViewHolder method"); + if(!mHolderToTypeMap.containsKey(holder)){ + throw new IllegalArgumentException("please invoke add ViewHolder method"); } - return mHolderType.get(holder); + return mHolderToTypeMap.get(holder); } - public Class getViewHolder(int viewType){ - if(!mTypeHolder.containsKey(viewType)){ - throw new NullPointerException("please invoke addViewHolder method"); + public Class getViewHolderClass(int viewType){ + if(mTypeToHolderMap.get(viewType) == null){ + throw new IllegalArgumentException("please invoke add ViewHolder method"); } - return mTypeHolder.get(viewType); + return mTypeToHolderMap.get(viewType); } } diff --git a/RefreshRecyclerView/src/main/res/layout/view_refresh_recycler.xml b/RefreshRecyclerView/src/main/res/layout/view_refresh_recycler.xml index 4306575..91648b7 100644 --- a/RefreshRecyclerView/src/main/res/layout/view_refresh_recycler.xml +++ b/RefreshRecyclerView/src/main/res/layout/view_refresh_recycler.xml @@ -1,12 +1,13 @@ + diff --git a/RefreshRecyclerView/src/main/res/layout/view_status_last.xml b/RefreshRecyclerView/src/main/res/layout/view_status_last.xml index b1228e5..7ea3479 100644 --- a/RefreshRecyclerView/src/main/res/layout/view_status_last.xml +++ b/RefreshRecyclerView/src/main/res/layout/view_status_last.xml @@ -1,36 +1,53 @@ - + android:visibility="gone" + tools:visibility="visible"> - + + + + + + + + android:id="@+id/load_more_error" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@drawable/bg_button_retry_adapter" + android:gravity="center" + android:text="数据错误,点我重试" + android:textSize="14sp"/> - + diff --git a/RefreshRecyclerView/src/main/res/values/attrs.xml b/RefreshRecyclerView/src/main/res/values/attrs.xml index d52407a..20a7458 100644 --- a/RefreshRecyclerView/src/main/res/values/attrs.xml +++ b/RefreshRecyclerView/src/main/res/values/attrs.xml @@ -1,7 +1,9 @@ - - + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 89fb0e1..e6afaf1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,11 +1,11 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 26 + compileSdkVersion 27 defaultConfig { applicationId "com.yutou.jianrmg_v2" minSdkVersion 19 - targetSdkVersion 26 + targetSdkVersion 27 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -17,26 +17,23 @@ android { } } } - dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //noinspection GradleCompatible - implementation 'com.android.support:appcompat-v7:26.1.0' - implementation 'com.android.support.constraint:constraint-layout:1.0.2' - implementation 'com.android.support:design:26.1.0' + implementation 'com.android.support:appcompat-v7:27.1.1' + implementation 'com.android.support.constraint:constraint-layout:1.1.1' + //implementation 'com.android.support:design:26.1.0' testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.1' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' //okhttp - implementation 'com.squareup.okhttp3:okhttp:3.9.1' + implementation 'com.squareup.okhttp3:okhttp:3.10.0' //FastJson implementation 'com.alibaba:fastjson:1.2.41' //轮播图 implementation 'com.bigkoo:convenientbanner:2.0.5' //图片流缓存 implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' - //圆形图片 - implementation 'com.github.siyamed:android-shape-imageview:0.9.+@aar' //滑动Tabs implementation 'com.ogaclejapan.smarttablayout:library:1.6.1@aar' implementation 'com.ogaclejapan.smarttablayout:utils-v13:1.6.1@aar' @@ -44,12 +41,12 @@ dependencies { implementation 'me.drakeet.materialdialog:library:1.3.1' //载入界面 implementation 'com.kaopiz:kprogresshud:1.1.0' - //富文本编辑器 - implementation 'com.github.louisgeek:LouisMultiLineEditText:v1.0.0' + //文本编辑器 + implementation 'com.github.louisgeek:ClassicLinesEditView:1.0.2' //文件选择器 - implementation 'com.leon:lfilepickerlibrary:1.4.0' - //富文本 - implementation 'com.github.limedroid:XRichText:v1.0.0' + implementation 'com.leon:lfilepickerlibrary:1.8.0' + //富文本展示 #关注更新 + implementation 'com.zzhoujay.richtext:richtext:3.0.7' //底端对话框 implementation 'com.orhanobut:dialogplus:1.11@aar' //二维码扫描 @@ -59,7 +56,7 @@ dependencies { //刷新载入 implementation project(path: ':RefreshRecyclerView') //图片形状 - implementation 'com.github.siyamed:android-shape-imageview:0.9.+@aar' + implementation 'com.github.siyamed:android-shape-imageview:0.9.3@aar' //毛玻璃 implementation 'jp.wasabeef:glide-transformations:3.0.0' //图表 diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e2b4e21..bc151e4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -45,12 +45,13 @@ android:exported="true" /> + android:name=".views.BaseActivity"/> + android:name=".views.WebActivity"/> + \ No newline at end of file diff --git a/app/src/main/java/com/yutou/jianrmg_v2/Adapters/DownloadItemAdapter.java b/app/src/main/java/com/yutou/jianrmg_v2/Adapters/DownloadItemAdapter.java index 983ee1d..f0efd38 100644 --- a/app/src/main/java/com/yutou/jianrmg_v2/Adapters/DownloadItemAdapter.java +++ b/app/src/main/java/com/yutou/jianrmg_v2/Adapters/DownloadItemAdapter.java @@ -1,24 +1,39 @@ package com.yutou.jianrmg_v2.Adapters; import android.content.Context; +import android.content.Intent; +import android.support.v7.widget.AppCompatButton; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; +import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; +import com.alibaba.fastjson.JSON; +import com.nostra13.universalimageloader.core.ImageLoader; +import com.yutou.jianrmg_v2.Data.AppData; +import com.yutou.jianrmg_v2.Data.TMod; +import com.yutou.jianrmg_v2.Interfaces.ModInterface; import com.yutou.jianrmg_v2.R; +import com.yutou.jianrmg_v2.Tools.ModUtils; +import com.yutou.jianrmg_v2.Tools.Utils; +import com.yutou.jianrmg_v2.views.ModActivity; import java.util.List; +import me.drakeet.materialdialog.MaterialDialog; + public class DownloadItemAdapter extends BaseAdapter { private Context context; - private List list; + private List list; + private ImageLoader imageLoader; - public DownloadItemAdapter(Context context, List list) { + public DownloadItemAdapter(Context context, List list) { this.context = context; this.list = list; + imageLoader= Utils.initImageLoader(context); } @Override @@ -37,20 +52,66 @@ public class DownloadItemAdapter extends BaseAdapter { } @Override - public View getView(int i, View view, ViewGroup viewGroup) { + public View getView(final int i, View view, ViewGroup viewGroup) { Items items; if(view==null){ view= LayoutInflater.from(context).inflate(R.layout.item_download,null); items=new Items(); - + items.delete=view.findViewById(R.id.delete); + items.install=view.findViewById(R.id.install); + items.icon=view.findViewById(R.id.image); + items.title=view.findViewById(R.id.title); view.setTag(items); }else{ items= (Items) view.getTag(); } + items.title.setText(list.get(i).getTitle()); + imageLoader.displayImage(AppData.appConfig.getDownloadhome()+list.get(i).getIcon(),items.icon); + items.delete.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final MaterialDialog dialog=new MaterialDialog(context); + dialog.setTitle("提示"); + dialog.setMessage("删除这个内容?"); + dialog.setNegativeButton("我手滑了", new View.OnClickListener() { + @Override + public void onClick(View v) { + dialog.dismiss(); + } + }); + dialog.setPositiveButton("是的", new View.OnClickListener() { + @Override + public void onClick(View v) { + Utils.deleteFiles(Utils.getAppPath()+"/"+list.get(i).getId()); + Utils.toast(context,"删除完成"); + list.remove(i); + notifyDataSetChanged(); + dialog.dismiss(); + } + }); + dialog.show(); + } + }); + items.install.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ModUtils mod=ModUtils.init(context); + mod.installMod(list.get(i), null); + } + }); + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent=new Intent(context, ModActivity.class); + intent.putExtra("mod", JSON.toJSONString(list.get(i))); + context.startActivity(intent); + } + }); return view; } private class Items{ ImageView icon; TextView title; + Button install,delete; } } diff --git a/app/src/main/java/com/yutou/jianrmg_v2/Fragments/Home.java b/app/src/main/java/com/yutou/jianrmg_v2/Fragments/Home.java index 42fb334..803f683 100644 --- a/app/src/main/java/com/yutou/jianrmg_v2/Fragments/Home.java +++ b/app/src/main/java/com/yutou/jianrmg_v2/Fragments/Home.java @@ -142,7 +142,7 @@ public class Home extends Fragment { endText.setText(" --已经没有了--"); adapter.setFooter(endText); recyclerView.setAdapter(adapter); - recyclerView.setRefreshAction(new Action() { + recyclerView.addRefreshAction(new Action() { @Override public void onAction() { min=0; diff --git a/app/src/main/java/com/yutou/jianrmg_v2/Fragments/MGList.java b/app/src/main/java/com/yutou/jianrmg_v2/Fragments/MGList.java index f63d358..8c3e0c3 100644 --- a/app/src/main/java/com/yutou/jianrmg_v2/Fragments/MGList.java +++ b/app/src/main/java/com/yutou/jianrmg_v2/Fragments/MGList.java @@ -71,7 +71,7 @@ public class MGList extends Fragment { endText.setText(" --已经没有了--"); adapter.setFooter(endText); recyclerView.setAdapter(adapter); - recyclerView.setRefreshAction(new Action() { + recyclerView.addRefreshAction(new Action() { @Override public void onAction() { min=0; diff --git a/app/src/main/java/com/yutou/jianrmg_v2/Fragments/ModListFragmentData.java b/app/src/main/java/com/yutou/jianrmg_v2/Fragments/ModListFragmentData.java index 0912789..d9122a7 100644 --- a/app/src/main/java/com/yutou/jianrmg_v2/Fragments/ModListFragmentData.java +++ b/app/src/main/java/com/yutou/jianrmg_v2/Fragments/ModListFragmentData.java @@ -71,7 +71,7 @@ public class ModListFragmentData { endText.setText(" --已经没有了--"); adapter.setFooter(endText); recyclerView.setAdapter(adapter); - recyclerView.setRefreshAction(new Action() { + recyclerView.addRefreshAction(new Action() { @Override public void onAction() { min=0; diff --git a/app/src/main/java/com/yutou/jianrmg_v2/Network/HttpApi.java b/app/src/main/java/com/yutou/jianrmg_v2/Network/HttpApi.java index 8c3cd4b..d68f86c 100644 --- a/app/src/main/java/com/yutou/jianrmg_v2/Network/HttpApi.java +++ b/app/src/main/java/com/yutou/jianrmg_v2/Network/HttpApi.java @@ -5,8 +5,8 @@ package com.yutou.jianrmg_v2.Network; */ public class HttpApi { - // public static final String HOME_URL="http://192.168.31.240:8088/android/"; //zzz_gz wifi - public static final String HOME_URL="http://192.168.137.1:8088/android/"; //笔记本本身WIFI + // public static final String HOME_URL="http://192.168.31.240:8088/android/"; //zzz_gz wifi + public static final String HOME_URL="http://192.168.137.1:8088/android/"; //笔记本本身WIFI // public static final String HOME_URL="http://game.yutou233.cn/android/"; //服务器 public static final String MOD_ALL="mod/all.do"; diff --git a/app/src/main/java/com/yutou/jianrmg_v2/Network/HttpUtils.java b/app/src/main/java/com/yutou/jianrmg_v2/Network/HttpUtils.java index 17bcbb7..ac3ea6f 100644 --- a/app/src/main/java/com/yutou/jianrmg_v2/Network/HttpUtils.java +++ b/app/src/main/java/com/yutou/jianrmg_v2/Network/HttpUtils.java @@ -77,6 +77,7 @@ public class HttpUtils { if(httpInterface!=null) httpInterface.httpError(e); e.printStackTrace(); + Log.e(e,HttpUtils.class); } @Override diff --git a/app/src/main/java/com/yutou/jianrmg_v2/Tools/Log.java b/app/src/main/java/com/yutou/jianrmg_v2/Tools/Log.java index 1b8ccbd..6cffab2 100644 --- a/app/src/main/java/com/yutou/jianrmg_v2/Tools/Log.java +++ b/app/src/main/java/com/yutou/jianrmg_v2/Tools/Log.java @@ -50,7 +50,7 @@ public class Log { * @param object 异常所在的类 * @return */ - public static String printf_Error(Exception e,Object object) { + public static String e(Exception e,Object object) { StringWriter writer=new StringWriter(); PrintWriter printWriter=new PrintWriter(writer); e.printStackTrace(printWriter); diff --git a/app/src/main/java/com/yutou/jianrmg_v2/Tools/ModUtils.java b/app/src/main/java/com/yutou/jianrmg_v2/Tools/ModUtils.java index 4911e76..7853bea 100644 --- a/app/src/main/java/com/yutou/jianrmg_v2/Tools/ModUtils.java +++ b/app/src/main/java/com/yutou/jianrmg_v2/Tools/ModUtils.java @@ -85,6 +85,10 @@ public class ModUtils { public void installMod(TMod mod, ModInterface modInterface) { this.mod = mod; + if(modfiles!=null&&modfiles.size()>0&&!mod.getId().equals(modfiles.get(0).getMid())){ + modfiles.clear(); + getModDownloadInfo(); + } if (modInterface == null) { modInterface = new ModInterface() { @Override @@ -102,9 +106,11 @@ public class ModUtils { getModDownloadInfo(); return; } - Log.i("安装mod", changeMod(mod, modfiles) + ""); - if (!isInstallMod(mod) && changeMod(mod, modfiles)) { + Log.i("安装mod", isInstallMod(mod) + " " + changeMod(mod, modfiles)); + if (changeMod(mod, modfiles) && !isInstallMod(mod)) { install(mod, modInterface); + } else if (isInstallMod(mod)) { + reBackMod(mod, modInterface); } else { if (getModPath(mod).listFiles().length > 0 && !changeMod(mod, modfiles)) { final MaterialDialog dialog = new MaterialDialog(context); @@ -190,7 +196,7 @@ public class ModUtils { } hud.dismiss(); dialog.dismiss(); - Toast.makeText(context, "安装成功,重启游戏生效", Toast.LENGTH_LONG).show(); + Utils.toast(context, "安装成功,重启游戏生效"); modInterface.onAction(true, MOD_INSTALL); } }); @@ -198,6 +204,7 @@ public class ModUtils { dialog.setPositiveButton("放弃", new View.OnClickListener() { @Override public void onClick(View view) { + modInterface.onAction(false,MOD_INSTALL); dialog.dismiss(); } }); @@ -218,15 +225,15 @@ public class ModUtils { private boolean rootInstall(File src, String path) { RootUtils root = RootUtils.init(context); if (RootUtils.su()) { - File tmpFile=new File("/data/data/"+context.getPackageName()+"/mods/"); - if(!tmpFile.getParentFile().exists()) + File tmpFile = new File("/data/data/" + context.getPackageName() + "/mods/"); + if (!tmpFile.getParentFile().exists()) tmpFile.getParentFile().mkdirs(); - if(tmpFile.exists()) + if (tmpFile.exists()) tmpFile.delete(); - Utils.copyFile(src.getAbsolutePath(),tmpFile.getAbsolutePath(),true); - root.exec("mkdir -p "+path); - root.exec("cp -f " + tmpFile.getAbsolutePath()+"/"+src.getName() + " " + path); - root.exec("chmod 777 " + path + src.getName()); + Utils.copyFile(src.getAbsolutePath(), tmpFile.getAbsolutePath(), true); + root.exec("mkdir -p " + path); + root.exec("cp -f " + tmpFile.getAbsolutePath() + "/" + src.getName() + " " + path); + root.exec("chmod 777 " + path + src.getName()); } return true; } @@ -267,6 +274,7 @@ public class ModUtils { if (modInterface != null) modInterface.onAction(true, MOD_UNINSTALL); dialog.dismiss(); + Utils.toast(context,"还原成功,重启游戏生效"); } }); dialog.setContentView(listView); @@ -295,14 +303,14 @@ public class ModUtils { Log.i("获取ROOT", "2"); backup.mkdirs(); } - File tmpFile=new File("/data/data/"+context.getPackageName()+"/mods/"+srcFile.getName()); - if(tmpFile.exists()) + File tmpFile = new File("/data/data/" + context.getPackageName() + "/mods/" + srcFile.getName()); + if (tmpFile.exists()) tmpFile.delete(); tmpFile.getParentFile().mkdirs(); - root.exec("mkdir -p "+srcPath); + root.exec("mkdir -p " + srcPath); root.exec("chmod 7777 " + srcPath + srcFile.getName()); root.exec("cp -f " + srcPath + srcFile.getName() + " " + tmpFile); - root.println("cp -f "+tmpFile.getAbsolutePath()+" "+backup.getAbsolutePath()); + root.println("cp -f " + tmpFile.getAbsolutePath() + " " + backup.getAbsolutePath()); } else { } } @@ -406,8 +414,8 @@ public class ModUtils { public static boolean changeMod(TMod mod, List modfiles) { for (TModfile modfile : modfiles) { if (!new File(Utils.getAppPath() + "/" + mod.getId() + "/" + modfile.getFilename()).exists()) { - Log.i(TAG,"mod不完整:"+Utils.getAppPath() + "/" + mod.getId() + "/" + modfile.getFilename()); - Log.i(TAG,JSON.toJSONString(modfile)); + Log.i(TAG, "mod不完整:" + Utils.getAppPath() + "/" + mod.getId() + "/" + modfile.getFilename()); + Log.i(TAG, JSON.toJSONString(modfile)); return false; } } diff --git a/app/src/main/java/com/yutou/jianrmg_v2/Tools/Utils.java b/app/src/main/java/com/yutou/jianrmg_v2/Tools/Utils.java index 43a6e7d..5c59b4a 100644 --- a/app/src/main/java/com/yutou/jianrmg_v2/Tools/Utils.java +++ b/app/src/main/java/com/yutou/jianrmg_v2/Tools/Utils.java @@ -141,10 +141,10 @@ public class Utils { // 判断目标文件是否存在 File destFile = new File(destFileName); // 如果目标文件所在目录不存在,则创建目录 - Log.i(TAG,"目标文件夹:"+destFileName+" exists:"+destFile.exists()); + Log.i(TAG, "目标文件夹:" + destFileName + " exists:" + destFile.exists()); if (!destFile.exists()) { // 目标文件所在目录不存在 - Log.i(TAG,"目标文件所在目录不存在"+destFile.getAbsolutePath()); + Log.i(TAG, "目标文件所在目录不存在" + destFile.getAbsolutePath()); if (!destFile.mkdirs()) { // 复制文件失败:创建目标文件所在目录失败 Log.i(TAG, " 复制文件失败:创建目标文件所在目录失败:" + destFileName); @@ -160,7 +160,7 @@ public class Utils { try { in = new FileInputStream(srcFile); - out = new FileOutputStream(destFile+"/"+srcFile.getName()); + out = new FileOutputStream(destFile + "/" + srcFile.getName()); byte[] buffer = new byte[1024]; while ((byteread = in.read(buffer)) != -1) { @@ -184,13 +184,14 @@ public class Utils { } } } - public static boolean writerFile(String srcFile,String data){ - File file=new File(srcFile); - if(!file.exists()){ - return false; + + public static boolean writerFile(String srcFile, String data) { + File file = new File(srcFile); + if (!file.exists()) { + return false; } try { - PrintWriter writer=new PrintWriter(file); + PrintWriter writer = new PrintWriter(file); writer.write(data); writer.flush(); writer.close(); @@ -200,16 +201,17 @@ public class Utils { } return false; } - public static String readFile(String srcFile){ - File file=new File(srcFile); - if(!file.exists()){ - return null; + + public static String readFile(String srcFile) { + File file = new File(srcFile); + if (!file.exists()) { + return null; } try { - BufferedReader reader=new BufferedReader(new FileReader(file)); - String tmp,str=""; - while ((tmp=reader.readLine())!=null){ - str+=tmp; + BufferedReader reader = new BufferedReader(new FileReader(file)); + String tmp, str = ""; + while ((tmp = reader.readLine()) != null) { + str += tmp; } return str; } catch (Exception e) { @@ -217,4 +219,16 @@ public class Utils { } return null; } + + public static void deleteFiles(String path) { + File files = new File(path); + if (files.exists()) { + if (files.isDirectory()) { + for (File file : files.listFiles()) { + deleteFiles(file.getAbsolutePath()); + } + } + files.delete(); + } + } } diff --git a/app/src/main/java/com/yutou/jianrmg_v2/views/DownloadListActivity.java b/app/src/main/java/com/yutou/jianrmg_v2/views/DownloadListActivity.java index 4a88734..75b945d 100644 --- a/app/src/main/java/com/yutou/jianrmg_v2/views/DownloadListActivity.java +++ b/app/src/main/java/com/yutou/jianrmg_v2/views/DownloadListActivity.java @@ -3,6 +3,7 @@ package com.yutou.jianrmg_v2.views; import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.os.Handler; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.view.KeyEvent; @@ -12,9 +13,14 @@ import android.view.View; import android.widget.LinearLayout; import android.widget.ListView; +import com.alibaba.fastjson.JSON; +import com.yutou.jianrmg_v2.Adapters.DownloadItemAdapter; +import com.yutou.jianrmg_v2.Data.AppData; +import com.yutou.jianrmg_v2.Data.TMod; import com.yutou.jianrmg_v2.Interfaces.HttpInterface; import com.yutou.jianrmg_v2.Network.HttpApi; import com.yutou.jianrmg_v2.Network.HttpUtils; +import com.yutou.jianrmg_v2.Tools.Log; import com.yutou.jianrmg_v2.Tools.Utils; import com.yutou.jianrmg_v2.R; @@ -24,20 +30,21 @@ import org.json.JSONObject; import java.io.File; import java.io.Serializable; +import java.util.List; import Interfaces.BaseActivityInterface; public class DownloadListActivity extends AppCompatActivity { private Context context; private ListView listView; - - + private List mods; + private Handler handler; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_download_list); this.context = this; - + handler=new Handler(); getDownloadFileList(); initViews(); } @@ -50,7 +57,7 @@ public class DownloadListActivity extends AppCompatActivity { if (path.isDirectory()){ try { array.put(Integer.valueOf(path.getName())+""); - }catch (Exception e){} + }catch (Exception e){ } } } json.put("ids",array); @@ -62,8 +69,13 @@ public class DownloadListActivity extends AppCompatActivity { if(json.getInt("code")!=100){ return; } - JSONArray dataList=json.getJSONArray("data"); - + mods= JSON.parseArray(json.getJSONArray("data").toString(),TMod.class); + handler.post(new Runnable() { + @Override + public void run() { + listView.setAdapter(new DownloadItemAdapter(context,mods)); + } + }); } catch (JSONException e) { e.printStackTrace(); } diff --git a/app/src/main/java/com/yutou/jianrmg_v2/views/FavoritesActivity.java b/app/src/main/java/com/yutou/jianrmg_v2/views/FavoritesActivity.java new file mode 100644 index 0000000..864ab45 --- /dev/null +++ b/app/src/main/java/com/yutou/jianrmg_v2/views/FavoritesActivity.java @@ -0,0 +1,14 @@ +package com.yutou.jianrmg_v2.views; + +import android.annotation.SuppressLint; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; + +public class FavoritesActivity extends AppCompatActivity { + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + } +} diff --git a/app/src/main/java/com/yutou/jianrmg_v2/views/ModActivity.java b/app/src/main/java/com/yutou/jianrmg_v2/views/ModActivity.java index 73c1024..9e866f0 100644 --- a/app/src/main/java/com/yutou/jianrmg_v2/views/ModActivity.java +++ b/app/src/main/java/com/yutou/jianrmg_v2/views/ModActivity.java @@ -7,9 +7,6 @@ import android.os.Bundle; import android.os.Handler; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.MotionEvent; import android.view.View; import android.widget.Button; import android.widget.FrameLayout; @@ -22,6 +19,7 @@ import com.alibaba.fastjson.JSON; import com.nostra13.universalimageloader.core.ImageLoader; import com.yutou.jianrmg_v2.Adapters.ReModListAdapter; import com.yutou.jianrmg_v2.Data.AppData; +import com.yutou.jianrmg_v2.Data.MGamePackname; import com.yutou.jianrmg_v2.Data.TMod; import com.yutou.jianrmg_v2.Data.TModtag; import com.yutou.jianrmg_v2.Interfaces.HttpInterface; @@ -32,16 +30,15 @@ import com.yutou.jianrmg_v2.R; import com.yutou.jianrmg_v2.Tools.Log; import com.yutou.jianrmg_v2.Tools.ModUtils; import com.yutou.jianrmg_v2.Tools.Utils; - +import com.zzhoujay.richtext.RichText; +import com.zzhoujay.richtext.RichType; +import com.zzhoujay.richtext.ig.DefaultImageGetter; import org.json.JSONObject; -import java.io.Serializable; import java.util.ArrayList; import java.util.List; -import Interfaces.BaseActivityInterface; -import cn.droidlover.xrichtext.XRichText; /** @@ -51,8 +48,7 @@ import cn.droidlover.xrichtext.XRichText; public class ModActivity extends AppCompatActivity{ private TMod tMod; private ImageView modImage, icon, collection_img; - private TextView title, by, downloadText; - private XRichText richText; + private TextView title, by, downloadText,richText; private LinearLayout tagsLayout; private FrameLayout collection, share, download; private ListView quote; @@ -107,24 +103,26 @@ public class ModActivity extends AppCompatActivity{ } private void initData(final TMod tMod) { + List installClick=modUtils.getInstallClens(); + System.out.println("---------->"+AppData.appConfig.getDownloadhome() + tMod.getImage()); + System.out.println("---------->"+AppData.appConfig.getDownloadhome() + tMod.getIcon()); imageLoader.displayImage(AppData.appConfig.getDownloadhome() + tMod.getImage(), modImage); imageLoader.displayImage(AppData.appConfig.getDownloadhome() + tMod.getIcon(), icon); title.setText(tMod.getTitle()); by.setText("@" + tMod.getByuser()); - richText.text(tMod.getInfo()); + RichText.fromHtml(tMod.getInfo()) + .imageGetter(new DefaultImageGetter()) + //.type(RichType.html) + .into(richText); downloadText.setTag(0); if (ModUtils.getModPath(tMod).listFiles().length > 0) { downloadText.setText("安装"); downloadText.setTag(2); } - if(ModUtils.isInstallMod(tMod)){ - downloadText.setText("还原"); - downloadText.setTag(1); - } download.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - downloadButtonClick(); + downloadButtonClick(); } }); collection.setOnClickListener(new View.OnClickListener() { @@ -140,7 +138,6 @@ public class ModActivity extends AppCompatActivity{ json.put("mid", tMod.getId() + ""); HttpUtils.post(HttpApi.HOME_URL + HttpApi.MOD_COLLCETION, json, new HttpInterface() { private String state = "收藏失败,未知错误"; - @Override public void httpGetData(String string, int code) { diff --git a/app/src/main/res/layout/activity_mod.xml b/app/src/main/res/layout/activity_mod.xml index bfccde2..0a54d4c 100644 --- a/app/src/main/res/layout/activity_mod.xml +++ b/app/src/main/res/layout/activity_mod.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="ModActivity"> + tools:context=".views.ModActivity"> + app:srcCompat="@drawable/ic_launcher_background" + tools:ignore="VectorDrawableCompat" /> + app:srcCompat="@drawable/ic_launcher_background" + tools:ignore="VectorDrawableCompat" /> + app:layout_constraintTop_toBottomOf="@+id/title"/> - + - + + + android:orientation="horizontal"> + + + + + + +