to top
BatchStepSensor / src / com.example.android.batchstepsensor /

CardStreamFragment.java

1
/*
2
* Copyright 2013 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
 
18
 
19
 
20
package com.example.android.batchstepsensor;
21
 
22
import android.os.Bundle;
23
import android.support.v4.app.Fragment;
24
import android.view.LayoutInflater;
25
import android.view.View;
26
import android.view.ViewGroup;
27
 
28
import java.util.Collection;
29
import java.util.HashMap;
30
import java.util.HashSet;
31
import java.util.LinkedHashMap;
32
 
33
 
34
/**
35
 * A Fragment that handles a stream of cards.
36
 * Cards can be shown or hidden. When a card is shown it can also be marked as not-dismissible, see
37
 * {@link CardStreamLinearLayout#addCard(android.view.View, boolean)}.
38
 */
39
public class CardStreamFragment extends Fragment {
40
 
41
    private static final int INITIAL_SIZE = 15;
42
    private CardStreamLinearLayout mLayout = null;
43
    private LinkedHashMap<String, Card> mVisibleCards = new LinkedHashMap<String, Card>(INITIAL_SIZE);
44
    private HashMap<String, Card> mHiddenCards = new HashMap<String, Card>(INITIAL_SIZE);
45
    private HashSet<String> mDismissibleCards = new HashSet<String>(INITIAL_SIZE);
46
 
47
    // Set the listener to handle dismissed cards by moving them to the hidden cards map.
48
    private CardStreamLinearLayout.OnDissmissListener mCardDismissListener =
49
            new CardStreamLinearLayout.OnDissmissListener() {
50
                @Override
51
                public void onDismiss(String tag) {
52
                    dismissCard(tag);
53
                }
54
            };
55
 
56
 
57
    @Override
58
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
59
                             Bundle savedInstanceState) {
60
 
61
        View view = inflater.inflate(R.layout.cardstream, container, false);
62
        mLayout = (CardStreamLinearLayout) view.findViewById(R.id.card_stream);
63
        mLayout.setOnDismissListener(mCardDismissListener);
64
 
65
        return view;
66
    }
67
 
68
    /**
69
     * Add a visible, dismissible card to the card stream.
70
     *
71
     * @param card
72
     */
73
    public void addCard(Card card) {
74
        final String tag = card.getTag();
75
 
76
        if (!mVisibleCards.containsKey(tag) && !mHiddenCards.containsKey(tag)) {
77
            final View view = card.getView();
78
            view.setTag(tag);
79
            mHiddenCards.put(tag, card);
80
        }
81
    }
82
 
83
    /**
84
     * Add and show a card.
85
     *
86
     * @param card
87
     * @param show
88
     */
89
    public void addCard(Card card, boolean show) {
90
        addCard(card);
91
        if (show) {
92
            showCard(card.getTag());
93
        }
94
    }
95
 
96
    /**
97
     * Remove a card and return true if it has been successfully removed.
98
     *
99
     * @param tag
100
     * @return
101
     */
102
    public boolean removeCard(String tag) {
103
        // Attempt to remove a visible card first
104
        Card card = mVisibleCards.get(tag);
105
        if (card != null) {
106
            // Card is visible, also remove from layout
107
            mVisibleCards.remove(tag);
108
            mLayout.removeView(card.getView());
109
            return true;
110
        } else {
111
            // Card is hidden, no need to remove from layout
112
            card = mHiddenCards.remove(tag);
113
            return card != null;
114
        }
115
    }
116
 
117
    /**
118
     * Show a dismissible card, returns false if the card could not be shown.
119
     *
120
     * @param tag
121
     * @return
122
     */
123
    public boolean showCard(String tag) {
124
        return showCard(tag, true);
125
    }
126
 
127
    /**
128
     * Show a card, returns false if the card could not be shown.
129
     *
130
     * @param tag
131
     * @param dismissible
132
     * @return
133
     */
134
    public boolean showCard(String tag, boolean dismissible) {
135
        final Card card = mHiddenCards.get(tag);
136
        // ensure the card is hidden and not already visible
137
        if (card != null && !mVisibleCards.containsValue(tag)) {
138
            mHiddenCards.remove(tag);
139
            mVisibleCards.put(tag, card);
140
            mLayout.addCard(card.getView(), dismissible);
141
            if (dismissible) {
142
                mDismissibleCards.add(tag);
143
            }
144
            return true;
145
        }
146
        return false;
147
    }
