Android Open Source - appboy-android-sdk Base Card View






From Project

Back to project page appboy-android-sdk.

License

The source code is released under:

Copyright (c) 2014 Appboy, Inc. All rights reserved. * Use of source code or binaries contained within Appboy's Android SDK is permitted only to enable use of the Appboy platform by customers of Appb...

If you think the Android project appboy-android-sdk listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.appboy.ui.widget;
//from  ww w .ja v a 2s  . co m
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.ViewSwitcher;
import com.appboy.Appboy;
import com.appboy.Constants;
import com.appboy.models.cards.Card;
import com.appboy.ui.R;
import com.appboy.ui.support.StringUtils;
import java.util.Observable;
import java.util.Observer;

/**
 * Base class for Appboy feed card views
 */
public abstract class BaseCardView<T extends Card> extends RelativeLayout implements Observer {
  private static final String TAG = String.format("%s.%s", Constants.APPBOY_LOG_TAG_PREFIX, BaseCardView.class.getName());
  private static Boolean unreadCardVisualIndicatorOn;
  private static final float SQUARE_ASPECT_RATIO = 1f;

  protected final Context mContext;
  protected T mCard;
  protected ImageSwitcher mImageSwitcher;

  public BaseCardView(Context context) {
    super(context);
    mContext = context;
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    inflater.inflate(getLayoutResource(), this);
    // All implementing views of BaseCardView must include this switcher view in order to have the
    // read/unread functionality. Views that don't have the indicator (like banner views) won't have the image switcher
    // in them and thus we do the null-check below.
    mImageSwitcher = (ImageSwitcher) findViewById(R.id.com_appboy_newsfeed_item_read_indicator_image_switcher);
    if (mImageSwitcher != null) {
      mImageSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
        @Override
        public View makeView() {
          return new ImageView(mContext.getApplicationContext());
        }
      });
    }

    // If the visual indicator on cards shouldn't be on, due to the xml setting in appboy.xml, then set the
    // imageSwitcher to GONE to hide the indicator UI.

    // Read the setting from the appboy.xml if we don't already have a value.
    if (unreadCardVisualIndicatorOn == null) {
      int resId = mContext.getResources().getIdentifier("com_appboy_newsfeed_unread_visual_indicator_on", "bool", context.getPackageName());
      if (resId != 0) {
        unreadCardVisualIndicatorOn = context.getResources().getBoolean(resId);
      } else {
        // If the xml setting isn't present, default to true.
        unreadCardVisualIndicatorOn = true;
      }
    }

    // If the setting is false, then hide the indicator.
    if (!unreadCardVisualIndicatorOn) {
      if (mImageSwitcher != null) {
        mImageSwitcher.setVisibility(GONE);
      }
    }
  }

  /**
   * This method is called when the setRead() method is called on the internal Card object.
   */
  @Override
  public void update(Observable observable, Object data) {
    setCardViewedIndicator();
  }

  /**
   * Checks to see if the card object is viewed and if so, sets the read/unread status
   * indicator image. If the card is null, does nothing.
   */
  private void setCardViewedIndicator() {
    if (getCard() != null) {
      if (mImageSwitcher != null) {
        int resourceId;
        if (getCard().isRead()) {
          resourceId = R.drawable.icon_read;
        } else {
          resourceId = R.drawable.icon_unread;
        }
        mImageSwitcher.setImageResource(resourceId);
        // Used to identify the current Drawable in the imageSwitcher
        mImageSwitcher.setTag(String.valueOf(resourceId));
      } else {
        Log.d(TAG, "The imageSwitcher for the read/unread feature is null. Did you include it in your xml?");
      }
    } else {
      Log.d(TAG, "The card is null.");
    }
  }

  protected abstract int getLayoutResource();

  public void setCard(final T card) {
    mCard = card;
    onSetCard(card);
    // Register as an observer to the card class
    card.addObserver(this);
    setCardViewedIndicator();
  }

  protected abstract void onSetCard(T card);

  public Card getCard() {
    return mCard;
  }

  void setOptionalTextView(TextView view, String value) {
    if (value != null && !value.trim().equals(StringUtils.EMPTY_STRING)) {
      view.setText(value);
      view.setVisibility(VISIBLE);
    } else {
      view.setText(StringUtils.EMPTY_STRING);
      view.setVisibility(GONE);
    }
  }

  void safeSetBackground(Drawable background) {
    if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
      setBackgroundDrawable(background);
    } else {
      setBackgroundNew(background);
    }
  }

  @TargetApi(16)
  private void setBackgroundNew(Drawable background) {
    setBackground(background);
  }

  /**
   * Calls setImageViewToUrl with aspect ratio set to 1f and respectAspectRatio set to false.
   * @see com.appboy.ui.widget.BaseCardView#setImageViewToUrl(android.widget.ImageView, String, float, boolean)
   */
  void setImageViewToUrl(final ImageView imageView, final String imageUrl) {
    setImageViewToUrl(imageView, imageUrl, 1f, false);
  }

  /**
   * Calls setImageViewToUrl with respectAspectRatio set to true.
   * @see com.appboy.ui.widget.BaseCardView#setImageViewToUrl(android.widget.ImageView, String, float, boolean)
   */
  void setImageViewToUrl(final ImageView imageView, final String imageUrl, final float aspectRatio){
    setImageViewToUrl(imageView, imageUrl, aspectRatio, true);
  }

  /**
   * Asynchronously fetches the image at the given imageUrl and displays the image in the ImageView. No image will be
   * displayed if the image cannot be downloaded or fetched from the cache.
   *
   * @param imageView the ImageView in which to display the image
   * @param imageUrl the URL of the image resource
   * @param aspectRatio the desired aspect ratio of the image. This should match what's being sent down from the dashboard.
   * @param respectAspectRatio whether to use aspectRatio as the final aspect ratio of the imageView. When set to false,
   *                           the aspect ratio of the imageView will match that of the downloaded image. When set to true,
   *                           the provided aspect ratio will match aspectRatio, regardless of the actual dimensions of the
   *                           downloaded image.
   */
  void setImageViewToUrl(final ImageView imageView, final String imageUrl, final float aspectRatio, final boolean respectAspectRatio) {
    if (imageUrl == null) {
      Log.w(TAG, "The image url to render is null. Not setting the card image.");
      return;
    }

    if (aspectRatio == 0){
      Log.w(TAG, "The image aspect ratio is 0. Not setting the card image.");
      return;
    }

    if (!imageUrl.equals(imageView.getTag())) {
      if (aspectRatio != SQUARE_ASPECT_RATIO) {
        // We need to set layout params on the imageView once its layout state is visible. To do this,
        // we obtain the imageView's observer and attach a listener on it for when the view's layout
        // occurs. At layout time, we set the imageView's size params based on the aspect ratio
        // for our card. Note that after the card's first layout, we don't want redundant resizing
        // so we remove our listener after the resizing.
        ViewTreeObserver viewTreeObserver = imageView.getViewTreeObserver();
        if (viewTreeObserver.isAlive()) {
          viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
              int width = imageView.getWidth();
              imageView.setLayoutParams(new LayoutParams(width, (int) (width / aspectRatio)));
              removeOnGlobalLayoutListenerSafe(imageView.getViewTreeObserver(), this);
            }
          });
        }
      }

      imageView.setImageResource(android.R.color.transparent);
      Appboy.getInstance(getContext()).fetchAndRenderImage(imageUrl, imageView, respectAspectRatio);
      imageView.setTag(imageUrl);
    }
  }

  @TargetApi(16)
  public static void removeOnGlobalLayoutListenerSafe(ViewTreeObserver viewTreeObserver,
                                                ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener) {
    if (android.os.Build.VERSION.SDK_INT < 16) {
      viewTreeObserver.removeGlobalOnLayoutListener(onGlobalLayoutListener);
    } else {
      viewTreeObserver.removeOnGlobalLayoutListener(onGlobalLayoutListener);
    }
  }
}




