/* * Copyright 2015 Google Inc. All rights reserved. * * 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.google.samples.apps.iosched.map; import com.google.samples.apps.iosched.R; import android.content.res.Resources; import android.database.Cursor; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.design.widget.BottomSheetBehavior; import android.support.design.widget.CoordinatorLayout; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; /** * Map info fragment that uses a {@link com.sothree.slidinguppanel.SlidingUpPanelLayout} to display * its contents. * It is designed to be displayed at the bottom of the screen and handles resizing, scrolling and * expanding of content itself. * Minimised panel heights need to be predefined (see * <code>@dimen/map_slideableinfo_height_titleonly</code>) and are automatically applied depending * on its state. */ public class SlideableInfoFragment extends MapInfoFragment { private View mBottomSheet; private CoordinatorLayout mCoordinator; private BottomSheetBehavior mBehavior; private int mHeightTitleOnly; private int mHeightVenue; private int mHeightSession; /** * Progress of panel sliding after which the padding returned through the #Callback is fixed * at 0. Below this factor it returns the actual height of the bottom panel. */ public static final float MAX_PANEL_PADDING_FACTOR = 0.6f; protected static SlideableInfoFragment newInstance() { return new SlideableInfoFragment(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Load heights final Resources resources = getResources(); mHeightTitleOnly = resources .getDimensionPixelOffset(R.dimen.map_slideableinfo_height_titleonly); mHeightVenue = resources .getDimensionPixelOffset(R.dimen.map_slideableinfo_height_venue); mHeightSession = resources .getDimensionPixelOffset(R.dimen.map_slideableinfo_height_session); } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return super.onCreateView(inflater, container, savedInstanceState, R.layout.map_info_bottom); } @Override public void onViewCreated(final View view, final Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); mCoordinator = (CoordinatorLayout) view.findViewById(R.id.map_coordinator); mBottomSheet = mCoordinator.findViewById(R.id.map_bottomsheet); mBehavior = BottomSheetBehavior.from(mBottomSheet); mBehavior.setBottomSheetCallback(mBottomSheetCallback); } @Override public void showTitleOnly(int roomType, String title) { super.showTitleOnly(roomType, title); setCollapsedOnly(); } @Override protected void onSessionListLoading(String roomId, String roomTitle) { // Update the title and hide the list if displayed. // We don't want to uneccessarily resize the panel. mTitle.setText(roomTitle); mList.setVisibility(mList.getVisibility() == View.VISIBLE ? View.INVISIBLE : View.GONE); } private void setCollapsedOnly() { // Set up panel: collapsed only with title height and icon mBehavior.setPeekHeight(mHeightTitleOnly); mBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); } @Override public void showVenue() { // Set up panel: collapsed with venue height mBehavior.setPeekHeight(mHeightVenue); mBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); super.showVenue(); } @Override protected void onSessionLoadingFailed(String roomTitle, int roomType) { // Do not display the list but permanently hide it super.onSessionLoadingFailed(roomTitle, roomType); setCollapsedOnly(); } @Override protected void onSessionsLoaded(String roomTitle, int roomType, Cursor cursor) { super.onSessionsLoaded(roomTitle, roomType, cursor); // Set up panel: expandable with session height mBehavior.setPeekHeight(mHeightSession); mBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); } @Override protected void onRoomSubtitleLoaded(String roomTitle, int roomType, String subTitle) { super.onRoomSubtitleLoaded(roomTitle, roomType, subTitle); // Set up panel: Same height as venue, but collapsible mBehavior.setPeekHeight(mHeightVenue); mBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); } @Override public void hide() { mBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); } @Override public boolean isExpanded() { return mBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED; } @Override public void minimize() { mBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); } private BottomSheetBehavior.BottomSheetCallback mBottomSheetCallback = new BottomSheetBehavior.BottomSheetCallback() { @Override public void onStateChanged(@NonNull final View bottomSheet, final int newState) { switch (newState) { case BottomSheetBehavior.STATE_COLLAPSED: mList.setScrollContainer(false); mList.setEnabled(false); mList.getLayoutManager().scrollToPosition(0); mCoordinator.requestLayout(); break; case BottomSheetBehavior.STATE_EXPANDED: mList.setScrollContainer(true); mList.setEnabled(true); break; case BottomSheetBehavior.STATE_HIDDEN: mCallback.onInfoSizeChanged(mBottomSheet.getLeft(), mBottomSheet.getTop(), mBottomSheet.getRight(), mCoordinator.getHeight()); break; } } @Override public void onSlide(@NonNull final View bottomSheet, final float slideOffset) { mCallback.onInfoSizeChanged(mBottomSheet.getLeft(), mBottomSheet.getTop(), mBottomSheet.getRight(), mCoordinator.getHeight()); } }; }