diff --git a/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.java b/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.java
deleted file mode 100644
index d61c027..0000000
--- a/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.java
+++ /dev/null
@@ -1,310 +0,0 @@
-package com.android.base.app.fragment;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.view.animation.Animation;
-
-import com.android.base.app.Sword;
-import com.android.base.app.activity.BackHandlerHelper;
-import com.android.base.app.activity.OnBackPressListener;
-import com.android.base.app.ui.LoadingView;
-import com.github.dmstocking.optional.java.util.function.Predicate;
-
-import org.jetbrains.annotations.NotNull;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
-import androidx.annotation.UiThread;
-import androidx.fragment.app.Fragment;
-import timber.log.Timber;
-
-/**
- * 提供:
- *
- * 1. RxJava 生命周期绑定。
- * 2. 返回键监听。
- * 3. 显示 LoadingDialog 和 Message。
- * 4. 可以添加生命周期代理。
- *
- *
- * @author Ztiany
- * date : 2016-03-19 23:09
- * email: 1169654504@qq.com
- */
-public class BaseFragment extends Fragment implements LoadingView, OnBackPressListener, FragmentDelegateOwner {
-
- private LoadingView mLoadingViewImpl;
-
- private View mLayoutView;
-
- /* just for cache*/
- private View mCachedView;
-
- private FragmentAnimatorHelper mFragmentAnimatorHelper;
-
- private final FragmentDelegates mFragmentDelegates = new FragmentDelegates(this);
-
- private String tag() {
- return this.getClass().getSimpleName();
- }
-
- @Override
- public void onAttach(@NotNull Context context) {
- super.onAttach(context);
- Timber.tag(tag()).d("onAttach() called with: context = [" + context + "]");
- mFragmentDelegates.onAttach(context);
- }
-
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- Timber.tag(tag()).d("-->onCreate savedInstanceState = " + savedInstanceState);
- mFragmentDelegates.onCreate(savedInstanceState);
- }
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- if (mCachedView == null) {
- Object layout = provideLayout();
- if (layout == null) {
- return null;
- }
- if (layout instanceof Integer) {
- return mCachedView = inflater.inflate((Integer) layout, container, false);
- }
- if (layout instanceof View) {
- return mCachedView = (View) layout;
- }
- throw new IllegalArgumentException("Here you should provide a layout id or a View");
- }
-
- Timber.tag(tag()).d("mCachedView.parent: " + mCachedView.getParent());
-
- if (mCachedView.getParent() != null) {
- ViewParent parent = mCachedView.getParent();
- if (parent instanceof ViewGroup) {
- ((ViewGroup) parent).removeView(mCachedView);
- }
- }
-
- return mCachedView;
- }
-
- /**
- * 使用此方法提供的布局,将只会被缓存起来,即此方法将只会被调用一次。
- *
- * @return provide a layout id or a View
- */
- @Nullable
- @SuppressWarnings("unused")
- protected Object provideLayout() {
- return null;
- }
-
- @Override
- public final void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- Timber.tag(tag()).d("-->onViewCreated savedInstanceState = " + savedInstanceState);
- if (mLayoutView != view) {
- mLayoutView = view;
- internalOnViewPrepared(view, savedInstanceState);
- onViewPrepared(view, savedInstanceState);
- }
- mFragmentDelegates.onViewCreated(view, savedInstanceState);
- }
-
- void internalOnViewPrepared(@NonNull View view, @Nullable Bundle savedInstanceState) {
- }
-
- /**
- * View is prepared, If {@link androidx.fragment.app.Fragment#onCreateView(LayoutInflater, ViewGroup, Bundle)} return same layout, it will be called once
- *
- * @param view view of fragment
- */
- protected void onViewPrepared(@NonNull View view, @Nullable Bundle savedInstanceState) {
- }
-
- @Override
- public void onActivityCreated(@Nullable Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- Timber.tag(tag()).d("-->onActivityCreated savedInstanceState = " + savedInstanceState);
- mFragmentDelegates.onActivityCreated(savedInstanceState);
- }
-
- @Override
- public void onStart() {
- super.onStart();
- Timber.tag(tag()).d("-->onStart");
- mFragmentDelegates.onStart();
- }
-
- @Override
- public void onResume() {
- super.onResume();
- Timber.tag(tag()).d("-->onResume");
- mFragmentDelegates.onResume();
- }
-
- @Override
- public void onPause() {
- Timber.tag(tag()).d("-->onPause");
- mFragmentDelegates.onPause();
- super.onPause();
- }
-
- @Override
- public void onStop() {
- Timber.tag(tag()).d("-->onStop");
- mFragmentDelegates.onStop();
- super.onStop();
- }
-
- @Override
- public void onDestroyView() {
- Timber.tag(tag()).d("-->onDestroyView");
- mFragmentDelegates.onDestroyView();
- super.onDestroyView();
- }
-
- @Override
- public void onDestroy() {
- Timber.tag(tag()).d("-->onDestroy");
- mFragmentDelegates.onDestroy();
- super.onDestroy();
- dismissLoadingDialog();
- }
-
- @Override
- public void onDetach() {
- Timber.tag(tag()).d("-->onDetach");
- mFragmentDelegates.onDetach();
- super.onDetach();
- }
-
- @Override
- public void onSaveInstanceState(@NonNull Bundle outState) {
- mFragmentDelegates.onSaveInstanceState(outState);
- super.onSaveInstanceState(outState);
- }
-
- @Override
- public void setUserVisibleHint(boolean isVisibleToUser) {
- super.setUserVisibleHint(isVisibleToUser);
- Timber.tag(tag()).d("-->setUserVisibleHint ==" + isVisibleToUser);
- mFragmentDelegates.setUserVisibleHint(isVisibleToUser);
- }
-
- @Override
- public void onHiddenChanged(boolean hidden) {
- super.onHiddenChanged(hidden);
- Timber.tag(tag()).d("-->onHiddenChanged = " + hidden);
- mFragmentDelegates.onHiddenChanged(hidden);
- }
-
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- mFragmentDelegates.onRequestPermissionsResult(requestCode, permissions, grantResults);
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- mFragmentDelegates.onActivityResult(requestCode, resultCode, data);
- }
-
- @Override
- @UiThread
- public final void addDelegate(FragmentDelegate fragmentDelegate) {
- mFragmentDelegates.addDelegate(fragmentDelegate);
- }
-
- @Override
- @UiThread
- public final boolean removeDelegate(FragmentDelegate fragmentDelegate) {
- return mFragmentDelegates.removeDelegate(fragmentDelegate);
- }
-
- @Override
- public FragmentDelegate findDelegate(Predicate predicate) {
- return mFragmentDelegates.findDelegate(predicate);
- }
-
- @Override
- public boolean onBackPressed() {
- return handleBackPress() || BackHandlerHelper.handleBackPress(this);
- }
-
- /**
- * Fragment需要自己处理BackPress事件,如果不处理,就交给子Fragment处理。都不处理则由Activity处理
- */
- protected boolean handleBackPress() {
- return false;
- }
-
- private LoadingView getLoadingViewImpl() {
- if (mLoadingViewImpl == null) {
- mLoadingViewImpl = onCreateLoadingView();
- }
- if (mLoadingViewImpl == null) {
- mLoadingViewImpl = Sword.get().getLoadingViewFactory().createLoadingDelegate(getContext());
- }
- return mLoadingViewImpl;
- }
-
- protected LoadingView onCreateLoadingView() {
- return null;
- }
-
- @Override
- public void showLoadingDialog() {
- getLoadingViewImpl().showLoadingDialog(true);
- }
-
- @Override
- public void showLoadingDialog(boolean cancelable) {
- getLoadingViewImpl().showLoadingDialog(cancelable);
- }
-
- @Override
- public void showLoadingDialog(CharSequence message, boolean cancelable) {
- getLoadingViewImpl().showLoadingDialog(message, cancelable);
- }
-
- @Override
- public void showLoadingDialog(@StringRes int messageId, boolean cancelable) {
- getLoadingViewImpl().showLoadingDialog(messageId, cancelable);
- }
-
- @Override
- public void dismissLoadingDialog() {
- getLoadingViewImpl().dismissLoadingDialog();
- }
-
- @Override
- public void showMessage(CharSequence message) {
- getLoadingViewImpl().showMessage(message);
- }
-
- @Override
- public void showMessage(@StringRes int messageId) {
- getLoadingViewImpl().showMessage(messageId);
- }
-
- @Nullable
- @Override
- public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
- if (mFragmentAnimatorHelper == null) {
- mFragmentAnimatorHelper = new FragmentAnimatorHelper(getContext(), FragmentConfig.defaultFragmentAnimator());
- }
- return mFragmentAnimatorHelper.onCreateAnimation(transit, enter);
- }
-
-}
\ No newline at end of file
diff --git a/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.kt b/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.kt
new file mode 100644
index 0000000..0fbf4d3
--- /dev/null
+++ b/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.kt
@@ -0,0 +1,263 @@
+package com.android.base.app.fragment
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.animation.Animation
+import androidx.annotation.StringRes
+import androidx.annotation.UiThread
+import androidx.fragment.app.Fragment
+import com.android.base.app.Sword
+import com.android.base.app.activity.BackHandlerHelper
+import com.android.base.app.activity.OnBackPressListener
+import com.android.base.app.ui.LoadingView
+import com.github.dmstocking.optional.java.util.function.Predicate
+import timber.log.Timber
+
+/**
+ *基础 BaseFragment 封装:
+ *
+ * 1. RxJava 生命周期绑定。
+ * 2. 返回键监听。
+ * 3. 显示 LoadingDialog 和 Message。
+ * 4. 可以添加生命周期代理。
+ *
+ * @author Ztiany
+ * date : 2016-03-19 23:09
+ * email: 1169654504@qq.com
+ */
+open class BaseFragment : Fragment(), LoadingView, OnBackPressListener, FragmentDelegateOwner {
+
+ private var loadingView: LoadingView? = null
+
+ private var layoutView: View? = null
+
+ /** just for cache*/
+ private var cachedView: View? = null
+
+ private var fragmentAnimatorHelper: FragmentAnimatorHelper? = null
+
+ @Suppress("LeakingThis")
+ private val fragmentDelegates = FragmentDelegates(this)
+
+ private fun tag() = this.javaClass.simpleName
+
+ override fun onAttach(context: Context) {
+ super.onAttach(context)
+ Timber.tag(tag()).d("onAttach() called with: context = [$context]")
+ fragmentDelegates.onAttach(context)
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ Timber.tag(tag()).d("-->onCreate savedInstanceState = $savedInstanceState")
+ fragmentDelegates.onCreate(savedInstanceState)
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ if (cachedView == null) {
+ val layout = provideLayout() ?: return null
+ if (layout is Int) {
+ return inflater.inflate(layout, container, false).also { cachedView = it }
+ }
+ if (layout is View) {
+ cachedView = layout
+ return layout
+ }
+ throw IllegalArgumentException("Here you should provide a layout id or a View")
+ }
+
+ Timber.tag(tag()).d("mCachedView.parent: " + cachedView?.parent)
+
+ cachedView?.run {
+ val viewParent = parent
+ if (viewParent != null && viewParent is ViewGroup) {
+ viewParent.removeView(this)
+ }
+ }
+
+ return cachedView
+ }
+
+ /**
+ * 使用此方法提供的布局,将只会被缓存起来,即此方法将只会被调用一次。
+ *
+ * @return provide a layout id or a View
+ */
+ protected open fun provideLayout(): Any? = null
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ Timber.tag(tag()).d("-->onViewCreated savedInstanceState = %s", savedInstanceState)
+ if (layoutView !== view) {
+ layoutView = view
+ internalOnViewPrepared(view, savedInstanceState)
+ onViewPrepared(view, savedInstanceState)
+ }
+ fragmentDelegates.onViewCreated(view, savedInstanceState)
+ }
+
+ internal open fun internalOnViewPrepared(view: View, savedInstanceState: Bundle?) {}
+
+ /**
+ * View is prepared, If [androidx.fragment.app.Fragment.onCreateView] return same layout, it will be called once
+ *
+ * @param view view of fragment
+ */
+ protected open fun onViewPrepared(view: View, savedInstanceState: Bundle?) {}
+
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ Timber.tag(tag()).d("-->onActivityCreated savedInstanceState = $savedInstanceState")
+ fragmentDelegates.onActivityCreated(savedInstanceState)
+ }
+
+ override fun onStart() {
+ super.onStart()
+ Timber.tag(tag()).d("-->onStart")
+ fragmentDelegates.onStart()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ Timber.tag(tag()).d("-->onResume")
+ fragmentDelegates.onResume()
+ }
+
+ override fun onPause() {
+ Timber.tag(tag()).d("-->onPause")
+ fragmentDelegates.onPause()
+ super.onPause()
+ }
+
+ override fun onStop() {
+ Timber.tag(tag()).d("-->onStop")
+ fragmentDelegates.onStop()
+ super.onStop()
+ }
+
+ override fun onDestroyView() {
+ Timber.tag(tag()).d("-->onDestroyView")
+ fragmentDelegates.onDestroyView()
+ super.onDestroyView()
+ }
+
+ override fun onDestroy() {
+ Timber.tag(tag()).d("-->onDestroy")
+ fragmentDelegates.onDestroy()
+ super.onDestroy()
+ dismissLoadingDialog()
+ }
+
+ override fun onDetach() {
+ Timber.tag(tag()).d("-->onDetach")
+ fragmentDelegates.onDetach()
+ super.onDetach()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ fragmentDelegates.onSaveInstanceState(outState)
+ super.onSaveInstanceState(outState)
+ }
+
+ override fun setUserVisibleHint(isVisibleToUser: Boolean) {
+ super.setUserVisibleHint(isVisibleToUser)
+ Timber.tag(tag()).d("-->setUserVisibleHint ==$isVisibleToUser")
+ fragmentDelegates.setUserVisibleHint(isVisibleToUser)
+ }
+
+ override fun onHiddenChanged(hidden: Boolean) {
+ super.onHiddenChanged(hidden)
+ Timber.tag(tag()).d("-->onHiddenChanged = $hidden")
+ fragmentDelegates.onHiddenChanged(hidden)
+ }
+
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ fragmentDelegates.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ fragmentDelegates.onActivityResult(requestCode, resultCode, data)
+ }
+
+ @UiThread
+ override fun addDelegate(fragmentDelegate: FragmentDelegate<*>?) {
+ fragmentDelegates.addDelegate(fragmentDelegate)
+ }
+
+ @UiThread
+ override fun removeDelegate(fragmentDelegate: FragmentDelegate<*>?): Boolean {
+ return fragmentDelegates.removeDelegate(fragmentDelegate)
+ }
+
+ override fun findDelegate(predicate: Predicate?>?): FragmentDelegate<*>? {
+ return fragmentDelegates.findDelegate(predicate)
+ }
+
+ final override fun onBackPressed(): Boolean {
+ return handleBackPress() || BackHandlerHelper.handleBackPress(this)
+ }
+
+ /**
+ * Fragment需要自己处理BackPress事件,如果不处理,就交给子Fragment处理。都不处理则由Activity处理
+ */
+ protected open fun handleBackPress(): Boolean {
+ return false
+ }
+
+ private fun loadingView(): LoadingView? {
+ val loadingViewImpl = loadingView
+ if (loadingViewImpl == null) {
+ loadingView = onCreateLoadingView()
+ }
+ if (loadingViewImpl == null) {
+ loadingView = Sword.get().loadingViewFactory.createLoadingDelegate(context)
+ }
+ return loadingViewImpl
+ }
+
+ protected open fun onCreateLoadingView(): LoadingView? {
+ return null
+ }
+
+ override fun showLoadingDialog() {
+ loadingView()?.showLoadingDialog(true)
+ }
+
+ override fun showLoadingDialog(cancelable: Boolean) {
+ loadingView()?.showLoadingDialog(cancelable)
+ }
+
+ override fun showLoadingDialog(message: CharSequence, cancelable: Boolean) {
+ loadingView()?.showLoadingDialog(message, cancelable)
+ }
+
+ override fun showLoadingDialog(@StringRes messageId: Int, cancelable: Boolean) {
+ loadingView()?.showLoadingDialog(messageId, cancelable)
+ }
+
+ override fun dismissLoadingDialog() {
+ loadingView()?.dismissLoadingDialog()
+ }
+
+ override fun showMessage(message: CharSequence) {
+ loadingView()?.showMessage(message)
+ }
+
+ override fun showMessage(@StringRes messageId: Int) {
+ loadingView()?.showMessage(messageId)
+ }
+
+ override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
+ if (fragmentAnimatorHelper == null) {
+ fragmentAnimatorHelper = FragmentAnimatorHelper(context, FragmentConfig.defaultFragmentAnimator())
+ }
+ return fragmentAnimatorHelper!!.onCreateAnimation(transit, enter)
+ }
+
+}
\ No newline at end of file
diff --git a/lib_base/src/main/java/com/android/base/app/fragment/BaseListFragment.java b/lib_base/src/main/java/com/android/base/app/fragment/BaseListFragment.java
deleted file mode 100644
index f1a4349..0000000
--- a/lib_base/src/main/java/com/android/base/app/fragment/BaseListFragment.java
+++ /dev/null
@@ -1,151 +0,0 @@
-package com.android.base.app.fragment;
-
-import android.os.Bundle;
-
-import com.android.base.adapter.DataManager;
-import com.android.base.app.ui.AutoPageNumber;
-import com.android.base.app.ui.PageNumber;
-import com.android.base.app.ui.RefreshListLayout;
-import com.ztiany.loadmore.adapter.ILoadMore;
-import com.ztiany.loadmore.adapter.OnLoadMoreListener;
-import com.ztiany.loadmore.adapter.WrapperAdapter;
-
-import java.util.List;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-
-/**
- * 通用的RecyclerView列表界面:支持下拉刷新和加载更多。
- *
- * @param 当前列表使用的数据类型
- * @author Ztiany
- * date : 2016-03-19 23:09
- * email: 1169654504@qq.com
- */
-public abstract class BaseListFragment extends BaseStateFragment implements RefreshListLayout {
-
- /**
- * 加载更多
- */
- private ILoadMore mLoadMore;
-
- /**
- * 列表数据管理
- */
- private DataManager mDataManager;
-
- /**
- * 分页页码
- */
- private PageNumber mPageNumber;
-
- @Override
- public void onActivityCreated(@Nullable Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- if (mDataManager == null) {
- throw new NullPointerException("you need set DataManager");
- }
- }
-
- protected final void setDataManager(@NonNull DataManager dataManager) {
- mDataManager = dataManager;
- }
-
- /**
- * Default PageNumber is {@link AutoPageNumber}
- *
- * @param recyclerAdapter adapter
- * @return recycler adapter wrapper
- */
- protected final RecyclerView.Adapter setupLoadMore(@NonNull RecyclerView.Adapter> recyclerAdapter) {
- if (mDataManager == null) {
- throw new IllegalStateException("you should setup a DataManager before call this method");
- }
- return setupLoadMore(recyclerAdapter, new AutoPageNumber(this, mDataManager));
- }
-
- protected final RecyclerView.Adapter setupLoadMore(@NonNull RecyclerView.Adapter> recyclerAdapter, @NonNull PageNumber pageNumber) {
- mPageNumber = pageNumber;
-
- WrapperAdapter wrap = WrapperAdapter.wrap(recyclerAdapter);
- mLoadMore = wrap;
- mLoadMore.setOnLoadMoreListener(new OnLoadMoreListener() {
- @Override
- public void onLoadMore() {
- BaseListFragment.this.onLoadMore();
- }
-
- @Override
- public boolean canLoadMore() {
- return !isRefreshing();
- }
- });
- return wrap;
- }
-
- @Override
- protected void onRefresh() {
- onStartLoad();
- }
-
- protected void onLoadMore() {
- onStartLoad();
- }
-
- @Override
- final boolean canRefresh() {
- return !isLoadingMore();
- }
-
- /**
- * call by {@link #onRefresh()} or {@link #onLoadMore()}, you can get current loading type from {@link #isRefreshing()} or {@link #isLoadingMore()}.
- */
- protected void onStartLoad() {
- }
-
- @Override
- public void replaceData(List data) {
- mDataManager.replaceAll(data);
- }
-
- @Override
- public void addData(List data) {
- mDataManager.addItems(data);
- }
-
- protected final ILoadMore getLoadMoreController() {
- return mLoadMore;
- }
-
- @Override
- public PageNumber getPager() {
- return mPageNumber;
- }
-
- @Override
- public boolean isEmpty() {
- return mDataManager.isEmpty();
- }
-
- @Override
- public boolean isLoadingMore() {
- return mLoadMore != null && mLoadMore.isLoadingMore();
- }
-
- @Override
- public void loadMoreCompleted(boolean hasMore) {
- if (mLoadMore != null) {
- mLoadMore.loadCompleted(hasMore);
- }
- }
-
- @Override
- public void loadMoreFailed() {
- if (mLoadMore != null) {
- mLoadMore.loadFail();
- }
- }
-
-}
\ No newline at end of file
diff --git a/lib_base/src/main/java/com/android/base/app/fragment/BaseListFragment.kt b/lib_base/src/main/java/com/android/base/app/fragment/BaseListFragment.kt
new file mode 100644
index 0000000..efd016d
--- /dev/null
+++ b/lib_base/src/main/java/com/android/base/app/fragment/BaseListFragment.kt
@@ -0,0 +1,89 @@
+package com.android.base.app.fragment
+
+import android.os.Bundle
+import androidx.recyclerview.widget.RecyclerView.Adapter
+import com.android.base.adapter.DataManager
+import com.android.base.app.ui.AutoPageNumber
+import com.android.base.app.ui.PageNumber
+import com.android.base.app.ui.RefreshListLayout
+import com.ztiany.loadmore.adapter.ILoadMore
+import com.ztiany.loadmore.adapter.OnLoadMoreListener
+import com.ztiany.loadmore.adapter.WrapperAdapter
+
+/**
+ * 通用的基于 RecyclerView 的列表界面,支持下拉刷新和加载更多。
+ *
+ * @param 当前列表使用的数据类型
+ * @author Ztiany
+ * date : 2016-03-19 23:09
+ * email: 1169654504@qq.com
+ */
+abstract class BaseListFragment : BaseStateFragment(), RefreshListLayout {
+
+ /**加载更多*/
+ private var loadMore: ILoadMore? = null
+
+ /**列表数据管理*/
+ private lateinit var dataManager: DataManager
+
+ /**分页页码*/
+ private var pageNumber: PageNumber? = null
+
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ if (!::dataManager.isInitialized) {
+ throw NullPointerException("you need set DataManager")
+ }
+ }
+
+ protected fun setDataManager(dataManager: DataManager) {
+ this.dataManager = dataManager
+ }
+
+ protected fun setupLoadMore(recyclerAdapter: Adapter<*>, pageNumber: PageNumber = AutoPageNumber(this, dataManager)): Adapter<*> {
+ this.pageNumber = pageNumber
+
+ return WrapperAdapter.wrap(recyclerAdapter).apply {
+ setOnLoadMoreListener(object : OnLoadMoreListener {
+ override fun onLoadMore() {
+ this@BaseListFragment.onLoadMore()
+ }
+
+ override fun canLoadMore(): Boolean {
+ return !isRefreshing
+ }
+ })
+ loadMore = this
+ }
+ }
+
+ /**call by [.onRefresh] or [.onLoadMore], you can get current loading type from [.isRefreshing] or [.isLoadingMore].*/
+ protected open fun onStartLoad() {}
+
+ override fun onRefresh() = onStartLoad()
+
+ protected fun onLoadMore() = onStartLoad()
+
+ override fun canRefresh() = !isLoadingMore
+
+ override fun replaceData(data: List)= dataManager.replaceAll(data)
+
+ override fun addData(data: List) = dataManager.addItems(data)
+
+ override fun isEmpty(): Boolean = dataManager.isEmpty
+
+ override fun isLoadingMore(): Boolean = loadMore != null && loadMore?.isLoadingMore ?: false
+
+ override fun getPager(): PageNumber = pageNumber ?: throw NullPointerException("you need to call setupLoadMore to init pageNumber")
+
+ fun loadMoreController(): ILoadMore = loadMore ?: throw NullPointerException("you need to call setupLoadMore to init loadMoreController")
+
+ override fun loadMoreCompleted(hasMore: Boolean) {
+ loadMore?.loadCompleted(hasMore)
+ }
+
+ override fun loadMoreFailed() {
+ loadMore?.loadFail()
+ }
+
+}
\ No newline at end of file
diff --git a/lib_base/src/main/java/com/android/base/app/fragment/BaseListV2Fragment.kt b/lib_base/src/main/java/com/android/base/app/fragment/BaseListV2Fragment.kt
index 158d980..24169a0 100644
--- a/lib_base/src/main/java/com/android/base/app/fragment/BaseListV2Fragment.kt
+++ b/lib_base/src/main/java/com/android/base/app/fragment/BaseListV2Fragment.kt
@@ -19,19 +19,11 @@ import com.android.base.app.ui.StateLayoutConfig
*/
abstract class BaseListV2Fragment : BaseFragment(), RefreshListLayout {
- companion object {
- protected const val CONTENT = StateLayoutConfig.CONTENT
- protected const val LOADING = StateLayoutConfig.LOADING
- protected const val ERROR = StateLayoutConfig.ERROR
- protected const val EMPTY = StateLayoutConfig.EMPTY
- protected const val NET_ERROR = StateLayoutConfig.NET_ERROR
- protected const val SERVER_ERROR = StateLayoutConfig.SERVER_ERROR
- }
-
private lateinit var stateLayout: RefreshLoadMoreStateLayoutImpl
+
protected open lateinit var dataManager: DataManager
- internal override fun internalOnViewPrepared(view: View, savedInstanceState: Bundle?) {
+ override fun internalOnViewPrepared(view: View, savedInstanceState: Bundle?) {
stateLayout = RefreshLoadMoreStateLayoutImpl.init(view)
stateLayout.refreshView.setRefreshHandler {
onRefresh()
@@ -52,9 +44,7 @@ abstract class BaseListV2Fragment : BaseFragment(), RefreshListLayout {
protected open fun onLoadMore() = onStartLoad()
- /**
- * call by [onRefresh] or [onLoadMore], you can get current loading type from [isRefreshing] or [isLoadingMore].
- */
+ /** call by [onRefresh] or [onLoadMore], you can get current loading type from [isRefreshing] or [isLoadingMore]. */
protected open fun onStartLoad() {}
override fun onActivityCreated(savedInstanceState: Bundle?) {
@@ -100,4 +90,13 @@ abstract class BaseListV2Fragment : BaseFragment(), RefreshListLayout {
override fun isLoadingMore() = stateLayout.refreshView.isLoadingMore
override fun currentStatus() = stateLayout.currentStatus()
+ companion object {
+ const val CONTENT = StateLayoutConfig.CONTENT
+ const val LOADING = StateLayoutConfig.LOADING
+ const val ERROR = StateLayoutConfig.ERROR
+ const val EMPTY = StateLayoutConfig.EMPTY
+ const val NET_ERROR = StateLayoutConfig.NET_ERROR
+ const val SERVER_ERROR = StateLayoutConfig.SERVER_ERROR
+ }
+
}
\ No newline at end of file
diff --git a/lib_base/src/main/java/com/android/base/app/fragment/BaseStateFragment.java b/lib_base/src/main/java/com/android/base/app/fragment/BaseStateFragment.java
deleted file mode 100644
index 27cc42f..0000000
--- a/lib_base/src/main/java/com/android/base/app/fragment/BaseStateFragment.java
+++ /dev/null
@@ -1,158 +0,0 @@
-package com.android.base.app.fragment;
-
-import android.os.Bundle;
-import android.view.View;
-
-import com.android.base.app.ui.RefreshStateLayout;
-import com.android.base.app.ui.RefreshView;
-import com.android.base.app.ui.StateLayoutConfig;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/**
- *
- * 1: 支持显示{CONTENT、LOADING、ERROR、EMPTY}四种布局、支持下拉刷新
- * 2: 使用的布局中必须有一个id = R.id.base_status_layout的Layout,切改Layout实现了StateLayout
- * 3: RefreshView(下拉刷新)的id必须设置为 :R.id.refresh_layout,没有添加则表示不需要下拉刷新功能
- * 4: 默认所有重试和下拉刷新都会调用{@link #onRefresh()},子类可以修改该行为
- *
- *
- * @author Ztiany
- * date : 2016-03-19 23:09
- * email: 1169654504@qq.com
- */
-@SuppressWarnings("unused")
-public abstract class BaseStateFragment extends BaseFragment implements RefreshStateLayout {
-
- private RefreshableStateLayoutImpl mStateLayout;
-
- protected static final int CONTENT = StateLayoutConfig.CONTENT;
- protected static final int LOADING = StateLayoutConfig.LOADING;
- protected static final int ERROR = StateLayoutConfig.ERROR;
- protected static final int EMPTY = StateLayoutConfig.EMPTY;
- protected static final int NET_ERROR = StateLayoutConfig.NET_ERROR;
- protected static final int SERVER_ERROR = StateLayoutConfig.SERVER_ERROR;
-
- @Override
- void internalOnViewPrepared(@NonNull View view, @Nullable Bundle savedInstanceState) {
- mStateLayout = RefreshableStateLayoutImpl.init(view);
- mStateLayout.setRefreshHandler(new RefreshView.RefreshHandler() {
- @Override
- public void onRefresh() {
- BaseStateFragment.this.onRefresh();
- }
-
- @Override
- public boolean canRefresh() {
- return BaseStateFragment.this.canRefresh();
- }
- });
-
- mStateLayout.setStateRetryListenerUnchecked(this::onRetry);
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- refreshCompleted();
- }
-
- boolean canRefresh() {
- return true;
- }
-
- final RefreshView getRefreshView() {
- return mStateLayout.getRefreshView();
- }
-
- protected void onRetry(@StateLayoutConfig.RetryableState int state) {
- if (getRefreshView() != null) {
- if (!getRefreshView().isRefreshing()) {
- autoRefresh();
- }
- } else {
- onRefresh();
- }
- }
-
- protected void onRefresh() {
- }
-
- public final void setRefreshEnable(boolean enable) {
- if (getRefreshView() != null) {
- getRefreshView().setRefreshEnable(enable);
- }
- }
-
- @Override
- @NonNull
- public final StateLayoutConfig getStateLayoutConfig() {
- return mStateLayout.getStateLayoutConfig();
- }
-
- private RefreshStateLayout getStateLayout() {
- return mStateLayout;
- }
-
- @Override
- public final boolean isRefreshing() {
- return mStateLayout.isRefreshing();
- }
-
- @Override
- public void refreshCompleted() {
- getStateLayout().refreshCompleted();
- }
-
- @Override
- public void autoRefresh() {
- getStateLayout().autoRefresh();
- }
-
- @Override
- public void showContentLayout() {
- getStateLayout().showContentLayout();
- }
-
- @Override
- public void showLoadingLayout() {
- getStateLayout().showLoadingLayout();
- }
-
- @Override
- public void showEmptyLayout() {
- getStateLayout().showEmptyLayout();
- }
-
- @Override
- public void showErrorLayout() {
- getStateLayout().showErrorLayout();
- }
-
- @Override
- public void showRequesting() {
- getStateLayout().showRequesting();
- }
-
- @Override
- public void showBlank() {
- getStateLayout().showBlank();
- }
-
- @Override
- public void showNetErrorLayout() {
- getStateLayout().showNetErrorLayout();
- }
-
- @Override
- public void showServerErrorLayout() {
- getStateLayout().showServerErrorLayout();
- }
-
- @Override
- public int currentStatus() {
- return mStateLayout.currentStatus();
- }
-
-}
diff --git a/lib_base/src/main/java/com/android/base/app/fragment/BaseStateFragment.kt b/lib_base/src/main/java/com/android/base/app/fragment/BaseStateFragment.kt
new file mode 100644
index 0000000..7e26c84
--- /dev/null
+++ b/lib_base/src/main/java/com/android/base/app/fragment/BaseStateFragment.kt
@@ -0,0 +1,101 @@
+package com.android.base.app.fragment
+
+import android.os.Bundle
+import android.view.View
+import com.android.base.R
+import com.android.base.app.ui.RefreshStateLayout
+import com.android.base.app.ui.RefreshView
+import com.android.base.app.ui.RefreshView.RefreshHandler
+import com.android.base.app.ui.StateLayoutConfig
+import com.android.base.app.ui.StateLayoutConfig.RetryableState
+import com.android.base.utils.common.ifNonNull
+import com.android.base.utils.common.otherwise
+
+/**
+ * 1. 支持显示{CONTENT, LOADING, ERROR, EMPTY}等状态布局、支持下拉刷新
+ * 2. 使用的布局中必须有一个id = [R.id.base_state_layout] 的 Layout,确保 Layout 实现了[com.android.base.app.ui.StateLayout]
+ * 3. [RefreshView] (下拉刷新)的 id 必须设置为 :[R.id.base_refresh_layout],没有添加则表示不需要下拉刷新功能
+ * 4. 默认所有重试和下拉刷新都会调用 [onRefresh],子类可以修改该行为
+ *
+ * @author Ztiany
+ * date : 2016-03-19 23:09
+ * email: 1169654504@qq.com
+ */
+abstract class BaseStateFragment : BaseFragment(), RefreshStateLayout {
+
+ private lateinit var stateLayout: RefreshableStateLayoutImpl
+
+ override fun internalOnViewPrepared(view: View, savedInstanceState: Bundle?) {
+ stateLayout = RefreshableStateLayoutImpl.init(view)
+ stateLayout.setRefreshHandler(object : RefreshHandler() {
+ override fun onRefresh() {
+ this@BaseStateFragment.onRefresh()
+ }
+
+ override fun canRefresh(): Boolean {
+ return this@BaseStateFragment.canRefresh()
+ }
+ })
+ stateLayout.setStateRetryListenerUnchecked { state -> onRetry(state) }
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ refreshCompleted()
+ }
+
+ internal open fun canRefresh() = true
+
+ private val refreshView: RefreshView?
+ get() = stateLayout.refreshView
+
+ protected open fun onRetry(@RetryableState state: Int) {
+ refreshView.ifNonNull {
+ if (this.isRefreshing) {
+ autoRefresh()
+ }
+ } otherwise {
+ onRefresh()
+ }
+ }
+
+ protected open fun onRefresh() {}
+
+ fun setRefreshEnable(enable: Boolean) = refreshView?.setRefreshEnable(enable)
+
+ override fun getStateLayoutConfig(): StateLayoutConfig = stateLayout.stateLayoutConfig
+
+ override fun isRefreshing() = stateLayout.isRefreshing
+
+ override fun refreshCompleted() = stateLayout.refreshCompleted()
+
+ override fun autoRefresh() = stateLayout.autoRefresh()
+
+ override fun showContentLayout() = stateLayout.showContentLayout()
+
+ override fun showLoadingLayout() = stateLayout.showLoadingLayout()
+
+ override fun showEmptyLayout() = stateLayout.showEmptyLayout()
+
+ override fun showErrorLayout() = stateLayout.showErrorLayout()
+
+ override fun showRequesting() = stateLayout.showRequesting()
+
+ override fun showBlank() = stateLayout.showBlank()
+
+ override fun showNetErrorLayout() = stateLayout.showNetErrorLayout()
+
+ override fun showServerErrorLayout() = stateLayout.showServerErrorLayout()
+
+ override fun currentStatus() = stateLayout.currentStatus()
+
+ companion object {
+ const val CONTENT = StateLayoutConfig.CONTENT
+ const val LOADING = StateLayoutConfig.LOADING
+ const val ERROR = StateLayoutConfig.ERROR
+ const val EMPTY = StateLayoutConfig.EMPTY
+ const val NET_ERROR = StateLayoutConfig.NET_ERROR
+ const val SERVER_ERROR = StateLayoutConfig.SERVER_ERROR
+ }
+
+}
\ No newline at end of file