LargeTemplateView.java revision 63fb9955b209f1bb9d19e41df9784bfbdf63defe
1/*
2 * Copyright 2017 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
17package androidx.slice.widget;
18
19import android.content.Context;
20import android.util.AttributeSet;
21
22import androidx.annotation.RestrictTo;
23import androidx.recyclerview.widget.LinearLayoutManager;
24import androidx.recyclerview.widget.RecyclerView;
25import androidx.slice.Slice;
26import androidx.slice.SliceItem;
27
28import java.util.ArrayList;
29import java.util.List;
30
31/**
32 * @hide
33 */
34@RestrictTo(RestrictTo.Scope.LIBRARY)
35public class LargeTemplateView extends SliceChildView {
36
37    private final LargeSliceAdapter mAdapter;
38    private final RecyclerView mRecyclerView;
39    private Slice mSlice;
40    private boolean mIsScrollable;
41    private ListContent mListContent;
42    private List<SliceItem> mDisplayedItems = new ArrayList<>();
43    private int mDisplayedItemsHeight = 0;
44
45    public LargeTemplateView(Context context) {
46        super(context);
47        mRecyclerView = new RecyclerView(getContext());
48        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
49        mAdapter = new LargeSliceAdapter(context);
50        mRecyclerView.setAdapter(mAdapter);
51        addView(mRecyclerView);
52    }
53
54    @Override
55    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
56        int height = MeasureSpec.getSize(heightMeasureSpec);
57        if (mDisplayedItems.size() > 0 && mDisplayedItemsHeight > height) {
58            // Need to resize
59            updateDisplayedItems(height);
60        }
61        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
62    }
63
64    @Override
65    public int getActualHeight() {
66        return mDisplayedItemsHeight;
67    }
68
69    @Override
70    public void setTint(int tint) {
71        super.setTint(tint);
72        populate();
73    }
74
75    @Override
76    public @SliceView.SliceMode int getMode() {
77        return SliceView.MODE_LARGE;
78    }
79
80    @Override
81    public void setSliceActionListener(SliceView.OnSliceActionListener observer) {
82        mObserver = observer;
83        if (mAdapter != null) {
84            mAdapter.setSliceObserver(mObserver);
85        }
86    }
87
88    @Override
89    public void setSliceActions(List<SliceItem> actions) {
90        mAdapter.setSliceActions(actions);
91    }
92
93    @Override
94    public void setSlice(Slice slice) {
95        mSlice = slice;
96        populate();
97    }
98
99    @Override
100    public void setStyle(AttributeSet attrs) {
101        super.setStyle(attrs);
102        mAdapter.setStyle(attrs);
103    }
104
105    @Override
106    public void setShowLastUpdated(boolean showLastUpdated) {
107        super.setShowLastUpdated(showLastUpdated);
108        mAdapter.setShowLastUpdated(showLastUpdated);
109    }
110
111    @Override
112    public void setLastUpdated(long lastUpdated) {
113        super.setLastUpdated(lastUpdated);
114        mAdapter.setLastUpdated(lastUpdated);
115    }
116
117    private void populate() {
118        if (mSlice == null) {
119            resetView();
120            return;
121        }
122        mListContent = new ListContent(getContext(), mSlice);
123        updateDisplayedItems(getMeasuredHeight());
124    }
125
126    /**
127     * Whether or not the content in this template should be scrollable.
128     */
129    public void setScrollable(boolean isScrollable) {
130        mIsScrollable = isScrollable;
131        updateDisplayedItems(getMeasuredHeight());
132    }
133
134    private void updateDisplayedItems(int height) {
135        if (mListContent == null) {
136            return;
137        }
138        if (!mIsScrollable) {
139            // If we're not scrollable we must cap the number of items we're displaying such
140            // that they fit in the available space
141            if (height == 0) {
142                // Not measured, use default
143                mDisplayedItems = mListContent.getItemsForNonScrollingList(-1);
144            } else {
145                mDisplayedItems = mListContent.getItemsForNonScrollingList(height);
146            }
147        } else {
148            mDisplayedItems = mListContent.getRowItems();
149        }
150        mDisplayedItemsHeight = ListContent.getListHeight(getContext(), mDisplayedItems);
151        mAdapter.setSliceItems(mDisplayedItems, mTintColor);
152    }
153
154    @Override
155    public void resetView() {
156        mSlice = null;
157        mDisplayedItemsHeight = 0;
158        mDisplayedItems.clear();
159        mAdapter.setSliceItems(null, -1);
160        mListContent = null;
161    }
162}
163