예제 #1
0
  private void runEnterAnimation(View view, int position) {
    if (!animateItems || position >= ANIMATED_ITEMS_COUNT - 1) {
      return;
    }

    if (position > lastAnimatedPosition) {
      lastAnimatedPosition = position;
      view.setTranslationY(Utils.getScreenHeight(context));
      view.animate()
          .translationY(0)
          .setInterpolator(new DecelerateInterpolator(3.f))
          .setDuration(700)
          .start();
    }
  }
예제 #2
0
/** Created by Miris on 09.02.15. */
public class FeedAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
    implements View.OnClickListener {
  private static final int VIEW_TYPE_DEFAULT = 1;
  private static final int VIEW_TYPE_LOADER = 2;

  private static final DecelerateInterpolator DECCELERATE_INTERPOLATOR =
      new DecelerateInterpolator();
  private static final AccelerateInterpolator ACCELERATE_INTERPOLATOR =
      new AccelerateInterpolator();
  private static final OvershootInterpolator OVERSHOOT_INTERPOLATOR = new OvershootInterpolator(4);

  private static final int ANIMATED_ITEMS_COUNT = 2;

  private Context context;
  private int lastAnimatedPosition = -1;
  private int itemsCount = 0;
  private boolean animateItems = false;

  private final Map<Integer, Integer> likesCount = new HashMap<>();
  private final Map<RecyclerView.ViewHolder, AnimatorSet> likeAnimations = new HashMap<>();
  private final ArrayList<Integer> likedPositions = new ArrayList<>();

  private OnFeedItemClickListener onFeedItemClickListener;

  private boolean showLoadingView = false;
  private int loadingViewSize = Utils.dpToPx(200);

  public FeedAdapter(Context context) {
    this.context = context;
  }

  @Override
  public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    final View view = LayoutInflater.from(context).inflate(R.layout.item_feed, parent, false);
    final CellFeedViewHolder cellFeedViewHolder = new CellFeedViewHolder(view);
    if (viewType == VIEW_TYPE_DEFAULT) {
      cellFeedViewHolder.btnComments.setOnClickListener(this);
      cellFeedViewHolder.btnMore.setOnClickListener(this);
      cellFeedViewHolder.ivFeedCenter.setOnClickListener(this);
      cellFeedViewHolder.btnLike.setOnClickListener(this);
      cellFeedViewHolder.ivUserProfile.setOnClickListener(this);
    } else if (viewType == VIEW_TYPE_LOADER) {
      View bgView = new View(context);
      bgView.setLayoutParams(
          new FrameLayout.LayoutParams(
              ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
      bgView.setBackgroundColor(0x77ffffff);
      cellFeedViewHolder.vImageRoot.addView(bgView);
      cellFeedViewHolder.vProgressBg = bgView;

      FrameLayout.LayoutParams params =
          new FrameLayout.LayoutParams(loadingViewSize, loadingViewSize);
      params.gravity = Gravity.CENTER;
      SendingProgressView sendingProgressView = new SendingProgressView(context);
      sendingProgressView.setLayoutParams(params);
      cellFeedViewHolder.vImageRoot.addView(sendingProgressView);
      cellFeedViewHolder.vSendingProgress = sendingProgressView;
    }

    return cellFeedViewHolder;
  }

  private void runEnterAnimation(View view, int position) {
    if (!animateItems || position >= ANIMATED_ITEMS_COUNT - 1) {
      return;
    }

    if (position > lastAnimatedPosition) {
      lastAnimatedPosition = position;
      view.setTranslationY(Utils.getScreenHeight(context));
      view.animate()
          .translationY(0)
          .setInterpolator(new DecelerateInterpolator(3.f))
          .setDuration(700)
          .start();
    }
  }

  @Override
  public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
    runEnterAnimation(viewHolder.itemView, position);
    final CellFeedViewHolder holder = (CellFeedViewHolder) viewHolder;
    if (getItemViewType(position) == VIEW_TYPE_DEFAULT) {
      bindDefaultFeedItem(position, holder);
    } else if (getItemViewType(position) == VIEW_TYPE_LOADER) {
      bindLoadingFeedItem(holder);
    }
  }

  private void bindDefaultFeedItem(int position, CellFeedViewHolder holder) {
    if (position % 2 == 0) {
      holder.ivFeedCenter.setImageResource(R.drawable.img_feed_center_1);
      holder.ivFeedBottom.setText("미르이즈 송년회");
    } else {
      holder.ivFeedCenter.setImageResource(R.drawable.img_feed_center_2);
      holder.ivFeedBottom.setText("미르이즈 전체회식");
    }
    updateLikesCounter(holder, false);
    updateHeartButton(holder, false);

    holder.btnComments.setTag(position);
    holder.btnMore.setTag(position);
    holder.ivFeedCenter.setTag(holder);
    holder.btnLike.setTag(holder);

    if (likeAnimations.containsKey(holder)) {
      likeAnimations.get(holder).cancel();
    }
    resetLikeAnimationState(holder);
  }

  private void bindLoadingFeedItem(final CellFeedViewHolder holder) {
    holder.ivFeedCenter.setImageResource(R.drawable.img_feed_center_1);
    holder.ivFeedBottom.setText("미르이즈 송년회");
    holder
        .vSendingProgress
        .getViewTreeObserver()
        .addOnPreDrawListener(
            new ViewTreeObserver.OnPreDrawListener() {
              @Override
              public boolean onPreDraw() {
                holder.vSendingProgress.getViewTreeObserver().removeOnPreDrawListener(this);
                holder.vSendingProgress.simulateProgress();
                return true;
              }
            });
    holder.vSendingProgress.setOnLoadingFinishedListener(
        new SendingProgressView.OnLoadingFinishedListener() {
          @Override
          public void onLoadingFinished() {
            holder
                .vSendingProgress
                .animate()
                .scaleY(0)
                .scaleX(0)
                .setDuration(200)
                .setStartDelay(100);
            holder
                .vProgressBg
                .animate()
                .alpha(0.f)
                .setDuration(200)
                .setStartDelay(100)
                .setListener(
                    new AnimatorListenerAdapter() {
                      @Override
                      public void onAnimationEnd(Animator animation) {
                        holder.vSendingProgress.setScaleX(1);
                        holder.vSendingProgress.setScaleY(1);
                        holder.vProgressBg.setAlpha(1);
                        showLoadingView = false;
                        notifyItemChanged(0);
                      }
                    })
                .start();
          }
        });
  }

  @Override
  public int getItemViewType(int position) {
    if (showLoadingView && position == 0) {
      return VIEW_TYPE_LOADER;
    } else {
      return VIEW_TYPE_DEFAULT;
    }
  }

  @Override
  public int getItemCount() {
    return itemsCount;
  }

  private void updateLikesCounter(CellFeedViewHolder holder, boolean animated) {
    int currentLikesCount = likesCount.get(holder.getPosition()) + 1;
    String likesCountText =
        context
            .getResources()
            .getQuantityString(R.plurals.likes_count, currentLikesCount, currentLikesCount);

    if (animated) {
      holder.tsLikesCounter.setText(likesCountText);
    } else {
      holder.tsLikesCounter.setCurrentText(likesCountText);
    }

    likesCount.put(holder.getPosition(), currentLikesCount);
  }

  private void updateHeartButton(final CellFeedViewHolder holder, boolean animated) {
    if (animated) {
      if (!likeAnimations.containsKey(holder)) {
        AnimatorSet animatorSet = new AnimatorSet();
        likeAnimations.put(holder, animatorSet);

        ObjectAnimator rotationAnim = ObjectAnimator.ofFloat(holder.btnLike, "rotation", 0f, 360f);
        rotationAnim.setDuration(300);
        rotationAnim.setInterpolator(ACCELERATE_INTERPOLATOR);

        ObjectAnimator bounceAnimX = ObjectAnimator.ofFloat(holder.btnLike, "scaleX", 0.2f, 1f);
        bounceAnimX.setDuration(300);
        bounceAnimX.setInterpolator(OVERSHOOT_INTERPOLATOR);

        ObjectAnimator bounceAnimY = ObjectAnimator.ofFloat(holder.btnLike, "scaleY", 0.2f, 1f);
        bounceAnimY.setDuration(300);
        bounceAnimY.setInterpolator(OVERSHOOT_INTERPOLATOR);
        bounceAnimY.addListener(
            new AnimatorListenerAdapter() {
              @Override
              public void onAnimationStart(Animator animation) {
                holder.btnLike.setImageResource(R.drawable.ic_heart_red);
              }
            });

        animatorSet.play(rotationAnim);
        animatorSet.play(bounceAnimX).with(bounceAnimY).after(rotationAnim);

        animatorSet.addListener(
            new AnimatorListenerAdapter() {
              @Override
              public void onAnimationEnd(Animator animation) {
                resetLikeAnimationState(holder);
              }
            });

        animatorSet.start();
      }
    } else {
      if (likedPositions.contains(holder.getPosition())) {
        holder.btnLike.setImageResource(R.drawable.ic_heart_red);
      } else {
        holder.btnLike.setImageResource(R.drawable.ic_heart_outline_grey);
      }
    }
  }

  @Override
  public void onClick(View view) {
    final int viewId = view.getId();
    if (viewId == R.id.btnComments) {
      if (onFeedItemClickListener != null) {
        onFeedItemClickListener.onCommentsClick(view, (Integer) view.getTag());
      }
    } else if (viewId == R.id.btnMore) {
      if (onFeedItemClickListener != null) {
        onFeedItemClickListener.onMoreClick(view, (Integer) view.getTag());
      }
    } else if (viewId == R.id.btnLike) {
      CellFeedViewHolder holder = (CellFeedViewHolder) view.getTag();
      if (!likedPositions.contains(holder.getPosition())) {
        likedPositions.add(holder.getPosition());
        updateLikesCounter(holder, true);
        updateHeartButton(holder, true);
        if (context instanceof MainActivity) {
          ((MainActivity) context).showLikedSnackbar();
        }
      }
    } else if (viewId == R.id.ivFeedCenter) {
      CellFeedViewHolder holder = (CellFeedViewHolder) view.getTag();
      if (!likedPositions.contains(holder.getPosition())) {
        likedPositions.add(holder.getPosition());
        updateLikesCounter(holder, true);
        animatePhotoLike(holder);
        updateHeartButton(holder, false);
        if (context instanceof MainActivity) {
          ((MainActivity) context).showLikedSnackbar();
        }
      }
    } else if (viewId == R.id.ivUserProfile) {
      if (onFeedItemClickListener != null) {
        onFeedItemClickListener.onProfileClick(view);
      }
    }
  }

  private void animatePhotoLike(final CellFeedViewHolder holder) {
    if (!likeAnimations.containsKey(holder)) {
      holder.vBgLike.setVisibility(View.VISIBLE);
      holder.ivLike.setVisibility(View.VISIBLE);

      holder.vBgLike.setScaleY(0.1f);
      holder.vBgLike.setScaleX(0.1f);
      holder.vBgLike.setAlpha(1f);
      holder.ivLike.setScaleY(0.1f);
      holder.ivLike.setScaleX(0.1f);

      AnimatorSet animatorSet = new AnimatorSet();
      likeAnimations.put(holder, animatorSet);

      ObjectAnimator bgScaleYAnim = ObjectAnimator.ofFloat(holder.vBgLike, "scaleY", 0.1f, 1f);
      bgScaleYAnim.setDuration(200);
      bgScaleYAnim.setInterpolator(DECCELERATE_INTERPOLATOR);
      ObjectAnimator bgScaleXAnim = ObjectAnimator.ofFloat(holder.vBgLike, "scaleX", 0.1f, 1f);
      bgScaleXAnim.setDuration(200);
      bgScaleXAnim.setInterpolator(DECCELERATE_INTERPOLATOR);
      ObjectAnimator bgAlphaAnim = ObjectAnimator.ofFloat(holder.vBgLike, "alpha", 1f, 0f);
      bgAlphaAnim.setDuration(200);
      bgAlphaAnim.setStartDelay(150);
      bgAlphaAnim.setInterpolator(DECCELERATE_INTERPOLATOR);

      ObjectAnimator imgScaleUpYAnim = ObjectAnimator.ofFloat(holder.ivLike, "scaleY", 0.1f, 1f);
      imgScaleUpYAnim.setDuration(300);
      imgScaleUpYAnim.setInterpolator(DECCELERATE_INTERPOLATOR);
      ObjectAnimator imgScaleUpXAnim = ObjectAnimator.ofFloat(holder.ivLike, "scaleX", 0.1f, 1f);
      imgScaleUpXAnim.setDuration(300);
      imgScaleUpXAnim.setInterpolator(DECCELERATE_INTERPOLATOR);

      ObjectAnimator imgScaleDownYAnim = ObjectAnimator.ofFloat(holder.ivLike, "scaleY", 1f, 0f);
      imgScaleDownYAnim.setDuration(300);
      imgScaleDownYAnim.setInterpolator(ACCELERATE_INTERPOLATOR);
      ObjectAnimator imgScaleDownXAnim = ObjectAnimator.ofFloat(holder.ivLike, "scaleX", 1f, 0f);
      imgScaleDownXAnim.setDuration(300);
      imgScaleDownXAnim.setInterpolator(ACCELERATE_INTERPOLATOR);

      animatorSet.playTogether(
          bgScaleYAnim, bgScaleXAnim, bgAlphaAnim, imgScaleUpYAnim, imgScaleUpXAnim);
      animatorSet.play(imgScaleDownYAnim).with(imgScaleDownXAnim).after(imgScaleUpYAnim);

      animatorSet.addListener(
          new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
              resetLikeAnimationState(holder);
            }
          });
      animatorSet.start();
    }
  }

  private void resetLikeAnimationState(CellFeedViewHolder holder) {
    likeAnimations.remove(holder);
    holder.vBgLike.setVisibility(View.GONE);
    holder.ivLike.setVisibility(View.GONE);
  }

  public void updateItems(boolean animated) {
    itemsCount = 10;
    animateItems = animated;
    fillLikesWithRandomValues();
    notifyDataSetChanged();
  }

  private void fillLikesWithRandomValues() {
    for (int i = 0; i < getItemCount(); i++) {
      likesCount.put(i, new Random().nextInt(100));
    }
  }

  public void setOnFeedItemClickListener(OnFeedItemClickListener onFeedItemClickListener) {
    this.onFeedItemClickListener = onFeedItemClickListener;
  }

  public void showLoadingView() {
    showLoadingView = true;
    notifyItemChanged(0);
  }

  public static class CellFeedViewHolder extends RecyclerView.ViewHolder {
    @InjectView(R.id.ivFeedCenter)
    ImageView ivFeedCenter;

    @InjectView(R.id.ivFeedBottom)
    TextView ivFeedBottom;

    @InjectView(R.id.btnComments)
    ImageButton btnComments;

    @InjectView(R.id.btnLike)
    ImageButton btnLike;

    @InjectView(R.id.btnMore)
    ImageButton btnMore;

    @InjectView(R.id.vBgLike)
    View vBgLike;

    @InjectView(R.id.ivLike)
    ImageView ivLike;

    @InjectView(R.id.tsLikesCounter)
    TextSwitcher tsLikesCounter;

    @InjectView(R.id.ivUserProfile)
    ImageView ivUserProfile;

    @InjectView(R.id.vImageRoot)
    FrameLayout vImageRoot;

    SendingProgressView vSendingProgress;
    View vProgressBg;

    public CellFeedViewHolder(View view) {
      super(view);
      ButterKnife.inject(this, view);
    }
  }

  public interface OnFeedItemClickListener {
    public void onCommentsClick(View v, int position);

    public void onMoreClick(View v, int position);

    public void onProfileClick(View v);
  }
}