Please note that the contents of this offline web site may be out of date. To access the most recent documentation visit the online version .
Note that links that point to online resources are green in color and will open in a new window.
We would love it if you could give us feedback about this material by filling this form (You have to be online to fill it)
BatchStepSensor / src / com.example.android.batchstepsensor / cardstream /

Card.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.cardstream;
       
       
        21
       
       
       
       
        22
       
       
        import android.animation.Animator;
       
       
        23
       
       
        import android.animation.AnimatorListenerAdapter;
       
       
        24
       
       
        import android.animation.ObjectAnimator;
       
       
        25
       
       
        import android.app.Activity;
       
       
        26
       
       
        import android.graphics.Color;
       
       
        27
       
       
        import android.view.LayoutInflater;
       
       
        28
       
       
        import android.view.View;
       
       
        29
       
       
        import android.view.ViewGroup;
       
       
        30
       
       
        import android.widget.Button;
       
       
        31
       
       
        import android.widget.ProgressBar;
       
       
        32
       
       
        import android.widget.TextView;
       
       
        33
       
       
       
       
        34
       
       
        import com.example.android.batchstepsensor.R;
       
       
        35
       
       
       
       
        36
       
       
        import java.util.ArrayList;
       
       
        37
       
       
       
       
        38
       
       
        /**
       
       
        39
       
       
        * A Card contains a description and has a visual state. Optionally a card also contains a title,
       
       
        40
       
       
        * progress indicator and zero or more actions. It is constructed through the {@link Builder}.
       
       
        41
       
       
        */
       
       
        42
       
       
        public class Card {
       
       
        43
       
       
       
       
        44
       
       
        public static final int ACTION_POSITIVE = 1;
       
       
        45
       
       
        public static final int ACTION_NEGATIVE = 2;
       
       
        46
       
       
        public static final int ACTION_NEUTRAL = 3;
       
       
        47
       
       
       
       
        48
       
       
        public static final int PROGRESS_TYPE_NO_PROGRESS = 0;
       
       
        49
       
       
        public static final int PROGRESS_TYPE_NORMAL = 1;
       
       
        50
       
       
        public static final int PROGRESS_TYPE_INDETERMINATE = 2;
       
       
        51
       
       
        public static final int PROGRESS_TYPE_LABEL = 3;
       
       
        52
       
       
       
       
        53
       
       
        private OnCardClickListener mClickListener;
       
       
        54
       
       
       
       
        55
       
       
       
       
        56
       
       
        // The card model contains a reference to its desired layout (for extensibility), title,
       
       
        57
       
       
        // description, zero to many action buttons, and zero or 1 progress indicators.
       
       
        58
       
       
        private int mLayoutId = R.layout.card;
       
       
        59
       
       
       
       
        60
       
       
        /**
       
       
        61
       
       
        * Tag that uniquely identifies this card.
       
       
        62
       
       
        */
       
       
        63
       
       
        private String mTag = null;
       
       
        64
       
       
       
       
        65
       
       
        private String mTitle = null;
       
       
        66
       
       
        private String mDescription = null;
       
       
        67
       
       
       
       
        68
       
       
        private View mCardView = null;
       
       
        69
       
       
        private View mOverlayView = null;
       
       
        70
       
       
        private TextView mTitleView = null;
       
       
        71
       
       
        private TextView mDescView = null;
       
       
        72
       
       
        private View mActionAreaView = null;
       
       
        73
       
       
       
       
        74
       
       
        private Animator mOngoingAnimator = null;
       
       
        75
       
       
       
       
        76
       
       
        /**
       
       
        77
       
       
        * Visual state, either {@link #CARD_STATE_NORMAL}, {@link #CARD_STATE_FOCUSED} or
       
       
        78
       
       
        * {@link #CARD_STATE_INACTIVE}.
       
       
        79
       
       
        */
       
       
        80
       
       
        private int mCardState = CARD_STATE_NORMAL;
       
       
        81
       
       
        public static final int CARD_STATE_NORMAL = 1;
       
       
        82
       
       
        public static final int CARD_STATE_FOCUSED = 2;
       
       
        83
       
       
        public static final int CARD_STATE_INACTIVE = 3;
       
       
        84
       
       
       
       
        85
       
       
        /**
       
       
        86
       
       
        * Represent actions that can be taken from the card.  Stylistically the developer can
       
       
        87
       
       
        * designate the action as positive, negative (ok/cancel, for instance), or neutral.
       
       
        88
       
       
        * This "type" can be used as a UI hint.
       
       
        89
       
       
        * @see com.example.android.sensors.batchstepsensor.Card.CardAction
       
       
        90
       
       
        */
       
       
        91
       
       
        private ArrayList<CardAction> mCardActions = new ArrayList<CardAction>();
       
       
        92
       
       
       
       
        93
       
       
        /**
       
       
        94
       
       
        * Some cards will have a sense of "progress" which should be associated with, but separated
       
       
        95
       
       
        * from its "parent" card.  To push for simplicity in samples, Cards are designed to have
       
       
        96
       
       
        * a maximum of one progress indicator per Card.
       
       
        97
       
       
        */
       
       
        98
       
       
        private CardProgress mCardProgress = null;
       
       
        99
       
       
       
       
        100
       
       
        public Card() {
       
       
        101
       
       
        }
       
       
        102
       
       
       
       
        103
       
       
        public String getTag() {
       
       
        104
       
       
        return mTag;
       
       
        105
       
       
        }
       
       
        106
       
       
       
       
        107
       
       
        public View getView() {
       
       
        108
       
       
        return mCardView;
       
       
        109
       
       
        }
       
       
        110
       
       
       
       
        111
       
       
       
       
        112
       
       
        public Card setDescription(String desc) {
       
       
        113
       
       
        if (mDescView != null) {
       
       
        114
       
       
        mDescription = desc;
       
       
        115
       
       
        mDescView.setText(desc);
       
       
        116
       
       
        }
       
       
        117
       
       
        return this;
       
       
        118
       
       
        }
       
       
        119
       
       
       
       
        120
       
       
        public Card setTitle(String title) {
       
       
        121
       
       
        if (mTitleView != null) {
       
       
        122
       
       
        mTitle = title;
       
       
        123
       
       
        mTitleView.setText(title);
       
       
        124
       
       
        }
       
       
        125
       
       
        return this;
       
       
        126
       
       
        }
       
       
        127
       
       
       
       
        128
       
       
       
       
        129
       
       
        /**
       
       
        130
       
       
        * Return the UI state, either {@link #CARD_STATE_NORMAL}, {@link #CARD_STATE_FOCUSED}
       
       
        131
       
       
        * or {@link #CARD_STATE_INACTIVE}.
       
       
        132
       
       
        */
       
       
        133
       
       
        public int getState() {
       
       
        134
       
       
        return mCardState;
       
       
        135
       
       
        }
       
       
        136
       
       
       
       
        137
       
       
        /**
       
       
        138
       
       
        * Set the UI state. The parameter describes the state and must be either
       
       
        139
       
       
        * {@link #CARD_STATE_NORMAL}, {@link #CARD_STATE_FOCUSED} or {@link #CARD_STATE_INACTIVE}.
       
       
        140
       
       
        * Note: This method must be called from the UI Thread.
       
       
        141
       
       
        * @param state
       
       
        142
       
       
        * @return The card itself, allows for chaining of calls
       
       
        143
       
       
        */
       
       
        144
       
       
        public Card setState(int state) {
       
       
        145
       
       
        mCardState = state;
       
       
        146
       
       
        if (null != mOverlayView) {
       
       
        147
       
       
        if (null != mOngoingAnimator) {
       
       
        148
       
       
        mOngoingAnimator.end();
       
       
        149
       
       
        mOngoingAnimator = null;
       
       
        150
       
       
        }
       
       
        151
       
       
        switch (state) {
       
       
        152
       
       
        case CARD_STATE_NORMAL: {
       
       
        153
       
       
        mOverlayView.setVisibility(View.GONE);
       
       
        154
       
       
        mOverlayView.setAlpha(1.f);
       
       
        155
       
       
        break;
       
       
        156
       
       
        }
       
       
        157
       
       
        case CARD_STATE_FOCUSED: {
       
       
        158
       
       
        mOverlayView.setVisibility(View.VISIBLE);
       
       
        159
       
       
        mOverlayView.setBackgroundResource(R.drawable.card_overlay_focused);
       
       
        160
       
       
        ObjectAnimator animator = ObjectAnimator.ofFloat(mOverlayView, "alpha", 0.f);
       
       
        161
       
       
        animator.setRepeatMode(ObjectAnimator.REVERSE);
       
       
        162
       
       
        animator.setRepeatCount(ObjectAnimator.INFINITE);
       
       
        163
       
       
        animator.setDuration(1000);
       
       
        164
       
       
        animator.start();
       
       
        165
       
       
        mOngoingAnimator = animator;
       
       
        166
       
       
        break;
       
       
        167
       
       
        }
       
       
        168
       
       
        case CARD_STATE_INACTIVE: {
       
       
        169
       
       
        mOverlayView.setVisibility(View.VISIBLE);
       
       
        170
       
       
        mOverlayView.setAlpha(1.f);
       
       
        171
       
       
        mOverlayView.setBackgroundColor(Color.argb(0xaa, 0xcc, 0xcc, 0xcc));
       
       
        172
       
       
        break;
       
       
        173
       
       
        }
       
       
        174
       
       
        }
       
       
        175
       
       
        }
       
       
        176
       
       
        return this;
       
       
        177
       
       
        }
       
       
        178
       
       
       
       
        179
       
       
        /**
       
       
        180
       
       
        * Set the type of progress indicator.
       
       
        181
       
       
        * The progress type can only be changed if the Card was initially build with a progress
       
       
        182
       
       
        * indicator.
       
       
        183
       
       
        * See {@link Builder#setProgressType(int)}.
       
       
        184
       
       
        * Must be a value of either {@link #PROGRESS_TYPE_NORMAL},
       
       
        185
       
       
        * {@link #PROGRESS_TYPE_INDETERMINATE}, {@link #PROGRESS_TYPE_LABEL} or
       
       
        186
       
       
        * {@link #PROGRESS_TYPE_NO_PROGRESS}.
       
       
        187
       
       
        * @param progressType
       
       
        188
       
       
        * @return The card itself, allows for chaining of calls
       
       
        189
       
       
        */
       
       
        190
       
       
        public Card setProgressType(int progressType) {
       
       
        191
       
       
        if (mCardProgress == null) {
       
       
        192
       
       
        mCardProgress = new CardProgress();
       
       
        193
       
       
        }
       
       
        194
       
       
        mCardProgress.setProgressType(progressType);
       
       
        195
       
       
        return this;
       
       
        196
       
       
        }
       
       
        197
       
       
       
       
        198
       
       
        /**
       
       
        199
       
       
        * Return the progress indicator type. A value of either {@link #PROGRESS_TYPE_NORMAL},
       
       
        200
       
       
        * {@link #PROGRESS_TYPE_INDETERMINATE}, {@link #PROGRESS_TYPE_LABEL}. Otherwise if no progress
       
       
        201
       
       
        * indicator is enabled, {@link #PROGRESS_TYPE_NO_PROGRESS} is returned.
       
       
        202
       
       
        * @return
       
       
        203
       
       
        */
       
       
        204
       
       
        public int getProgressType() {
       
       
        205
       
       
        if (mCardProgress == null) {
       
       
        206
       
       
        return PROGRESS_TYPE_NO_PROGRESS;
       
       
        207
       
       
        }
       
       
        208
       
       
        return mCardProgress.progressType;
       
       
        209
       
       
        }
       
       
        210
       
       
       
       
        211
       
       
        /**
       
       
        212
       
       
        * Set the progress to the specified value. Only applicable if the card has a
       
       
        213
       
       
        * {@link #PROGRESS_TYPE_NORMAL} progress type.
       
       
        214
       
       
        * @param progress
       
       
        215
       
       
        * @return
       
       
        216
       
       
        * @see #setMaxProgress(int)
       
       
        217
       
       
        */
       
       
        218
       
       
        public Card setProgress(int progress) {
       
       
        219
       
       
        if (mCardProgress != null) {
       
       
        220
       
       
        mCardProgress.setProgress(progress);
       
       
        221
       
       
        }
       
       
        222
       
       
        return this;
       
       
        223
       
       
        }
       
       
        224
       
       
       
       
        225
       
       
        /**
       
       
        226
       
       
        * Set the range of the progress to 0...max. Only applicable if the card has a
       
       
        227
       
       
        * {@link #PROGRESS_TYPE_NORMAL} progress type.
       
       
        228
       
       
        * @return
       
       
        229
       
       
        */
       
       
        230
       
       
        public Card setMaxProgress(int max){
       
       
        231
       
       
        if (mCardProgress != null) {
       
       
        232
       
       
        mCardProgress.setMax(max);
       
       
        233
       
       
        }
       
       
        234
       
       
        return this;
       
       
        235
       
       
        }
       
       
        236
       
       
       
       
        237
       
       
        /**
       
       
        238
       
       
        * Set the label text for the progress if the card has a progress type of
       
       
        239
       
       
        * {@link #PROGRESS_TYPE_NORMAL}, {@link #PROGRESS_TYPE_INDETERMINATE} or
       
       
        240
       
       
        * {@link #PROGRESS_TYPE_LABEL}
       
       
        241
       
       
        * @param text
       
       
        242
       
       
        * @return
       
       
        243
       
       
        */
       
       
        244
       
       
        public Card setProgressLabel(String text) {
       
       
        245
       
       
        if (mCardProgress != null) {
       
       
        246
       
       
        mCardProgress.setProgressLabel(text);
       
       
        247
       
       
        }
       
       
        248
       
       
        return this;
       
       
        249
       
       
        }
       
       
        250
       
       
       
       
        251
       
       
        /**
       
       
        252
       
       
        * Toggle the visibility of the progress section of the card. Only applicable if
       
       
        253
       
       
        * the card has a progress type of
       
       
        254
       
       
        * {@link #PROGRESS_TYPE_NORMAL}, {@link #PROGRESS_TYPE_INDETERMINATE} or
       
       
        255
       
       
        * {@link #PROGRESS_TYPE_LABEL}.
       
       
        256
       
       
        * @param isVisible
       
       
        257
       
       
        * @return
       
       
        258
       
       
        */
       
       
        259
       
       
        public Card setProgressVisibility(boolean isVisible) {
       
       
        260
       
       
        if (mCardProgress.progressView == null) {
       
       
        261
       
       
        return this; // Card does not have progress
       
       
        262
       
       
        }
       
       
        263
       
       
        mCardProgress.progressView.setVisibility(isVisible ? View.VISIBLE : View.GONE);
       
       
        264
       
       
       
       
        265
       
       
        return this;
       
       
        266
       
       
        }
       
       
        267
       
       
       
       
        268
       
       
        /**
       
       
        269
       
       
        * Adds an action to this card during build time.
       
       
        270
       
       
        *
       
       
        271
       
       
        * @param label
       
       
        272
       
       
        * @param id
       
       
        273
       
       
        * @param type
       
       
        274
       
       
        */
       
       
        275
       
       
        private void addAction(String label, int id, int type) {
       
       
        276
       
       
        CardAction cardAction = new CardAction();
       
       
        277
       
       
        cardAction.label = label;
       
       
        278
       
       
        cardAction.id = id;
       
       
        279
       
       
        cardAction.type = type;
       
       
        280
       
       
        mCardActions.add(cardAction);
       
       
        281
       
       
        }
       
       
        282
       
       
       
       
        283
       
       
        /**
       
       
        284
       
       
        * Toggles the visibility of a card action.
       
       
        285
       
       
        * @param actionId
       
       
        286
       
       
        * @param isVisible
       
       
        287
       
       
        * @return
       
       
        288
       
       
        */
       
       
        289
       
       
        public Card setActionVisibility(int actionId, boolean isVisible) {
       
       
        290
       
       
        int visibilityFlag = isVisible ? View.VISIBLE : View.GONE;
       
       
        291
       
       
        for (CardAction action : mCardActions) {
       
       
        292
       
       
        if (action.id == actionId && action.actionView != null) {
       
       
        293
       
       
        action.actionView.setVisibility(visibilityFlag);
       
       
        294
       
       
        }
       
       
        295
       
       
        }
       
       
        296
       
       
        return this;
       
       
        297
       
       
        }
       
       
        298
       
       
       
       
        299
       
       
        /**
       
       
        300
       
       
        * Toggles visibility of the action area of this Card through an animation.
       
       
        301
       
       
        * @param isVisible
       
       
        302
       
       
        * @return
       
       
        303
       
       
        */
       
       
        304
       
       
        public Card setActionAreaVisibility(boolean isVisible) {
       
       
        305
       
       
        if (mActionAreaView == null) {
       
       
        306
       
       
        return this; // Card does not have an action area
       
       
        307
       
       
        }
       
       
        308
       
       
       
       
        309
       
       
        if (isVisible) {
       
       
        310
       
       
        // Show the action area
       
       
        311
       
       
        mActionAreaView.setVisibility(View.VISIBLE);
       
       
        312
       
       
        mActionAreaView.setPivotY(0.f);
       
       
        313
       
       
        mActionAreaView.setPivotX(mCardView.getWidth() / 2.f);
       
       
        314
       
       
        mActionAreaView.setAlpha(0.5f);
       
       
        315
       
       
        mActionAreaView.setRotationX(-90.f);
       
       
        316
       
       
        mActionAreaView.animate().rotationX(0.f).alpha(1.f).setDuration(400);
       
       
        317
       
       
        } else {
       
       
        318
       
       
        // Hide the action area
       
       
        319
       
       
        mActionAreaView.setPivotY(0.f);
       
       
        320
       
       
        mActionAreaView.setPivotX(mCardView.getWidth() / 2.f);
       
       
        321
       
       
        mActionAreaView.animate().rotationX(-90.f).alpha(0.f).setDuration(400).setListener(
       
       
        322
       
       
        new AnimatorListenerAdapter() {
       
       
        323
       
       
        @Override
       
       
        324
       
       
        public void onAnimationEnd(Animator animation) {
       
       
        325
       
       
        mActionAreaView.setVisibility(View.GONE);
       
       
        326
       
       
        }
       
       
        327
       
       
        });
       
       
        328
       
       
        }
       
       
        329
       
       
        return this;
       
       
        330
       
       
        }
       
       
        331
       
       
       
       
        332
       
       
       
       
        333
       
       
        /**
       
       
        334
       
       
        * Creates a shallow clone of the card.  Shallow means all values are present, but no views.
       
       
        335
       
       
        * This is useful for saving/restoring in the case of configuration changes, like screen
       
       
        336
       
       
        * rotation.
       
       
        337
       
       
        *
       
       
        338
       
       
        * @return A shallow clone of the card instance
       
       
        339
       
       
        */
       
       
        340
       
       
        public Card createShallowClone() {
       
       
        341
       
       
        Card cloneCard = new Card();
       
       
        342
       
       
       
       
        343
       
       
        // Outer card values
       
       
        344
       
       
        cloneCard.mTitle = mTitle;
       
       
        345
       
       
        cloneCard.mDescription = mDescription;
       
       
        346
       
       
        cloneCard.mTag = mTag;
       
       
        347
       
       
        cloneCard.mLayoutId = mLayoutId;
       
       
        348
       
       
        cloneCard.mCardState = mCardState;
       
       
        349
       
       
       
       
        350
       
       
        // Progress
       
       
        351
       
       
        if (mCardProgress != null) {
       
       
        352
       
       
        cloneCard.mCardProgress = mCardProgress.createShallowClone();
       
       
        353
       
       
        }
       
       
        354
       
       
       
       
        355
       
       
        // Actions
       
       
        356
       
       
        for (CardAction action : mCardActions) {
       
       
        357
       
       
        cloneCard.mCardActions.add(action.createShallowClone());
       
       
        358
       
       
        }
       
       
        359
       
       
       
       
        360
       
       
        return cloneCard;
       
       
        361
       
       
        }
       
       
        362
       
       
       
       
        363
       
       
       
       
        364
       
       
        /**
       
       
        365
       
       
        * Prepare the card to be stored for configuration change.
       
       
        366
       
       
        */
       
       
        367
       
       
        public void prepareForConfigurationChange() {
       
       
        368
       
       
        // Null out views.
       
       
        369
       
       
        mCardView = null;
       
       
        370
       
       
        for (CardAction action : mCardActions) {
       
       
        371
       
       
        action.actionView = null;
       
       
        372
       
       
        }
       
       
        373
       
       
        mCardProgress.progressView = null;
       
       
        374
       
       
        }
       
       
        375
       
       
       
       
        376
       
       
        /**
       
       
        377
       
       
        * Creates a new {@link #Card}.
       
       
        378
       
       
        */
       
       
        379
       
       
        public static class Builder {
       
       
        380
       
       
        private Card mCard;
       
       
        381
       
       
       
       
        382
       
       
        /**
       
       
        383
       
       
        * Instantiate the builder with data from a shallow clone.
       
       
        384
       
       
        * @param listener
       
       
        385
       
       
        * @param card
       
       
        386
       
       
        * @see Card#createShallowClone()
       
       
        387
       
       
        */
       
       
        388
       
       
        protected Builder(OnCardClickListener listener, Card card) {
       
       
        389
       
       
        mCard = card;
       
       
        390
       
       
        mCard.mClickListener = listener;
       
       
        391
       
       
        }
       
       
        392
       
       
       
       
        393
       
       
        /**
       
       
        394
       
       
        * Instantiate the builder with the tag of the card.
       
       
        395
       
       
        * @param listener
       
       
        396
       
       
        * @param tag
       
       
        397
       
       
        */
       
       
        398
       
       
        public Builder(OnCardClickListener listener, String tag) {
       
       
        399
       
       
        mCard = new Card();
       
       
        400
       
       
        mCard.mTag = tag;
       
       
        401
       
       
        mCard.mClickListener = listener;
       
       
        402
       
       
        }
       
       
        403
       
       
       
       
        404
       
       
        public Builder setTitle(String title) {
       
       
        405
       
       
        mCard.mTitle = title;
       
       
        406
       
       
        return this;
       
       
        407
       
       
        }
       
       
        408
       
       
       
       
        409
       
       
        public Builder setDescription(String desc) {
       
       
        410
       
       
        mCard.mDescription = desc;
       
       
        411
       
       
        return this;
       
       
        412
       
       
        }
       
       
        413
       
       
       
       
        414
       
       
        /**
       
       
        415
       
       
        * Add an action.
       
       
        416
       
       
        * The type describes how this action will be displayed. Accepted values are
       
       
        417
       
       
        * {@link #ACTION_NEUTRAL}, {@link #ACTION_POSITIVE} or {@link #ACTION_NEGATIVE}.
       
       
        418
       
       
        *
       
       
        419
       
       
        * @param label The text to display for this action
       
       
        420
       
       
        * @param id Identifier for this action, supplied in the click listener
       
       
        421
       
       
        * @param type UI style of action
       
       
        422
       
       
        * @return
       
       
        423
       
       
        */
       
       
        424
       
       
        public Builder addAction(String label, int id, int type) {
       
       
        425
       
       
        mCard.addAction(label, id, type);
       
       
        426
       
       
        return this;
       
       
        427
       
       
        }
       
       
        428
       
       
       
       
        429
       
       
        /**
       
       
        430
       
       
        * Override the default layout.
       
       
        431
       
       
        * The referenced layout file has to contain the same identifiers as defined in the default
       
       
        432
       
       
        * layout configuration.
       
       
        433
       
       
        * @param layout
       
       
        434
       
       
        * @return
       
       
        435
       
       
        * @see R.layout.card
       
       
        436
       
       
        */
       
       
        437
       
       
        public Builder setLayout(int layout) {
       
       
        438
       
       
        mCard.mLayoutId = layout;
       
       
        439
       
       
        return this;
       
       
        440
       
       
        }
       
       
        441
       
       
       
       
        442
       
       
        /**
       
       
        443
       
       
        * Set the type of progress bar to display.
       
       
        444
       
       
        * Accepted values are:
       
       
        445
       
       
        * <ul>
       
       
        446
       
       
        *     <li>{@link #PROGRESS_TYPE_NO_PROGRESS} disables the progress indicator</li>
       
       
        447
       
       
        *     <li>{@link #PROGRESS_TYPE_NORMAL}
       
       
        448
       
       
        *     displays a standard, linear progress indicator.</li>
       
       
        449
       
       
        *     <li>{@link #PROGRESS_TYPE_INDETERMINATE} displays an indeterminate (infite) progress
       
       
        450
       
       
        *     indicator.</li>
       
       
        451
       
       
        *     <li>{@link #PROGRESS_TYPE_LABEL} only displays a label text in the progress area
       
       
        452
       
       
        *     of the card.</li>
       
       
        453
       
       
        * </ul>
       
       
        454
       
       
        *
       
       
        455
       
       
        * @param progressType
       
       
        456
       
       
        * @return
       
       
        457
       
       
        */
       
       
        458
       
       
        public Builder setProgressType(int progressType) {
       
       
        459
       
       
        mCard.setProgressType(progressType);
       
       
        460
       
       
        return this;
       
       
        461
       
       
        }
       
       
        462
       
       
       
       
        463
       
       
        public Builder setProgressLabel(String label) {
       
       
        464
       
       
        // ensure the progress layout has been initialized, use 'no progress' by default
       
       
        465
       
       
        if (mCard.mCardProgress == null) {
       
       
        466
       
       
        mCard.setProgressType(PROGRESS_TYPE_NO_PROGRESS);
       
       
        467
       
       
        }
       
       
        468
       
       
        mCard.mCardProgress.label = label;
       
       
        469
       
       
        return this;
       
       
        470
       
       
        }
       
       
        471
       
       
       
       
        472
       
       
        public Builder setProgressMaxValue(int maxValue) {
       
       
        473
       
       
        // ensure the progress layout has been initialized, use 'no progress' by default
       
       
        474
       
       
        if (mCard.mCardProgress == null) {
       
       
        475
       
       
        mCard.setProgressType(PROGRESS_TYPE_NO_PROGRESS);
       
       
        476
       
       
        }
       
       
        477
       
       
        mCard.mCardProgress.maxValue = maxValue;
       
       
        478
       
       
        return this;
       
       
        479
       
       
        }
       
       
        480
       
       
       
       
        481
       
       
        public Builder setStatus(int status) {
       
       
        482
       
       
        mCard.setState(status);
       
       
        483
       
       
        return this;
       
       
        484
       
       
        }
       
       
        485
       
       
       
       
        486
       
       
        public Card build(Activity activity) {
       
       
        487
       
       
        LayoutInflater inflater = activity.getLayoutInflater();
       
       
        488
       
       
        // Inflating the card.
       
       
        489
       
       
        ViewGroup cardView = (ViewGroup) inflater.inflate(mCard.mLayoutId,
       
       
        490
       
       
        (ViewGroup) activity.findViewById(R.id.card_stream), false);
       
       
        491
       
       
       
       
        492
       
       
        // Check that the layout contains a TextView with the card_title id
       
       
        493
       
       
        View viewTitle = cardView.findViewById(R.id.card_title);
       
       
        494
       
       
        if (mCard.mTitle != null && viewTitle != null) {
       
       
        495
       
       
        mCard.mTitleView = (TextView) viewTitle;
       
       
        496
       
       
        mCard.mTitleView.setText(mCard.mTitle);
       
       
        497
       
       
        } else if (viewTitle != null) {
       
       
        498
       
       
        viewTitle.setVisibility(View.GONE);
       
       
        499
       
       
        }
       
       
        500
       
       
       
       
        501
       
       
        // Check that the layout contains a TextView with the card_content id
       
       
        502
       
       
        View viewDesc = cardView.findViewById(R.id.card_content);
       
       
        503
       
       
        if (mCard.mDescription != null && viewDesc != null) {
       
       
        504
       
       
        mCard.mDescView = (TextView) viewDesc;
       
       
        505
       
       
        mCard.mDescView.setText(mCard.mDescription);
       
       
        506
       
       
        } else if (viewDesc != null) {
       
       
        507
       
       
        cardView.findViewById(R.id.card_content).setVisibility(View.GONE);
       
       
        508
       
       
        }
       
       
        509
       
       
       
       
        510
       
       
       
       
        511
       
       
        ViewGroup actionArea = (ViewGroup) cardView.findViewById(R.id.card_actionarea);
       
       
        512
       
       
       
       
        513
       
       
        // Inflate Progress
       
       
        514
       
       
        initializeProgressView(inflater, actionArea);
       
       
        515
       
       
       
       
        516
       
       
        // Inflate all action views.
       
       
        517
       
       
        initializeActionViews(inflater, cardView, actionArea);
       
       
        518
       
       
       
       
        519
       
       
        mCard.mCardView = cardView;
       
       
        520
       
       
        mCard.mOverlayView = cardView.findViewById(R.id.card_overlay);
       
       
        521
       
       
       
       
        522
       
       
        return mCard;
       
       
        523
       
       
        }
       
       
        524
       
       
       
       
        525
       
       
        /**
       
       
        526
       
       
        * Initialize data from the given card.
       
       
        527
       
       
        * @param card
       
       
        528
       
       
        * @return
       
       
        529
       
       
        * @see Card#createShallowClone()
       
       
        530
       
       
        */
       
       
        531
       
       
        public Builder cloneFromCard(Card card) {
       
       
        532
       
       
        mCard = card.createShallowClone();
       
       
        533
       
       
        return this;
       
       
        534
       
       
        }
       
       
        535
       
       
       
       
        536
       
       
        /**
       
       
        537
       
       
        * Build the action views by inflating the appropriate layouts and setting the text and
       
       
        538
       
       
        * values.
       
       
        539
       
       
        * @param inflater
       
       
        540
       
       
        * @param cardView
       
       
        541
       
       
        * @param actionArea
       
       
        542
       
       
        */
       
       
        543
       
       
        private void initializeActionViews(LayoutInflater inflater, ViewGroup cardView,
       
       
        544
       
       
        ViewGroup actionArea) {
       
       
        545
       
       
        if (!mCard.mCardActions.isEmpty()) {
       
       
        546
       
       
        // Set action area to visible only when actions are visible
       
       
        547
       
       
        actionArea.setVisibility(View.VISIBLE);
       
       
        548
       
       
        mCard.mActionAreaView = actionArea;
       
       
        549
       
       
        }
       
       
        550
       
       
       
       
        551
       
       
        // Inflate all card actions
       
       
        552
       
       
        for (final CardAction action : mCard.mCardActions) {
       
       
        553
       
       
       
       
        554
       
       
        int useActionLayout = 0;
       
       
        555
       
       
        switch (action.type) {
       
       
        556
       
       
        case Card.ACTION_POSITIVE:
       
       
        557
       
       
        useActionLayout = R.layout.card_button_positive;
       
       
        558
       
       
        break;
       
       
        559
       
       
        case Card.ACTION_NEGATIVE:
       
       
        560
       
       
        useActionLayout = R.layout.card_button_negative;
       
       
        561
       
       
        break;
       
       
        562
       
       
        case Card.ACTION_NEUTRAL:
       
       
        563
       
       
        default:
       
       
        564
       
       
        useActionLayout = R.layout.card_button_neutral;
       
       
        565
       
       
        break;
       
       
        566
       
       
        }
       
       
        567
       
       
       
       
        568
       
       
        action.actionView = inflater.inflate(useActionLayout, actionArea, false);
       
       
        569
       
       
        Button actionButton = (Button) action.actionView.findViewById(R.id.card_button);
       
       
        570
       
       
       
       
        571
       
       
        actionButton.setText(action.label);
       
       
        572
       
       
        actionButton.setOnClickListener(new View.OnClickListener() {
       
       
        573
       
       
        @Override
       
       
        574
       
       
        public void onClick(View v) {
       
       
        575
       
       
        mCard.mClickListener.onCardClick(action.id, mCard.mTag);
       
       
        576
       
       
        }
       
       
        577
       
       
        });
       
       
        578
       
       
        actionArea.addView(action.actionView);
       
       
        579
       
       
        }
       
       
        580
       
       
        }
       
       
        581
       
       
       
       
        582
       
       
        /**
       
       
        583
       
       
        * Build the progress view into the given ViewGroup.
       
       
        584
       
       
        *
       
       
        585
       
       
        * @param inflater
       
       
        586
       
       
        * @param actionArea
       
       
        587
       
       
        */
       
       
        588
       
       
        private void initializeProgressView(LayoutInflater inflater, ViewGroup actionArea) {
       
       
        589
       
       
       
       
        590
       
       
        // Only inflate progress layout if a progress type other than NO_PROGRESS was set.
       
       
        591
       
       
        if (mCard.mCardProgress != null) {
       
       
        592
       
       
        //Setup progress card.
       
       
        593
       
       
        View progressView = inflater.inflate(R.layout.card_progress, actionArea, false);
       
       
        594
       
       
        ProgressBar progressBar =
       
       
        595
       
       
        (ProgressBar) progressView.findViewById(R.id.card_progress);
       
       
        596
       
       
        ((TextView) progressView.findViewById(R.id.card_progress_text))
       
       
        597
       
       
        .setText(mCard.mCardProgress.label);
       
       
        598
       
       
        progressBar.setMax(mCard.mCardProgress.maxValue);
       
       
        599
       
       
        progressBar.setProgress(0);
       
       
        600
       
       
        mCard.mCardProgress.progressView = progressView;
       
       
        601
       
       
        mCard.mCardProgress.setProgressType(mCard.getProgressType());
       
       
        602
       
       
        actionArea.addView(progressView);
       
       
        603
       
       
        }
       
       
        604
       
       
        }
       
       
        605
       
       
        }
       
       
        606
       
       
       
       
        607
       
       
        /**
       
       
        608
       
       
        * Represents a clickable action, accessible from the bottom of the card.
       
       
        609
       
       
        * Fields include the label, an ID to specify the action that was performed in the callback,
       
       
        610
       
       
        * an action type (positive, negative, neutral), and the callback.
       
       
        611
       
       
        */
       
       
        612
       
       
        public class CardAction {
       
       
        613
       
       
       
       
        614
       
       
        public String label;
       
       
        615
       
       
        public int id;
       
       
        616
       
       
        public int type;
       
       
        617
       
       
        public View actionView;
       
       
        618
       
       
       
       
        619
       
       
        public CardAction createShallowClone() {
       
       
        620
       
       
        CardAction actionClone = new CardAction();
       
       
        621
       
       
        actionClone.label = label;
       
       
        622
       
       
        actionClone.id = id;
       
       
        623
       
       
        actionClone.type = type;
       
       
        624
       
       
        return actionClone;
       
       
        625
       
       
        // Not the view.  Never the view (don't want to hold view references for
       
       
        626
       
       
        // onConfigurationChange.
       
       
        627
       
       
        }
       
       
        628
       
       
       
       
        629
       
       
        }
       
       
        630
       
       
       
       
        631
       
       
        /**
       
       
        632
       
       
        * Describes the progress of a {@link Card}.
       
       
        633
       
       
        * Three types of progress are supported:
       
       
        634
       
       
        * <ul><li>{@link Card#PROGRESS_TYPE_NORMAL: Standard progress bar with label text</li>
       
       
        635
       
       
        * <li>{@link Card#PROGRESS_TYPE_INDETERMINATE}: Indeterminate progress bar with label txt</li>
       
       
        636
       
       
        * <li>{@link Card#PROGRESS_TYPE_LABEL}: Label only, no progresss bar</li>
       
       
        637
       
       
        * </ul>
       
       
        638
       
       
        */
       
       
        639
       
       
        public class CardProgress {
       
       
        640
       
       
        private int progressType = Card.PROGRESS_TYPE_NO_PROGRESS;
       
       
        641
       
       
        private String label = "";
       
       
        642
       
       
        private int currProgress = 0;
       
       
        643
       
       
        private int maxValue = 100;
       
       
        644
       
       
       
       
        645
       
       
        public View progressView = null;
       
       
        646
       
       
        private ProgressBar progressBar = null;
       
       
        647
       
       
        private TextView progressLabel = null;
       
       
        648
       
       
       
       
        649
       
       
        public CardProgress createShallowClone() {
       
       
        650
       
       
        CardProgress progressClone = new CardProgress();
       
       
        651
       
       
        progressClone.label = label;
       
       
        652
       
       
        progressClone.currProgress = currProgress;
       
       
        653
       
       
        progressClone.maxValue = maxValue;
       
       
        654
       
       
        progressClone.progressType = progressType;
       
       
        655
       
       
        return progressClone;
       
       
        656
       
       
        }
       
       
        657
       
       
       
       
        658
       
       
        /**
       
       
        659
       
       
        * Set the progress. Only useful for the type {@link #PROGRESS_TYPE_NORMAL}.
       
       
        660
       
       
        * @param progress
       
       
        661
       
       
        * @see android.widget.ProgressBar#setProgress(int)
       
       
        662
       
       
        */
       
       
        663
       
       
        public void setProgress(int progress) {
       
       
        664
       
       
        currProgress = progress;
       
       
        665
       
       
        final ProgressBar bar = getProgressBar();
       
       
        666
       
       
        if (bar != null) {
       
       
        667
       
       
        bar.setProgress(currProgress);
       
       
        668
       
       
        bar.invalidate();
       
       
        669
       
       
        }
       
       
        670
       
       
        }
       
       
        671
       
       
       
       
        672
       
       
        /**
       
       
        673
       
       
        * Set the range of the progress to 0...max.
       
       
        674
       
       
        * Only useful for the type {@link #PROGRESS_TYPE_NORMAL}.
       
       
        675
       
       
        * @param max
       
       
        676
       
       
        * @see android.widget.ProgressBar#setMax(int)
       
       
        677
       
       
        */
       
       
        678
       
       
        public void setMax(int max) {
       
       
        679
       
       
        maxValue = max;
       
       
        680
       
       
        final ProgressBar bar = getProgressBar();
       
       
        681
       
       
        if (bar != null) {
       
       
        682
       
       
        bar.setMax(maxValue);
       
       
        683
       
       
        }
       
       
        684
       
       
        }
       
       
        685
       
       
       
       
        686
       
       
        /**
       
       
        687
       
       
        * Set the label text that appears near the progress indicator.
       
       
        688
       
       
        * @param text
       
       
        689
       
       
        */
       
       
        690
       
       
        public void setProgressLabel(String text) {
       
       
        691
       
       
        label = text;
       
       
        692
       
       
        final TextView labelView = getProgressLabel();
       
       
        693
       
       
        if (labelView != null) {
       
       
        694
       
       
        labelView.setText(text);
       
       
        695
       
       
        }
       
       
        696
       
       
        }
       
       
        697
       
       
       
       
        698
       
       
        /**
       
       
        699
       
       
        * Set how progress is displayed. The parameter must be one of three supported types:
       
       
        700
       
       
        * <ul><li>{@link Card#PROGRESS_TYPE_NORMAL: Standard progress bar with label text</li>
       
       
        701
       
       
        * <li>{@link Card#PROGRESS_TYPE_INDETERMINATE}:
       
       
        702
       
       
        * Indeterminate progress bar with label txt</li>
       
       
        703
       
       
        * <li>{@link Card#PROGRESS_TYPE_LABEL}: Label only, no progresss bar</li>
       
       
        704
       
       
        * @param type
       
       
        705
       
       
        */
       
       
        706
       
       
        public void setProgressType(int type) {
       
       
        707
       
       
        progressType = type;
       
       
        708
       
       
        if (progressView != null) {
       
       
        709
       
       
        switch (type) {
       
       
        710
       
       
        case PROGRESS_TYPE_NO_PROGRESS: {
       
       
        711
       
       
        progressView.setVisibility(View.GONE);
       
       
        712
       
       
        break;
       
       
        713
       
       
        }
       
       
        714
       
       
        case PROGRESS_TYPE_NORMAL: {
       
       
        715
       
       
        progressView.setVisibility(View.VISIBLE);
       
       
        716
       
       
        getProgressBar().setIndeterminate(false);
       
       
        717
       
       
        break;
       
       
        718
       
       
        }
       
       
        719
       
       
        case PROGRESS_TYPE_INDETERMINATE: {
       
       
        720
       
       
        progressView.setVisibility(View.VISIBLE);
       
       
        721
       
       
        getProgressBar().setIndeterminate(true);
       
       
        722
       
       
        break;
       
       
        723
       
       
        }
       
       
        724
       
       
        }
       
       
        725
       
       
        }
       
       
        726
       
       
        }
       
       
        727
       
       
       
       
        728
       
       
        private TextView getProgressLabel() {
       
       
        729
       
       
        if (progressLabel != null) {
       
       
        730
       
       
        return progressLabel;
       
       
        731
       
       
        } else if (progressView != null) {
       
       
        732
       
       
        progressLabel = (TextView) progressView.findViewById(R.id.card_progress_text);
       
       
        733
       
       
        return progressLabel;
       
       
        734
       
       
        } else {
       
       
        735
       
       
        return null;
       
       
        736
       
       
        }
       
       
        737
       
       
        }
       
       
        738
       
       
       
       
        739
       
       
        private ProgressBar getProgressBar() {
       
       
        740
       
       
        if (progressBar != null) {
       
       
        741
       
       
        return progressBar;
       
       
        742
       
       
        } else if (progressView != null) {
       
       
        743
       
       
        progressBar = (ProgressBar) progressView.findViewById(R.id.card_progress);
       
       
        744
       
       
        return progressBar;
       
       
        745
       
       
        } else {
       
       
        746
       
       
        return null;
       
       
        747
       
       
        }
       
       
        748
       
       
        }
       
       
        749
       
       
       
       
        750
       
       
        }
       
       
        751
       
       
        }
       
       
        752