• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.dialer.ui.common;
18 
19 import android.os.Bundle;
20 import android.view.LayoutInflater;
21 import android.view.View;
22 import android.view.ViewGroup;
23 
24 import androidx.annotation.DrawableRes;
25 import androidx.annotation.LayoutRes;
26 import androidx.annotation.NonNull;
27 import androidx.annotation.StringRes;
28 import androidx.recyclerview.widget.LinearLayoutManager;
29 import androidx.recyclerview.widget.RecyclerView;
30 
31 import com.android.car.dialer.R;
32 import com.android.car.dialer.widget.LoadingFrameLayout;
33 import com.android.car.ui.FocusArea;
34 import com.android.car.ui.baselayout.Insets;
35 import com.android.car.ui.recyclerview.CarUiRecyclerView;
36 import com.android.car.ui.recyclerview.ContentLimiting;
37 import com.android.car.uxr.LifeCycleObserverUxrContentLimiter;
38 import com.android.car.uxr.UxrContentLimiter;
39 import com.android.car.uxr.UxrContentLimiterImpl;
40 
41 /**
42  * Base fragment that inflates a {@link RecyclerView}. It handles the top offset for first row item
43  * so the list can scroll underneath the top bar.
44  *
45  * <p>It also provides a {@link UxrContentLimiter} to children classes so they can "register" their
46  * associated {@link RecyclerView.Adapter} objects to listen to changes to
47  * {@link android.car.drivingstate.CarUxRestrictions}.
48  */
49 public class DialerListBaseFragment extends DialerBaseFragment {
50 
51     private LoadingFrameLayout mLoadingFrameLayout;
52     private CarUiRecyclerView mRecyclerView;
53     private FocusArea mFocusArea;
54     private LifeCycleObserverUxrContentLimiter mUxrContentLimiter;
55 
56     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)57     public View onCreateView(LayoutInflater inflater, ViewGroup container,
58             Bundle savedInstanceState) {
59         View view = inflater.inflate(getLayoutResource(), container, false);
60         mLoadingFrameLayout = view.findViewById(R.id.loading_frame_layout);
61         mRecyclerView = view.requireViewById(R.id.list_view);
62         mRecyclerView.setLayoutManager(createLayoutManager());
63         mFocusArea = view.requireViewById(R.id.loading_focus_area);
64         mUxrContentLimiter = new LifeCycleObserverUxrContentLimiter(
65                 new UxrContentLimiterImpl(getContext(), R.xml.uxr_config));
66         getLifecycle().addObserver(mUxrContentLimiter);
67         return view;
68     }
69 
70     /**
71      * Returns the {@link UxrContentLimiter} instance in use by this class.
72      *
73      * <p>Together with {@link UxrContentLimiter#setAdapter(ContentLimiting)}, this can be used to
74      * "register" compatible {@link RecyclerView.Adapter} object to listen to changes to
75      * {@link android.car.drivingstate.CarUxRestrictions}.
76      */
getUxrContentLimiter()77     protected UxrContentLimiter getUxrContentLimiter() {
78         return mUxrContentLimiter;
79     }
80 
81     /**
82      * Layout resource for this fragment. It must contains a RecyclerView with id list_view.
83      */
84     @LayoutRes
getLayoutResource()85     protected int getLayoutResource() {
86         return R.layout.loading_list_fragment;
87     }
88 
89     /**
90      * Creates the layout manager for the recycler view. Default is a {@link LinearLayoutManager}.
91      * Child inheriting from this fragment can override to create a different layout manager.
92      */
93     @NonNull
createLayoutManager()94     protected RecyclerView.LayoutManager createLayoutManager() {
95         return new LinearLayoutManager(getContext());
96     }
97 
98     /**
99      * Returns the {@link RecyclerView} instance.
100      */
101     @NonNull
getRecyclerView()102     protected CarUiRecyclerView getRecyclerView() {
103         return mRecyclerView;
104     }
105 
106     /**
107      * Shows loading spinner when the data is still loading.
108      */
showLoading()109     protected void showLoading() {
110         mLoadingFrameLayout.showLoading();
111     }
112 
113     /**
114      * Shows content when data is loaded and the content is not empty.
115      */
showContent()116     protected void showContent() {
117         mLoadingFrameLayout.showContent();
118     }
119 
120     /**
121      * Shows the empty view with icon, message and secondary message.
122      */
showEmpty(@rawableRes int iconResId, @StringRes int messageResId, @StringRes int secondaryMessageResId)123     protected void showEmpty(@DrawableRes int iconResId, @StringRes int messageResId,
124             @StringRes int secondaryMessageResId) {
125         mLoadingFrameLayout.showEmpty(iconResId, messageResId, secondaryMessageResId);
126     }
127 
128     /**
129      * Shows the empty view with icon, message, secondary message and action button.
130      */
showEmpty(@rawableRes int iconResId, @StringRes int messageResId, @StringRes int secondaryMessageResId, @StringRes int actionButtonTextResId, View.OnClickListener actionButtonOnClickListener, boolean showActionButton)131     protected void showEmpty(@DrawableRes int iconResId, @StringRes int messageResId,
132             @StringRes int secondaryMessageResId,
133             @StringRes int actionButtonTextResId, View.OnClickListener actionButtonOnClickListener,
134             boolean showActionButton) {
135         mLoadingFrameLayout.showEmpty(iconResId, messageResId, secondaryMessageResId,
136                 actionButtonTextResId, actionButtonOnClickListener, showActionButton);
137     }
138 
139     @Override
onCarUiInsetsChanged(Insets insets)140     public void onCarUiInsetsChanged(Insets insets) {
141         int listTopPadding = requireContext().getResources().getDimensionPixelSize(
142                 R.dimen.list_top_padding);
143         mRecyclerView.setPadding(0, insets.getTop() + listTopPadding, 0, insets.getBottom());
144         mFocusArea.setHighlightPadding(0, insets.getTop() + listTopPadding, 0, insets.getBottom());
145         mFocusArea.setBoundsOffset(0, insets.getTop() + listTopPadding, 0, insets.getBottom());
146         requireView().setPadding(insets.getLeft(), 0, insets.getRight(), 0);
147     }
148 
149     @Override
onDestroyView()150     public void onDestroyView() {
151         super.onDestroyView();
152         mRecyclerView.setAdapter(null);
153         mRecyclerView.setLayoutManager(null);
154         mRecyclerView = null;
155     }
156 }
157