Java Source Code List

com.android.vending.billing.utils.Base64DecoderException.java
com.android.vending.billing.utils.Base64.java
com.android.vending.billing.utils.IabException.java
com.android.vending.billing.utils.IabHelper.java
com.android.vending.billing.utils.IabResult.java
com.android.vending.billing.utils.Inventory.java
com.android.vending.billing.utils.Purchase.java
com.android.vending.billing.utils.Security.java
com.android.vending.billing.utils.SkuDetails.java
com.appboy.AppboyAdmReceiver.java
com.appboy.AppboyGcmReceiver.java
com.appboy.AppboyNotificationUtils.java
com.appboy.helloworld.HelloAppboyActivity.java
com.appboy.sample.AppboyBroadcastReceiver.java
com.appboy.sample.AppboyFragmentActivity.java
com.appboy.sample.CustomAppboyNavigator.java
com.appboy.sample.CustomSlideupManagerListener.java
com.appboy.sample.CustomSlideupViewFactory.java
com.appboy.sample.DecisionFragment.java
com.appboy.sample.DroidBoyActivity.java
com.appboy.sample.DroidGirlActivity.java
com.appboy.sample.DroidboyApplication.java
com.appboy.sample.FeedCategoriesFragment.java
com.appboy.sample.FeedFragmentActivity.java
com.appboy.sample.FeedbackFragmentActivity.java
com.appboy.sample.PreferencesActivity.java
com.appboy.sample.SlideupTesterActivity.java
com.appboy.sample.Test.java
com.appboy.sample.UserProfileDialog.java
com.appboy.sample.util.SharedPrefsUtil.java
com.appboy.ui.AppboyFeedFragment.java
com.appboy.ui.AppboyFeedbackFragment.java
com.appboy.ui.AppboyNavigator.java
com.appboy.ui.AppboyWebViewActivity.java
com.appboy.ui.actions.ActionFactory.java
com.appboy.ui.actions.ActivityAction.java
com.appboy.ui.actions.GooglePlayAppDetailsAction.java
com.appboy.ui.actions.IAction.java
com.appboy.ui.actions.ViewAction.java
com.appboy.ui.actions.WebAction.java
com.appboy.ui.activities.AppboyBaseActivity.java
com.appboy.ui.activities.AppboyBaseFragmentActivity.java
com.appboy.ui.activities.AppboyFeedActivity.java
com.appboy.ui.adapters.AppboyListAdapter.java
com.appboy.ui.configuration.XmlUIConfigurationProvider.java
com.appboy.ui.slideups.AppboySlideupManager.java
com.appboy.ui.slideups.ISlideupManagerListener.java
com.appboy.ui.slideups.ISlideupViewFactory.java
com.appboy.ui.slideups.ISlideupViewLifecycleListener.java
com.appboy.ui.slideups.SlideupCloser.java
com.appboy.ui.slideups.SlideupOperation.java
com.appboy.ui.slideups.SlideupViewWrapper.java
com.appboy.ui.slideups.SwipeDismissTouchListener.java
com.appboy.ui.slideups.TouchAwareSwipeDismissTouchListener.java
com.appboy.ui.support.DrawingUtils.java
com.appboy.ui.support.StringUtils.java
com.appboy.ui.support.UriUtils.java
com.appboy.ui.support.ViewUtils.java
com.appboy.ui.widget.BannerImageCardView.java
com.appboy.ui.widget.BaseCardView.java
com.appboy.ui.widget.CaptionedImageCardView.java
com.appboy.ui.widget.CrossPromotionSmallCardView.java
com.appboy.ui.widget.DefaultCardView.java
com.appboy.ui.widget.ShortNewsCardView.java
com.appboy.ui.widget.StarRatingView.java
com.appboy.ui.widget.TextAnnouncementCardView.java