package com.hannesdorfmann.mosby3.sample.mail.details; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.annotation.TargetApi; import android.os.Build; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.ActivityOptionsCompat; import android.transition.TransitionInflater; import android.transition.TransitionSet; import android.view.View; import android.view.ViewTreeObserver; import android.view.Window; import android.view.animation.OvershootInterpolator; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import com.hannesdorfmann.fragmentargs.annotation.Arg; import com.hannesdorfmann.mosby3.sample.mail.IntentStarter; import com.hannesdorfmann.mosby3.sample.mail.MailApplication; import com.hannesdorfmann.mosby3.sample.mail.R; import com.hannesdorfmann.mosby3.sample.mail.base.view.AuthFragment; import com.hannesdorfmann.mosby3.sample.mail.base.view.viewstate.AuthParcelableDataViewState; import com.hannesdorfmann.mosby3.sample.mail.base.view.viewstate.AuthViewState; import com.hannesdorfmann.mosby3.sample.mail.label.LabelLayout; import com.hannesdorfmann.mosby3.sample.mail.model.mail.Mail; import com.hannesdorfmann.mosby3.sample.mail.ui.transition.ExcludedExplodeTransition; import com.hannesdorfmann.mosby3.sample.mail.ui.transition.ExplodeFadeEnterTransition; import com.hannesdorfmann.mosby3.sample.mail.ui.transition.TextSizeEnterSharedElementCallback; import com.hannesdorfmann.mosby3.sample.mail.ui.transition.TextSizeTransition; import com.hannesdorfmann.mosby3.sample.mail.ui.view.StarView; import com.melnykov.fab.FloatingActionButton; import com.melnykov.fab.ObservableScrollView; import java.text.Format; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import javax.inject.Inject; import butterknife.BindView; import butterknife.OnClick; /** * @author Hannes Dorfmann */ public class DetailsFragment extends AuthFragment<TextView, Mail, DetailsView, DetailsPresenter> implements DetailsView, View.OnClickListener { @Arg int mailId; @Arg String subject; @Arg int senderProfilePic; @Arg String senderName; @Arg String senderEmail; @Arg long date; @Arg boolean starred; @Inject IntentStarter intentStarter; @BindView(R.id.senderPic) ImageView senderImageView; @BindView(R.id.subject) TextView subjectView; @BindView(R.id.date) TextView dateView; @BindView(R.id.starButton) StarView starView; @BindView(R.id.replay) FloatingActionButton replayView; @BindView(R.id.senderName) TextView senderNameView; @BindView(R.id.senderMail) TextView senderMailView; @BindView(R.id.separatorLine) View separatorLine; @BindView(R.id.label) LabelLayout labelView; @BindView(R.id.scrollView) ObservableScrollView scrollView; private DetailsComponent detailsComponent; Format format = new SimpleDateFormat("d. MMM", Locale.getDefault()); // The loaded data private Mail mail; @Override public AuthViewState<Mail, DetailsView> createViewState() { return new AuthParcelableDataViewState<>(); } @Override protected int getLayoutRes() { return R.layout.fragment_mail_details; } @TargetApi(21) @Override public void onViewCreated(final View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); replayView.attachToScrollView(scrollView); starView.setOnClickListener(this); subjectView.setText(subject); senderImageView.setImageResource(senderProfilePic); senderNameView.setText(senderName); senderMailView.setText(senderEmail); starView.setStarred(starred); dateView.setText(format.format(new Date(date))); senderImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mail != null) { intentStarter.showProfile(getActivity(), mail.getSender()); } } }); // Shared element animation if (Build.VERSION.SDK_INT >= 21 && !isTablet()) { initTransitions(); view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { view.getViewTreeObserver().removeOnPreDrawListener(this); getActivity().startPostponedEnterTransition(); return true; } }); } } @TargetApi(21) private void initTransitions() { Window window = getActivity().getWindow(); window.setEnterTransition( new ExplodeFadeEnterTransition(senderNameView, senderMailView, separatorLine)); window.setExitTransition(new ExcludedExplodeTransition()); window.setReenterTransition(new ExcludedExplodeTransition()); window.setReturnTransition(new ExcludedExplodeTransition()); TransitionSet textSizeSet = new TransitionSet(); textSizeSet.addTransition( TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.move)); TextSizeTransition textSizeTransition = new TextSizeTransition(); textSizeTransition.addTarget(R.id.subject); textSizeTransition.addTarget(getString(R.string.shared_mail_subject)); textSizeSet.addTransition(textSizeTransition); textSizeSet.setOrdering(TransitionSet.ORDERING_TOGETHER); window.setSharedElementEnterTransition(textSizeSet); getActivity().setEnterSharedElementCallback( new TextSizeEnterSharedElementCallback(getActivity())); } private boolean isTablet() { return getResources().getBoolean(R.bool.tablet); } @Override public Mail getData() { return mail; } @Override public DetailsPresenter createPresenter() { return detailsComponent.presenter(); } @Override public void setData(Mail data) { this.mail = data; senderImageView.setImageResource(data.getSender().getImageRes()); senderNameView.setText(data.getSender().getName()); senderMailView.setText(data.getSender().getEmail()); subjectView.setText(data.getSubject()); contentView.setText(data.getText() + data.getText() + data.getText() + data.getText()); starView.setStarred(data.isStarred()); dateView.setText(format.format(data.getDate())); labelView.setMail(data); labelView.setVisibility(View.VISIBLE); replayView.setVisibility(View.VISIBLE); // Animate only if not restoring if (!isRestoringViewState()) { labelView.setAlpha(0f); labelView.animate().alpha(1f).setDuration(150).start(); PropertyValuesHolder holderX = PropertyValuesHolder.ofFloat("scaleX", 0, 1); PropertyValuesHolder holderY = PropertyValuesHolder.ofFloat("scaleY", 0, 1); ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(replayView, holderX, holderY); animator.setInterpolator(new OvershootInterpolator()); animator.start(); } } @Override public void loadData(boolean pullToRefresh) { presenter.loadMail(mailId); } public int getMailId() { return mailId; } @Override public void onClick(View v) { if (mail != null) { presenter.starMail(mail, !mail.isStarred()); } else { Toast.makeText(getActivity(), R.string.error_wait_mail_loaded, Toast.LENGTH_SHORT).show(); } } @Override public void markMailAsStared(int mailId) { if (mail.getId() == mailId) { mail.setStarred(true); starView.setStarred(true); } } @Override public void markMailAsUnstared(int mailId) { if (mail.getId() == mailId) { mail.setStarred(false); starView.setStarred(false); } } private void showStarErrorToast(int messageRes, Mail mail) { Toast.makeText(getActivity(), String.format(getString(messageRes), mail.getSender().getName()), Toast.LENGTH_SHORT).show(); } @Override public void showStaringFailed(Mail mail) { showStarErrorToast(R.string.error_staring_mail, mail); } @Override public void showUnstaringFailed(Mail mail) { showStarErrorToast(R.string.error_unstaring_mail, mail); } @OnClick(R.id.replay) public void onReplayClicked() { ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(), replayView, getString(R.string.shared_write_action)); intentStarter.showWriteMail(getActivity(), mail, options.toBundle()); } @Override public void markMailAsRead(Mail mail, boolean read) { // TODO: currently there is no UI component that shows if that mail has been read or not } @Override protected void injectDependencies() { detailsComponent = DaggerDetailsComponent.builder().mailAppComponent(MailApplication.getMailComponents()).build(); detailsComponent.inject(this); } }