1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.car.carlauncher.pagination; 18 19 import android.view.View; 20 import android.view.ViewTreeObserver.OnGlobalLayoutListener; 21 22 import com.android.car.carlauncher.pagination.PageMeasurementHelper.GridDimensions; 23 import com.android.car.carlauncher.pagination.PageMeasurementHelper.PageDimensions; 24 25 import java.util.HashSet; 26 import java.util.Iterator; 27 import java.util.Set; 28 29 /** 30 * Controller class that handling all pagination related logic. 31 */ 32 public class PaginationController { 33 private final PageMeasurementHelper mPageMeasurementHelper; 34 private final DimensionUpdateCallback mCallback; 35 PaginationController(View windowBackground, DimensionUpdateCallback callback)36 public PaginationController(View windowBackground, DimensionUpdateCallback callback) { 37 mCallback = callback; 38 mPageMeasurementHelper = new PageMeasurementHelper(windowBackground); 39 windowBackground.getViewTreeObserver().addOnGlobalLayoutListener( 40 new OnGlobalLayoutListener() { 41 @Override 42 public void onGlobalLayout() { 43 int windowHeight = windowBackground.getMeasuredHeight(); 44 int windowWidth = windowBackground.getMeasuredWidth(); 45 maybeHandleWindowResize(windowWidth, windowHeight); 46 } 47 }); 48 } 49 maybeHandleWindowResize(int windowWidth, int windowHeight)50 private void maybeHandleWindowResize(int windowWidth, int windowHeight) { 51 boolean consumed = mPageMeasurementHelper.handleWindowSizeChange(windowWidth, windowHeight); 52 if (consumed) { 53 mCallback.notifyDimensionsUpdated(mPageMeasurementHelper.getPageDimensions(), 54 mPageMeasurementHelper.getGridDimensions()); 55 } 56 } 57 58 /** 59 * Callback contract between this controller and its {@link DimensionUpdateListener} classes. 60 * 61 * When {@link PageMeasurementHelper#handleWindowSizeChange} returns {@code true}, the callback 62 * will notify its listeners that the window size has changed. 63 */ 64 public static class DimensionUpdateCallback { 65 Set<DimensionUpdateListener> mListeners = new HashSet<>(); 66 67 /** 68 * Adds an {@link DimensionUpdateListener} to 69 */ addListener(DimensionUpdateListener listener)70 public void addListener(DimensionUpdateListener listener) { 71 mListeners.add(listener); 72 } 73 74 /** 75 * Updates all listeners with the new measured dimensions. 76 */ notifyDimensionsUpdated(PageDimensions pageDimens, GridDimensions gridDimens)77 public void notifyDimensionsUpdated(PageDimensions pageDimens, GridDimensions gridDimens) { 78 Iterator<DimensionUpdateListener> iterator = mListeners.iterator(); 79 while (iterator.hasNext()) { 80 if (iterator.next().onDimensionsUpdated(pageDimens, gridDimens)) { 81 iterator.remove(); 82 } 83 } 84 } 85 } 86 87 /** 88 * Listener interface for {@link DimensionUpdateCallback}. 89 * 90 * Classes that implement the listener should use the measured dimensions from 91 * {@link DimensionUpdateListener#onDimensionsUpdated} to update relevant layout params. 92 */ 93 public interface DimensionUpdateListener { 94 /** 95 * Updates layout params from the updated dimensions measurements in {@link PageDimensions} 96 * and {@link GridDimensions} 97 * 98 * @return true if this listener should be removed after the first invocation, 99 * indicating it's designed for a single execution. 100 */ onDimensionsUpdated(PageDimensions pageDimens, GridDimensions gridDimens)101 boolean onDimensionsUpdated(PageDimensions pageDimens, GridDimensions gridDimens); 102 } 103 } 104