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.favorite;
18 
19 import android.content.Context;
20 import android.content.res.Resources;
21 import android.graphics.Rect;
22 import android.os.Bundle;
23 import android.view.View;
24 
25 import androidx.annotation.NonNull;
26 import androidx.annotation.Nullable;
27 import androidx.lifecycle.ViewModelProviders;
28 import androidx.recyclerview.widget.GridLayoutManager;
29 import androidx.recyclerview.widget.RecyclerView;
30 
31 import com.android.car.dialer.Constants;
32 import com.android.car.dialer.R;
33 import com.android.car.dialer.telecom.UiCallManager;
34 import com.android.car.dialer.ui.common.DialerListBaseFragment;
35 import com.android.car.dialer.ui.common.DialerUtils;
36 import com.android.car.telephony.common.Contact;
37 
38 /**
39  * Contains a list of favorite contacts.
40  */
41 public class FavoriteFragment extends DialerListBaseFragment {
42     private FavoriteAdapter mFavoriteAdapter;
43 
44     /**
45      * Constructs a new {@link FavoriteFragment}
46      */
newInstance()47     public static FavoriteFragment newInstance() {
48         return new FavoriteFragment();
49     }
50 
51     @Override
onViewCreated(@onNull View view, @Nullable Bundle savedInstanceState)52     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
53         super.onViewCreated(view, savedInstanceState);
54         getRecyclerView().addItemDecoration(new ItemSpacingDecoration());
55         getRecyclerView().setItemAnimator(null);
56 
57         mFavoriteAdapter = new FavoriteAdapter();
58         mFavoriteAdapter.setOnAddFavoriteClickedListener(this::onAddFavoriteClicked);
59 
60         FavoriteViewModel favoriteViewModel = ViewModelProviders.of(getActivity()).get(
61                 FavoriteViewModel.class);
62         mFavoriteAdapter.setOnListItemClickedListener(this::onItemClicked);
63         favoriteViewModel.getFavoriteContacts().observe(this, contacts -> {
64             if (contacts.isLoading()) {
65                 showLoading();
66             } else if (contacts.getData() == null) {
67                 showEmpty(Constants.INVALID_RES_ID, R.string.favorites_empty,
68                         R.string.no_favorites_added, R.string.add_favorite_button,
69                         v -> onAddFavoriteClicked(), true);
70             } else {
71                 mFavoriteAdapter.setFavoriteContacts(contacts.getData());
72                 showContent();
73             }
74         });
75 
76         getRecyclerView().setAdapter(mFavoriteAdapter);
77     }
78 
79     @NonNull
80     @Override
createLayoutManager()81     protected RecyclerView.LayoutManager createLayoutManager() {
82         return new FavoriteLayoutManager(getContext());
83     }
84 
onItemClicked(Contact contact)85     private void onItemClicked(Contact contact) {
86         DialerUtils.promptForPrimaryNumber(getContext(), contact, (phoneNumber, always) ->
87                 UiCallManager.get().placeCall(phoneNumber.getRawNumber()));
88     }
89 
onAddFavoriteClicked()90     private void onAddFavoriteClicked() {
91         pushContentFragment(AddFavoriteFragment.newInstance(), null);
92     }
93 
94     private class ItemSpacingDecoration extends RecyclerView.ItemDecoration {
95 
96         @Override
getItemOffsets(@onNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state)97         public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
98                 @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
99             super.getItemOffsets(outRect, view, parent, state);
100             Resources resources = FavoriteFragment.this.getContext().getResources();
101             int numColumns = resources.getInteger(R.integer.favorite_fragment_grid_column);
102             int leftPadding =
103                     resources.getDimensionPixelOffset(R.dimen.favorite_card_space_horizontal);
104             int verticalPadding =
105                     resources.getDimensionPixelOffset(R.dimen.favorite_card_space_vertical);
106 
107             if (parent.getChildAdapterPosition(view) % numColumns == 0) {
108                 leftPadding = 0;
109             }
110 
111             outRect.set(leftPadding, verticalPadding, 0, verticalPadding);
112         }
113     }
114 
115     private class FavoriteLayoutManager extends GridLayoutManager {
FavoriteLayoutManager(Context context)116         private FavoriteLayoutManager(Context context) {
117             super(context,
118                     context.getResources().getInteger(R.integer.favorite_fragment_grid_column));
119             SpanSizeLookup spanSizeLookup = new SpanSizeLookup() {
120                 @Override
121                 public int getSpanSize(int position) {
122                     if (mFavoriteAdapter.getItemViewType(position) == FavoriteAdapter.TYPE_HEADER) {
123                         return getSpanCount();
124                     }
125                     return 1;
126                 }
127             };
128             setSpanSizeLookup(spanSizeLookup);
129         }
130     }
131 }
132