package com.wangdaye.mysplash.main.view.widget; import android.annotation.SuppressLint; import android.content.Context; import android.support.v4.view.ViewCompat; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import com.github.rahatarmanahmed.cpv.CircularProgressView; import com.wangdaye.mysplash.R; import com.wangdaye.mysplash.common._basic.MysplashActivity; import com.wangdaye.mysplash.common.i.model.LoadModel; import com.wangdaye.mysplash.common.i.model.NotificationsModel; import com.wangdaye.mysplash.common.i.model.ScrollModel; import com.wangdaye.mysplash.common.i.presenter.LoadPresenter; import com.wangdaye.mysplash.common.i.presenter.NotificationsPresenter; import com.wangdaye.mysplash.common.i.presenter.ScrollPresenter; import com.wangdaye.mysplash.common.i.view.LoadView; import com.wangdaye.mysplash.common.i.view.ScrollView; import com.wangdaye.mysplash.common.ui.adapter.NotificationAdapter; import com.wangdaye.mysplash.common.ui.decotarion.ListDecoration; import com.wangdaye.mysplash.common.ui.widget.SwipeBackCoordinatorLayout; import com.wangdaye.mysplash.common.ui.widget.nestedScrollView.NestedScrollFrameLayout; import com.wangdaye.mysplash.common.ui.widget.swipeRefreshView.BothWaySwipeRefreshLayout; import com.wangdaye.mysplash.common.utils.AnimUtils; import com.wangdaye.mysplash.common.utils.BackToTopUtils; import com.wangdaye.mysplash.common.utils.helper.ImageHelper; import com.wangdaye.mysplash.common.utils.manager.ThemeManager; import com.wangdaye.mysplash.common.utils.manager.UserNotificationManager; import com.wangdaye.mysplash.main.model.widget.LoadObject; import com.wangdaye.mysplash.main.model.widget.NotificationsObject; import com.wangdaye.mysplash.main.model.widget.ScrollObject; import com.wangdaye.mysplash.main.presenter.widget.LoadImplementor; import com.wangdaye.mysplash.main.presenter.widget.NotificationsImplementor; import com.wangdaye.mysplash.main.presenter.widget.ScrollImplementor; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; /** * Notifications view. * * This view is used to show user's notifications for * {@link com.wangdaye.mysplash.main.view.activity.NotificationActivity}. * * */ public class NotificationsView extends NestedScrollFrameLayout implements com.wangdaye.mysplash.common.i.view.NotificationsView, LoadView, ScrollView, BothWaySwipeRefreshLayout.OnRefreshAndLoadListener { @BindView(R.id.container_loading_in_category_view_large_progressView) CircularProgressView progressView; @BindView(R.id.container_loading_in_category_view_large_feedbackContainer) RelativeLayout feedbackContainer; @BindView(R.id.container_loading_in_category_view_large_feedbackTxt) TextView feedbackText; @BindView(R.id.container_photo_list_swipeRefreshLayout) BothWaySwipeRefreshLayout refreshLayout; @BindView(R.id.container_photo_list_recyclerView) RecyclerView recyclerView; private NotificationsModel notificationsModel; private NotificationsPresenter notificationsPresenter; private LoadModel loadModel; private LoadPresenter loadPresenter; private ScrollModel scrollModel; private ScrollPresenter scrollPresenter; public NotificationsView(Context context) { super(context); this.initialize(); } public NotificationsView(Context context, AttributeSet attrs) { super(context, attrs); this.initialize(); } public NotificationsView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.initialize(); } // init. @SuppressLint("InflateParams") private void initialize() { View searchingView = LayoutInflater.from(getContext()) .inflate(R.layout.container_loading_in_category_view_large, this, false); addView(searchingView); View contentView = LayoutInflater.from(getContext()) .inflate(R.layout.container_photo_list, null); addView(contentView); ButterKnife.bind(this, this); initModel(); initPresenter(); initView(); } private void initModel() { this.notificationsModel = new NotificationsObject(getContext()); this.loadModel = new LoadObject(LoadObject.LOADING_STATE); this.scrollModel = new ScrollObject(true); } private void initPresenter() { this.notificationsPresenter = new NotificationsImplementor( getContext(), notificationsModel, this); this.loadPresenter = new LoadImplementor(loadModel, this); this.scrollPresenter = new ScrollImplementor(scrollModel, this); } private void initView() { this.initContentView(); this.initLoadingView(); } private void initContentView() { refreshLayout.setColorSchemeColors(ThemeManager.getContentColor(getContext())); refreshLayout.setProgressBackgroundColorSchemeColor(ThemeManager.getRootColor(getContext())); refreshLayout.setOnRefreshAndLoadListener(this); refreshLayout.setPermitRefresh(false); refreshLayout.setPermitLoad(false); refreshLayout.setVisibility(GONE); recyclerView.setAdapter(notificationsPresenter.getAdapter()); recyclerView.setLayoutManager( new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); recyclerView.addItemDecoration(new ListDecoration(getContext())); recyclerView.addOnScrollListener(scrollListener); } private void initLoadingView() { progressView.setVisibility(VISIBLE); feedbackContainer.setVisibility(GONE); ImageView feedbackImg = ButterKnife.findById( this, R.id.container_loading_in_category_view_large_feedbackImg); ImageHelper.loadIcon(getContext(), feedbackImg, R.drawable.feedback_no_photos); } // control. /** * Set activity for the adapter in this view. * * @param a Container activity. * */ public void setActivity(MysplashActivity a) { notificationsPresenter.setActivityForAdapter(a); } @Override public boolean isParentOffset() { return false; } public NotificationAdapter getAdapter() { return notificationsPresenter.getAdapter(); } public UserNotificationManager.OnUpdateNotificationListener getOnUpdateNotificationListener() { return (NotificationsImplementor) notificationsPresenter; } // HTTP request. public void initRefresh() { notificationsPresenter.initRefresh(getContext()); } public void cancelRequest() { notificationsPresenter.cancelRequest(); } // back to top. public boolean needPagerBackToTop() { return scrollPresenter.needBackToTop(); } public void pagerScrollToTop() { scrollPresenter.scrollToTop(); } // swipe back. public boolean canSwipeBack(int dir) { switch (loadPresenter.getLoadState()) { case com.wangdaye.mysplash.collection.model.widget.LoadObject.NORMAL_STATE: return SwipeBackCoordinatorLayout.canSwipeBack(recyclerView, dir) || notificationsPresenter.getAdapter().getItemCount() <= 0; default: return true; } } // interface. // on click listener. @OnClick(R.id.container_loading_in_category_view_large_feedbackBtn) void retryRefresh() { notificationsPresenter.initRefresh(getContext()); } // on refresh an load listener. @Override public void onRefresh() { // do nothing. } @Override public void onLoad() { notificationsPresenter.loadMore(getContext(), false); } // on scroll listener. private RecyclerView.OnScrollListener scrollListener = new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); scrollPresenter.autoLoad(dy); } }; // view. // notifications view. @Override public void setRefreshing(boolean refreshing) { refreshLayout.setRefreshing(refreshing); } @Override public void setLoading(boolean loading) { refreshLayout.setLoading(loading); } @Override public void setPermitRefreshing(boolean permit) { refreshLayout.setPermitRefresh(permit); } @Override public void setPermitLoading(boolean permit) { refreshLayout.setPermitLoad(permit); } @Override public void initRefreshStart() { loadPresenter.setLoadingState(); } @Override public void requestNotificationsSuccess() { loadPresenter.setNormalState(); } @Override public void requestNotificationsFailed(String feedback) { feedbackText.setText(feedback); loadPresenter.setFailedState(); } // load view. @Override public void animShow(View v) { AnimUtils.animShow(v); } @Override public void animHide(final View v) { AnimUtils.animHide(v); } @Override public void setLoadingState() { animShow(progressView); animHide(feedbackContainer); } @Override public void setFailedState() { animShow(feedbackContainer); animHide(progressView); } @Override public void setNormalState() { animShow(refreshLayout); animHide(progressView); } @Override public void resetLoadingState() { animShow(progressView); animHide(refreshLayout); } // scroll view. @Override public void scrollToTop() { BackToTopUtils.scrollToTop(recyclerView); } @Override public void autoLoad(int dy) { int lastVisibleItem = ((LinearLayoutManager) recyclerView.getLayoutManager()).findLastVisibleItemPosition(); int totalItemCount = notificationsPresenter.getAdapter().getItemCount(); if (notificationsPresenter.canLoadMore() && lastVisibleItem >= totalItemCount - 10 && totalItemCount > 0 && dy > 0) { notificationsPresenter.loadMore(getContext(), false); } if (!ViewCompat.canScrollVertically(recyclerView, -1)) { scrollPresenter.setToTop(true); } else { scrollPresenter.setToTop(false); } if (!ViewCompat.canScrollVertically(recyclerView, 1) && notificationsPresenter.isLoading()) { refreshLayout.setLoading(true); } } @Override public boolean needBackToTop() { return !scrollPresenter.isToTop() && loadPresenter.getLoadState() == LoadObject.NORMAL_STATE; } }