summaryrefslogtreecommitdiffstats
path: root/src/com/android/messaging/ui/conversationlist/ConversationListFragment.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/messaging/ui/conversationlist/ConversationListFragment.java')
-rw-r--r--src/com/android/messaging/ui/conversationlist/ConversationListFragment.java446
1 files changed, 0 insertions, 446 deletions
diff --git a/src/com/android/messaging/ui/conversationlist/ConversationListFragment.java b/src/com/android/messaging/ui/conversationlist/ConversationListFragment.java
deleted file mode 100644
index 2f868d4..0000000
--- a/src/com/android/messaging/ui/conversationlist/ConversationListFragment.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * 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.android.messaging.ui.conversationlist;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.content.Context;
-import android.database.Cursor;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.support.v4.view.ViewCompat;
-import android.support.v4.view.ViewGroupCompat;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.view.ViewGroup.MarginLayoutParams;
-import android.view.ViewPropertyAnimator;
-import android.view.accessibility.AccessibilityManager;
-import android.widget.AbsListView;
-import android.widget.ImageView;
-
-import com.android.messaging.R;
-import com.android.messaging.annotation.VisibleForAnimation;
-import com.android.messaging.datamodel.DataModel;
-import com.android.messaging.datamodel.binding.Binding;
-import com.android.messaging.datamodel.binding.BindingBase;
-import com.android.messaging.datamodel.data.ConversationListData;
-import com.android.messaging.datamodel.data.ConversationListData.ConversationListDataListener;
-import com.android.messaging.datamodel.data.ConversationListItemData;
-import com.android.messaging.ui.BugleAnimationTags;
-import com.android.messaging.ui.ListEmptyView;
-import com.android.messaging.ui.SnackBarInteraction;
-import com.android.messaging.ui.UIIntents;
-import com.android.messaging.util.AccessibilityUtil;
-import com.android.messaging.util.Assert;
-import com.android.messaging.util.ImeUtil;
-import com.android.messaging.util.LogUtil;
-import com.android.messaging.util.UiUtils;
-import com.google.common.annotations.VisibleForTesting;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Shows a list of conversations.
- */
-public class ConversationListFragment extends Fragment implements ConversationListDataListener,
- ConversationListItemView.HostInterface {
- private static final String BUNDLE_ARCHIVED_MODE = "archived_mode";
- private static final String BUNDLE_FORWARD_MESSAGE_MODE = "forward_message_mode";
- private static final boolean VERBOSE = false;
-
- private MenuItem mShowBlockedMenuItem;
- private boolean mArchiveMode;
- private boolean mBlockedAvailable;
- private boolean mForwardMessageMode;
-
- public interface ConversationListFragmentHost {
- public void onConversationClick(final ConversationListData listData,
- final ConversationListItemData conversationListItemData,
- final boolean isLongClick,
- final ConversationListItemView conversationView);
- public void onCreateConversationClick();
- public boolean isConversationSelected(final String conversationId);
- public boolean isSwipeAnimatable();
- public boolean isSelectionMode();
- public boolean hasWindowFocus();
- }
-
- private ConversationListFragmentHost mHost;
- private RecyclerView mRecyclerView;
- private ImageView mStartNewConversationButton;
- private ListEmptyView mEmptyListMessageView;
- private ConversationListAdapter mAdapter;
-
- // Saved Instance State Data - only for temporal data which is nice to maintain but not
- // critical for correctness.
- private static final String SAVED_INSTANCE_STATE_LIST_VIEW_STATE_KEY =
- "conversationListViewState";
- private Parcelable mListState;
-
- @VisibleForTesting
- final Binding<ConversationListData> mListBinding = BindingBase.createBinding(this);
-
- public static ConversationListFragment createArchivedConversationListFragment() {
- return createConversationListFragment(BUNDLE_ARCHIVED_MODE);
- }
-
- public static ConversationListFragment createForwardMessageConversationListFragment() {
- return createConversationListFragment(BUNDLE_FORWARD_MESSAGE_MODE);
- }
-
- public static ConversationListFragment createConversationListFragment(String modeKeyName) {
- final ConversationListFragment fragment = new ConversationListFragment();
- final Bundle bundle = new Bundle();
- bundle.putBoolean(modeKeyName, true);
- fragment.setArguments(bundle);
- return fragment;
- }
-
- /**
- * {@inheritDoc} from Fragment
- */
- @Override
- public void onCreate(final Bundle bundle) {
- super.onCreate(bundle);
- mListBinding.getData().init(getLoaderManager(), mListBinding);
- mAdapter = new ConversationListAdapter(getActivity(), null, this);
- }
-
- @Override
- public void onResume() {
- super.onResume();
-
- Assert.notNull(mHost);
- setScrolledToNewestConversationIfNeeded();
-
- updateUi();
- }
-
- public void setScrolledToNewestConversationIfNeeded() {
- if (!mArchiveMode
- && !mForwardMessageMode
- && isScrolledToFirstConversation()
- && mHost.hasWindowFocus()) {
- mListBinding.getData().setScrolledToNewestConversation(true);
- }
- }
-
- private boolean isScrolledToFirstConversation() {
- int firstItemPosition = ((LinearLayoutManager) mRecyclerView.getLayoutManager())
- .findFirstCompletelyVisibleItemPosition();
- return firstItemPosition == 0;
- }
-
- /**
- * {@inheritDoc} from Fragment
- */
- @Override
- public void onDestroy() {
- super.onDestroy();
- mListBinding.unbind();
- mHost = null;
- }
-
- /**
- * {@inheritDoc} from Fragment
- */
- @Override
- public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
- final Bundle savedInstanceState) {
- final ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.conversation_list_fragment,
- container, false);
- mRecyclerView = (RecyclerView) rootView.findViewById(android.R.id.list);
- mEmptyListMessageView = (ListEmptyView) rootView.findViewById(R.id.no_conversations_view);
- mEmptyListMessageView.setImageHint(R.drawable.ic_oobe_conv_list);
- // The default behavior for default layout param generation by LinearLayoutManager is to
- // provide width and height of WRAP_CONTENT, but this is not desirable for
- // ConversationListFragment; the view in each row should be a width of MATCH_PARENT so that
- // the entire row is tappable.
- final Activity activity = getActivity();
- final LinearLayoutManager manager = new LinearLayoutManager(activity) {
- @Override
- public RecyclerView.LayoutParams generateDefaultLayoutParams() {
- return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- }
- };
- mRecyclerView.setLayoutManager(manager);
- mRecyclerView.setHasFixedSize(true);
- mRecyclerView.setAdapter(mAdapter);
- mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
- int mCurrentState = AbsListView.OnScrollListener.SCROLL_STATE_IDLE;
-
- @Override
- public void onScrolled(final RecyclerView recyclerView, final int dx, final int dy) {
- if (mCurrentState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL
- || mCurrentState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
- ImeUtil.get().hideImeKeyboard(getActivity(), mRecyclerView);
- }
-
- if (isScrolledToFirstConversation()) {
- setScrolledToNewestConversationIfNeeded();
- } else {
- mListBinding.getData().setScrolledToNewestConversation(false);
- }
- }
-
- @Override
- public void onScrollStateChanged(final RecyclerView recyclerView, final int newState) {
- mCurrentState = newState;
- }
- });
- mRecyclerView.addOnItemTouchListener(new ConversationListSwipeHelper(mRecyclerView));
-
- if (savedInstanceState != null) {
- mListState = savedInstanceState.getParcelable(SAVED_INSTANCE_STATE_LIST_VIEW_STATE_KEY);
- }
-
- mStartNewConversationButton = (ImageView) rootView.findViewById(
- R.id.start_new_conversation_button);
- if (mArchiveMode) {
- mStartNewConversationButton.setVisibility(View.GONE);
- } else {
- mStartNewConversationButton.setVisibility(View.VISIBLE);
- mStartNewConversationButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(final View clickView) {
- mHost.onCreateConversationClick();
- }
- });
- }
- ViewCompat.setTransitionName(mStartNewConversationButton, BugleAnimationTags.TAG_FABICON);
-
- // The root view has a non-null background, which by default is deemed by the framework
- // to be a "transition group," where all child views are animated together during an
- // activity transition. However, we want each individual items in the recycler view to
- // show explode animation themselves, so we explicitly tag the root view to be a non-group.
- ViewGroupCompat.setTransitionGroup(rootView, false);
-
- setHasOptionsMenu(true);
- return rootView;
- }
-
- @Override
- public void onAttach(final Activity activity) {
- super.onAttach(activity);
- if (VERBOSE) {
- LogUtil.v(LogUtil.BUGLE_TAG, "Attaching List");
- }
- final Bundle arguments = getArguments();
- if (arguments != null) {
- mArchiveMode = arguments.getBoolean(BUNDLE_ARCHIVED_MODE, false);
- mForwardMessageMode = arguments.getBoolean(BUNDLE_FORWARD_MESSAGE_MODE, false);
- }
- mListBinding.bind(DataModel.get().createConversationListData(activity, this, mArchiveMode));
- }
-
-
- @Override
- public void onSaveInstanceState(final Bundle outState) {
- super.onSaveInstanceState(outState);
- if (mListState != null) {
- outState.putParcelable(SAVED_INSTANCE_STATE_LIST_VIEW_STATE_KEY, mListState);
- }
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mListState = mRecyclerView.getLayoutManager().onSaveInstanceState();
- mListBinding.getData().setScrolledToNewestConversation(false);
- }
-
- /**
- * Call this immediately after attaching the fragment
- */
- public void setHost(final ConversationListFragmentHost host) {
- Assert.isNull(mHost);
- mHost = host;
- }
-
- @Override
- public void onConversationListCursorUpdated(final ConversationListData data,
- final Cursor cursor) {
- mListBinding.ensureBound(data);
- final Cursor oldCursor = mAdapter.swapCursor(cursor);
- updateEmptyListUi(cursor == null || cursor.getCount() == 0);
- if (mListState != null && cursor != null && oldCursor == null) {
- mRecyclerView.getLayoutManager().onRestoreInstanceState(mListState);
- }
- }
-
- @Override
- public void setBlockedParticipantsAvailable(final boolean blockedAvailable) {
- mBlockedAvailable = blockedAvailable;
- if (mShowBlockedMenuItem != null) {
- mShowBlockedMenuItem.setVisible(blockedAvailable);
- }
- }
-
- public void updateUi() {
- mAdapter.notifyDataSetChanged();
- }
-
- @Override
- public void onPrepareOptionsMenu(final Menu menu) {
- super.onPrepareOptionsMenu(menu);
- final MenuItem startNewConversationMenuItem =
- menu.findItem(R.id.action_start_new_conversation);
- if (startNewConversationMenuItem != null) {
- // It is recommended for the Floating Action button functionality to be duplicated as a
- // menu
- AccessibilityManager accessibilityManager = (AccessibilityManager)
- getActivity().getSystemService(Context.ACCESSIBILITY_SERVICE);
- startNewConversationMenuItem.setVisible(accessibilityManager
- .isTouchExplorationEnabled());
- }
-
- final MenuItem archive = menu.findItem(R.id.action_show_archived);
- if (archive != null) {
- archive.setVisible(true);
- }
- }
-
- @Override
- public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
- if (!isAdded()) {
- // Guard against being called before we're added to the activity
- return;
- }
-
- mShowBlockedMenuItem = menu.findItem(R.id.action_show_blocked_contacts);
- if (mShowBlockedMenuItem != null) {
- mShowBlockedMenuItem.setVisible(mBlockedAvailable);
- }
- }
-
- /**
- * {@inheritDoc} from ConversationListItemView.HostInterface
- */
- @Override
- public void onConversationClicked(final ConversationListItemData conversationListItemData,
- final boolean isLongClick, final ConversationListItemView conversationView) {
- final ConversationListData listData = mListBinding.getData();
- mHost.onConversationClick(listData, conversationListItemData, isLongClick,
- conversationView);
- }
-
- /**
- * {@inheritDoc} from ConversationListItemView.HostInterface
- */
- @Override
- public boolean isConversationSelected(final String conversationId) {
- return mHost.isConversationSelected(conversationId);
- }
-
- @Override
- public boolean isSwipeAnimatable() {
- return mHost.isSwipeAnimatable();
- }
-
- // Show and hide empty list UI as needed with appropriate text based on view specifics
- private void updateEmptyListUi(final boolean isEmpty) {
- if (isEmpty) {
- int emptyListText;
- if (!mListBinding.getData().getHasFirstSyncCompleted()) {
- emptyListText = R.string.conversation_list_first_sync_text;
- } else if (mArchiveMode) {
- emptyListText = R.string.archived_conversation_list_empty_text;
- } else {
- emptyListText = R.string.conversation_list_empty_text;
- }
- mEmptyListMessageView.setTextHint(emptyListText);
- mEmptyListMessageView.setVisibility(View.VISIBLE);
- mEmptyListMessageView.setIsImageVisible(true);
- mEmptyListMessageView.setIsVerticallyCentered(true);
- } else {
- mEmptyListMessageView.setVisibility(View.GONE);
- }
- }
-
- @Override
- public List<SnackBarInteraction> getSnackBarInteractions() {
- final List<SnackBarInteraction> interactions = new ArrayList<SnackBarInteraction>(1);
- final SnackBarInteraction fabInteraction =
- new SnackBarInteraction.BasicSnackBarInteraction(mStartNewConversationButton);
- interactions.add(fabInteraction);
- return interactions;
- }
-
- private ViewPropertyAnimator getNormalizedFabAnimator() {
- return mStartNewConversationButton.animate()
- .setInterpolator(UiUtils.DEFAULT_INTERPOLATOR)
- .setDuration(getActivity().getResources().getInteger(
- R.integer.fab_animation_duration_ms));
- }
-
- public ViewPropertyAnimator dismissFab() {
- // To prevent clicking while animating.
- mStartNewConversationButton.setEnabled(false);
- final MarginLayoutParams lp =
- (MarginLayoutParams) mStartNewConversationButton.getLayoutParams();
- final float fabWidthWithLeftRightMargin = mStartNewConversationButton.getWidth()
- + lp.leftMargin + lp.rightMargin;
- final int direction = AccessibilityUtil.isLayoutRtl(mStartNewConversationButton) ? -1 : 1;
- return getNormalizedFabAnimator().translationX(direction * fabWidthWithLeftRightMargin);
- }
-
- public ViewPropertyAnimator showFab() {
- return getNormalizedFabAnimator().translationX(0).withEndAction(new Runnable() {
- @Override
- public void run() {
- // Re-enable clicks after the animation.
- mStartNewConversationButton.setEnabled(true);
- }
- });
- }
-
- public View getHeroElementForTransition() {
- return mArchiveMode ? null : mStartNewConversationButton;
- }
-
- @VisibleForAnimation
- public RecyclerView getRecyclerView() {
- return mRecyclerView;
- }
-
- @Override
- public void startFullScreenPhotoViewer(
- final Uri initialPhoto, final Rect initialPhotoBounds, final Uri photosUri) {
- UIIntents.get().launchFullScreenPhotoViewer(
- getActivity(), initialPhoto, initialPhotoBounds, photosUri);
- }
-
- @Override
- public void startFullScreenVideoViewer(final Uri videoUri) {
- UIIntents.get().launchFullScreenVideoViewer(getActivity(), videoUri);
- }
-
- @Override
- public boolean isSelectionMode() {
- return mHost != null && mHost.isSelectionMode();
- }
-}