From 069cd7db7f38a8da1e3816c535d338508f3ed4f3 Mon Sep 17 00:00:00 2001 From: Ztiany Date: Fri, 11 Oct 2019 20:24:00 +0800 Subject: [PATCH] baseFragment to kotlin --- .../base/app/fragment/BaseFragment.java | 310 ------------------ .../android/base/app/fragment/BaseFragment.kt | 263 +++++++++++++++ .../base/app/fragment/BaseListFragment.java | 151 --------- .../base/app/fragment/BaseListFragment.kt | 89 +++++ .../base/app/fragment/BaseListV2Fragment.kt | 25 +- .../base/app/fragment/BaseStateFragment.java | 158 --------- .../base/app/fragment/BaseStateFragment.kt | 101 ++++++ 7 files changed, 465 insertions(+), 632 deletions(-) delete mode 100644 lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.java create mode 100644 lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.kt delete mode 100644 lib_base/src/main/java/com/android/base/app/fragment/BaseListFragment.java create mode 100644 lib_base/src/main/java/com/android/base/app/fragment/BaseListFragment.kt delete mode 100644 lib_base/src/main/java/com/android/base/app/fragment/BaseStateFragment.java create mode 100644 lib_base/src/main/java/com/android/base/app/fragment/BaseStateFragment.kt 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