按照如下步骤开发
- Step1 数据层:数据仓库实现
public class HotContentItem {
public String id;
public String name;
public String desc;
public long timeStamp;
}
复制代码
public class HotContentNetRepository {
public Either<? extends Failure, List<HotContentItem>> refreshNew() {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
Either<? extends Failure, List<HotContentItem>> result;
Random random = new Random();
boolean success = random.nextInt(10) > 3;
if (success) {
result = Either.right((mockItemList(0)));
} else if (random.nextInt(10) > 3) {
result = Either.right(Collections.<HotContentItem>emptyList());
} else {
result = Either.left(new NetworkFailure());
}
return result;
}
}
复制代码
- Step2 逻辑层:数据仓库选择及使用
- 省略列这一步,按照业务需求实现不一样的数据仓库组合使用
- Step3 逻辑层:实现UseCase(示例代码:刷新数据)
public class HotContentRefreshNew extends BaseUseCase<List<HotContentItem>, Void> {
private HotContentNetRepository mNetRepository;
public HotContentRefreshNew( MutableLiveData<List<HotContentItem>> data, MutableLiveData<Failure> failure) {
super(data, failure);
mNetRepository = new HotContentNetRepository();
}
@Override
protected Either<? extends Failure, List<HotContentItem>> loadData(Void aVoid) {
Either<? extends Failure, List<HotContentItem>> result = mNetRepository.refreshNew();
if (result.isRight() && CollectionUtil.isEmpty(result.right())) {
Failure failure = new RefreshNewFailure(RefreshNewFailure.CODE_DATA_EMPTY, "Data is empty!");
result = Either.left(failure);
}
return result;
}
@Override
protected Failure processFailure(Failure failure) {
...
}
}
复制代码
- Step4 展现层:UI框架选择
- 示例界面是做为一个TabLayout的一个Page页,所以这里选择"具有生命周期View"做为的UI框架,这是个自定的View,实现了LifecycleOwner接口(参考了LifecycleActivity和LifecycleFragment的实现逻辑)
public abstract class BaseLifecycleView extends FrameLayout implements LifecycleOwner {
private final LifecycleRegistry mRegistry = new LifecycleRegistry(this);
private ViewModelStore mViewModelStore = new ViewModelStore();
public BaseLifecycleView(@NonNull Context context) {
super(context);
}
protected abstract void onCreate();
protected abstract void onDestroy();
@Override
public Lifecycle getLifecycle() {
return mRegistry;
}
@Override
@CallSuper
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mRegistry.handleLifecycleEvent(Event.ON_CREATE);
onCreate();
if (getVisibility() == View.VISIBLE) {
mRegistry.handleLifecycleEvent(Event.ON_START);
}
}
@Override
@CallSuper
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mRegistry.handleLifecycleEvent(Event.ON_DESTROY);
mViewModelStore.clear();
onDestroy();
}
@Override
@CallSuper
protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
Event event = visibility == View.VISIBLE ? Event.ON_RESUME : Event.ON_PAUSE;
mRegistry.handleLifecycleEvent(event);
}
@Override
@CallSuper
public void onStartTemporaryDetach() {
super.onStartTemporaryDetach();
State state = mRegistry.getCurrentState();
if (state == State.RESUMED) {
mRegistry.handleLifecycleEvent(Event.ON_STOP);
}
}
@Override
@CallSuper
public void onFinishTemporaryDetach() {
super.onFinishTemporaryDetach();
State state = mRegistry.getCurrentState();
if (state == State.CREATED) {
mRegistry.handleLifecycleEvent(Event.ON_START);
}
}
protected <T extends ViewModel> T getViewModel(@NonNull ViewModelProvider.NewInstanceFactory modelFactory, @NonNull Class<T> modelClass) {
return new ViewModelProvider(mViewModelStore, modelFactory).get(modelClass);
}
}
复制代码
- Step5 展现层:定义本身的LiveData和ViewModel
public class HotContentViewModel extends BaseViewModel<List<HotContentItem>> {
private HotContentRefreshNew mRefreshNew;
public HotContentViewModel() {
refreshNew();
}
public void refreshNew() {
AssertUtil.mustInUiThread();
if (mRefreshNew == null) {
mRefreshNew = new HotContentRefreshNew(getMutableLiveData(), getMutableFailure());
}
mRefreshNew.executeOnAsyncThread(null);
}
...
}
复制代码
public class HotContentView extends BaseLifecycleView {
private HotContentViewModel mViewModel;
private SwipeRefreshLayout mSwipeRefreshLayout;
private AutoLoadMoreRecycleView mRecyclerView;
private HotContentAdapter mContentAdapter;
public HotContentView(@NonNull Context context) {
super(context);
视图对象初始化
...
mRecyclerView.setLoadMoreListener(new LoadMoreListener() {
@Override
public void onLoadMore() {
HotContentItem lastOne = CollectionUtil.lastOne(mViewModel.getData().getValue());
if (lastOne == null) {
mRecyclerView.completeLoadMore("No more data");
} else {
mViewModel.loadHistory(lastOne);
}
}
});
...
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
mViewModel.refreshNew();
}
});
}
@Override
protected void onCreate() {
mViewModel = getViewModel(new NewInstanceFactory(), HotContentViewModel.class);
mViewModel.getData().observe(this, new Observer<List<HotContentItem>>() {
@Override
public void onChanged(@Nullable List<HotContentItem> hotContentItems) {
mContentAdapter.setItemList(hotContentItems);
mSwipeRefreshLayout.setRefreshing(false);
...
}
});
...
}
@Override
protected void onDestroy() {
}
}
复制代码