Java tutorial
/* * Copyright 2015 Ayuget * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.ayuget.redface.ui.fragment; import android.content.Intent; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageView; import com.ayuget.redface.R; import com.ayuget.redface.account.UserManager; import com.ayuget.redface.data.api.MDService; import com.ayuget.redface.data.api.model.PrivateMessage; import com.ayuget.redface.data.rx.EndlessObserver; import com.ayuget.redface.data.rx.SubscriptionHandler; import com.ayuget.redface.settings.RedfaceSettings; import com.ayuget.redface.ui.UIConstants; import com.ayuget.redface.ui.activity.MultiPaneActivity; import com.ayuget.redface.ui.activity.WritePrivateMessageActivity; import com.ayuget.redface.ui.adapter.PrivateMessagesAdapter; import com.ayuget.redface.ui.misc.DataPresenter; import com.ayuget.redface.ui.misc.DividerItemDecoration; import com.ayuget.redface.ui.misc.EndlessScrollListener; import com.ayuget.redface.ui.misc.SnackbarHelper; import com.ayuget.redface.ui.misc.UiUtils; import com.ayuget.redface.ui.view.ContextMenuRecyclerView; import com.squareup.phrase.Phrase; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; import butterknife.InjectView; public class PrivateMessageListFragment extends ToggleToolbarFragment implements PrivateMessagesAdapter.OnPMClickedListener, PrivateMessagesAdapter.OnPMLongClickListener { private static final String LOG_TAG = PrivateMessageListFragment.class.getSimpleName(); private static final String ARG_PRIVATE_MESSAGES_LIST = "pms_list"; private static final String ARG_LAST_LOADED_PAGE = "last_loaded_page"; private PrivateMessagesAdapter pmAdapter; private LinearLayoutManager layoutManager; protected DataPresenter dataPresenter; private ArrayList<PrivateMessage> displayedPrivateMessages; private SubscriptionHandler<Integer, List<PrivateMessage>> pmSubscriptionHandler = new SubscriptionHandler<>(); private int lastLoadedPage; /** * Interface definition for a callback to be invoked when a private message in * this fragment has been clicked. */ public interface OnPrivateMessageClickedListener { void onPrivateMessageClicked(PrivateMessage privateMessage); } private OnPrivateMessageClickedListener onPrivateMessageClickedListener; @InjectView(R.id.private_messages_list) ContextMenuRecyclerView pmRecyclerView; @InjectView(R.id.pm_list_swipe_refresh_layout) SwipeRefreshLayout swipeRefreshLayout; @InjectView(R.id.loading_indicator) View loadingIndicator; @InjectView(R.id.error_layout) View errorView; @InjectView(R.id.error_reload_button) Button errorReloadButton; @InjectView(R.id.empty_reload_button) Button emptyReloadButton; @InjectView(R.id.empty_content_layout) View noPrivateMessagesLayout; @InjectView(R.id.empty_content_image) ImageView noPrivateMessagesImage; @Inject RedfaceSettings settings; @Inject MDService mdService; @Inject UserManager userManager; public static PrivateMessageListFragment newInstance() { PrivateMessageListFragment fragment = new PrivateMessageListFragment(); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); pmAdapter = new PrivateMessagesAdapter( new ContextThemeWrapper(getActivity(), themeManager.getActiveThemeStyle()), themeManager, settings.isCompactModeEnabled()); pmAdapter.setOnPMClickedListener(this); pmAdapter.setOnPMLongClickListener(this); } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflateRootView(R.layout.fragment_private_message_list, inflater, container); Drawable listDivider = getActivity().getResources().getDrawable(themeManager.getListDividerDrawable()); pmRecyclerView.setHasFixedSize(true); pmRecyclerView.addItemDecoration(new DividerItemDecoration(listDivider, false, false)); registerForContextMenu(pmRecyclerView); layoutManager = new LinearLayoutManager(getActivity()); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); pmRecyclerView.setLayoutManager(layoutManager); pmRecyclerView.setAdapter(pmAdapter); swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { Log.d(LOG_TAG, "Refreshing private messages"); loadPrivateMessages(1); } }); dataPresenter = DataPresenter.from(rootView).withDataView(R.id.pm_list_swipe_refresh_layout) .withEmptyView(R.id.empty_content_layout, R.id.empty_reload_button) .withErrorView(R.id.error_layout, R.id.error_reload_button).withLoadingView(R.id.loading_indicator) .build(); dataPresenter.setOnRefreshRequestedListener(new DataPresenter.OnRefreshRequestedListener() { @Override public void onRefresh() { dataPresenter.showLoadingView(); loadPrivateMessages(1); } }); // Style refresh indicator and empty content view swipeRefreshLayout.setColorSchemeResources(R.color.theme_primary, R.color.theme_primary_dark); UiUtils.setDrawableColor(noPrivateMessagesImage.getDrawable(), getResources().getColor(R.color.empty_view_image_color)); return rootView; } @Override public void onCreateOptionsMenu(Toolbar toolbar) { toolbar.inflateMenu(R.menu.menu_pm_list); } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); switch (id) { case R.id.action_new_private_message: startNewPMActivity(); break; } return super.onOptionsItemSelected(item); } @Override public void onToolbarInitialized(Toolbar toolbar) { pmRecyclerView.addOnScrollListener(new EndlessScrollListener(layoutManager) { @Override public void onLoadMore(int page, int totalItemsCount) { int realPage = page + 1; if (realPage > lastLoadedPage) { loadPrivateMessages(realPage); } } }); int progressBarStartMargin = getResources() .getDimensionPixelSize(R.dimen.swipe_refresh_progress_bar_start_margin); int progressBarEndMargin = getResources() .getDimensionPixelSize(R.dimen.swipe_refresh_progress_bar_end_margin); swipeRefreshLayout.setProgressViewOffset(false, progressBarStartMargin, progressBarEndMargin); toolbar.setTitle(R.string.navdrawer_item_private_messages); } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if (savedInstanceState != null) { displayedPrivateMessages = savedInstanceState.getParcelableArrayList(ARG_PRIVATE_MESSAGES_LIST); if (displayedPrivateMessages != null) { Log.d(LOG_TAG, String.format("Restored %d private messages", displayedPrivateMessages.size())); pmAdapter.replaceWith(displayedPrivateMessages); showPrivateMessages(); } } } /** * Refresh private messages list */ public void refreshData() { loadPrivateMessages(1); } @Override public void onResume() { super.onResume(); if (displayedPrivateMessages == null) { displayedPrivateMessages = new ArrayList<>(); loadPrivateMessages(1); } else { showPrivateMessages(); } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelableArrayList(ARG_PRIVATE_MESSAGES_LIST, displayedPrivateMessages); outState.putInt(ARG_LAST_LOADED_PAGE, lastLoadedPage); } @Override public void onPrivateMessageClicked(PrivateMessage privateMessage) { // Propagate event to listener if registred if (onPrivateMessageClickedListener != null) { onPrivateMessageClickedListener.onPrivateMessageClicked(privateMessage); } } @Override public void onPrivateMessageLongClick(int position) { } /** * Shows the private messages list, or the empty view if there are no PMs to display */ private void showPrivateMessages() { if (displayedPrivateMessages.size() > 0) { dataPresenter.showDataView(); } else { dataPresenter.showEmptyView(); } } /** * Loads private messages * @param page page to load */ private void loadPrivateMessages(final int page) { Log.d(LOG_TAG, String.format("Loading private messages page %d", page)); subscribe(pmSubscriptionHandler.load(1, mdService.listPrivateMessages(userManager.getActiveUser(), page), new EndlessObserver<List<PrivateMessage>>() { @Override public void onNext(List<PrivateMessage> privateMessages) { Log.d(LOG_TAG, String.format("Loading request completed, %d private messages loaded", privateMessages.size())); if (page == 1) { displayedPrivateMessages.clear(); } displayedPrivateMessages.addAll(privateMessages); if (page == 1) { pmAdapter.replaceWith(privateMessages); } else { pmAdapter.extendWith(privateMessages); } swipeRefreshLayout.setRefreshing(false); lastLoadedPage = page; showPrivateMessages(); } @Override public void onError(Throwable throwable) { Log.d(LOG_TAG, String.format("Error loading private messages page %d", page), throwable); swipeRefreshLayout.setRefreshing(false); // Do not display error view because some private messages are displayed (we are "just" loading additional content) if (page == 1) { dataPresenter.showErrorView(); } else { SnackbarHelper.make(PrivateMessageListFragment.this, Phrase.from(getActivity(), R.string.error_loading_private_messages_page) .put("page", page).format()) .show(); } } })); } public void setOnPrivateMessageClickedListener( OnPrivateMessageClickedListener onPrivateMessageClickedListener) { this.onPrivateMessageClickedListener = onPrivateMessageClickedListener; } private void startNewPMActivity() { MultiPaneActivity hostActivity = (MultiPaneActivity) getActivity(); if (hostActivity.canLaunchReplyActivity()) { hostActivity.setCanLaunchReplyActivity(false); Intent intent = new Intent(getActivity(), WritePrivateMessageActivity.class); getActivity().startActivityForResult(intent, UIConstants.NEW_PM_REQUEST_CODE); } } }