148
 
149
    /**
150
     * Hides the card, returns false if the card could not be hidden.
151
     *
152
     * @param tag
153
     * @return
154
     */
155
    public boolean hideCard(String tag) {
156
        final Card card = mVisibleCards.get(tag);
157
        if (card != null) {
158
            mVisibleCards.remove(tag);
159
            mDismissibleCards.remove(tag);
160
            mHiddenCards.put(tag, card);
161
 
162
            mLayout.removeView(card.getView());
163
            return true;
164
        }
165
        return mHiddenCards.containsValue(tag);
166
    }
167
 
168
 
169
    private void dismissCard(String tag) {
170
        final Card card = mVisibleCards.get(tag);
171
        if (card != null) {
172
            mDismissibleCards.remove(tag);
173
            mVisibleCards.remove(tag);
174
            mHiddenCards.put(tag, card);
175
        }
176
    }
177
 
178
 
179
    public boolean isCardVisible(String tag) {
180
        return mVisibleCards.containsValue(tag);
181
    }
182
 
183
    /**
184
     * Returns true if the card is shown and is dismissible.
185
     *
186
     * @param tag
187
     * @return
188
     */
189
    public boolean isCardDismissible(String tag) {
190
        return mDismissibleCards.contains(tag);
191
    }
192
 
193
    /**
194
     * Returns the Card for this tag.
195
     *
196
     * @param tag
197
     * @return
198
     */
199
    public Card getCard(String tag) {
200
        final Card card = mVisibleCards.get(tag);
201
        if (card != null) {
202
            return card;
203
        } else {
204
            return mHiddenCards.get(tag);
205
        }
206
    }
207
 
208
    /**
209
     * Moves the view port to show the card with this tag.
210
     *
211
     * @param tag
212
     * @see CardStreamLinearLayout#setFirstVisibleCard(String)
213
     */
214
    public void setFirstVisibleCard(String tag) {
215
        final Card card = mVisibleCards.get(tag);
216
        if (card != null) {
217
            mLayout.setFirstVisibleCard(tag);
218
        }
219
    }
220
 
221
    public int getVisibleCardCount() {
222
        return mVisibleCards.size();
223
    }
224
 
225
    public Collection<Card> getVisibleCards() {
226
        return mVisibleCards.values();
227
    }
228
 
229
    public void restoreState(CardStreamState state, OnCardClickListener callback) {
230
        // restore hidden cards
231
        for (Card c : state.hiddenCards) {
232
            Card card = new Card.Builder(callback,c).build(getActivity());
233
            mHiddenCards.put(card.getTag(), card);
234
        }
235
 
236
        // temporarily set up list of dismissible
237
        final HashSet<String> dismissibleCards = state.dismissibleCards;
238
 
239
        //restore shown cards
240
        for (Card c : state.visibleCards) {
241
            Card card = new Card.Builder(callback,c).build(getActivity());
242
            addCard(card);
243
            final String tag = card.getTag();
244
            showCard(tag, dismissibleCards.contains(tag));
245
        }
246
 
247
        // move to first visible card
248
        final String firstShown = state.shownTag;
249
        if (firstShown != null) {
250
            mLayout.setFirstVisibleCard(firstShown);
251
        }
252
 
253
        mLayout.triggerShowInitialAnimation();
254
    }
255
 
256
    public CardStreamState dumpState() {
257
        final Card[] visible = cloneCards(mVisibleCards.values());
258
        final Card[] hidden = cloneCards(mHiddenCards.values());
259
        final HashSet<String> dismissible = new HashSet<String>(mDismissibleCards);
260
        final String firstVisible = mLayout.getFirstVisibleCardTag();
261
 
262
        return new CardStreamState(visible, hidden, dismissible, firstVisible);
263
    }
264
 
265
    private Card[] cloneCards(Collection<Card> cards) {
266
        Card[] cardArray = new Card[cards.size()];
267
        int i = 0;
268
        for (Card c : cards) {
269
            cardArray[i++] = c.createShallowClone();
270
        }
271
 
272
        return cardArray;
273
    }
274
 
275
}