package io.hefuyi.listener.ui.fragment;
import android.animation.ObjectAnimator;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ScaleDrawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.graphics.Palette;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupMenu;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.appthemeengine.ATE;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
import net.steamcrafted.materialiconlib.MaterialIconView;
import java.io.File;
import java.security.InvalidParameterException;
import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.hefuyi.listener.ListenerApp;
import io.hefuyi.listener.MusicPlayer;
import io.hefuyi.listener.R;
import io.hefuyi.listener.RxBus;
import io.hefuyi.listener.event.FavourateSongEvent;
import io.hefuyi.listener.event.MetaChangedEvent;
import io.hefuyi.listener.injector.component.ApplicationComponent;
import io.hefuyi.listener.injector.component.DaggerQuickControlsComponent;
import io.hefuyi.listener.injector.component.QuickControlsComponent;
import io.hefuyi.listener.injector.module.ActivityModule;
import io.hefuyi.listener.injector.module.QuickControlsModule;
import io.hefuyi.listener.listener.PaletteColorChangeListener;
import io.hefuyi.listener.mvp.contract.QuickControlsContract;
import io.hefuyi.listener.provider.FavoriteSong;
import io.hefuyi.listener.ui.dialogs.PlayqueueDialog;
import io.hefuyi.listener.util.ATEUtil;
import io.hefuyi.listener.util.ColorUtil;
import io.hefuyi.listener.util.DensityUtil;
import io.hefuyi.listener.util.ListenerUtil;
import io.hefuyi.listener.util.NavigationUtil;
import io.hefuyi.listener.util.ScrimUtil;
import io.hefuyi.listener.widget.ForegroundImageView;
import io.hefuyi.listener.widget.LyricView;
import io.hefuyi.listener.widget.PlayPauseView;
import io.hefuyi.listener.widget.timely.TimelyView;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
/**
* A simple {@link Fragment} subclass.
*/
public class QuickControlsFragment extends Fragment implements QuickControlsContract.View {
@Inject
QuickControlsContract.Presenter mPresenter;
@BindView(R.id.topContainer)
public View topContainer;
@BindView(R.id.song_progress_normal)
ProgressBar mProgress;
@BindView(R.id.play_pause)
PlayPauseView mPlayPauseView;
@BindView(R.id.title)
TextView mTitle;
@BindView(R.id.artist)
TextView mArtist;
@BindView(R.id.album_art)
ForegroundImageView mAlbumArt;
@BindView(R.id.previous)
MaterialIconView previous;
@BindView(R.id.next)
MaterialIconView next;
@BindView(R.id.heart)
MaterialIconView favorite;
@BindView(R.id.ic_play_queue)
MaterialIconView iconPlayQueue;
@BindView(R.id.lyric_view)
LyricView mLyricView;
@BindView(R.id.popup_menu)
ImageView popupMenu;
@BindView(R.id.seek_song_touch)
SeekBar mSeekBar;
@BindView(R.id.timelyView11)
TimelyView timelyView11;
@BindView(R.id.timelyView12)
TimelyView timelyView12;
@BindView(R.id.timelyView13)
TimelyView timelyView13;
@BindView(R.id.timelyView14)
TimelyView timelyView14;
@BindView(R.id.timelyView15)
TimelyView timelyView15;
@BindView(R.id.hour_colon)
TextView hourColon;
@BindView(R.id.minute_colon)
TextView minuteColon;
@BindView(R.id.song_elapsedtime)
LinearLayout songElapsedTime;
private int blackWhiteColor;
private Handler mElapsedTimeHandler;
private int[] timeArr = new int[]{0, 0, 0, 0, 0};
private static PaletteColorChangeListener sListener;
private PlayqueueDialog bottomDialogFragment;
private SlidingUpPanelLayout mSlidingUpPanelLayout;
private Palette.Swatch mSwatch;
private boolean mIsFavorite = false;
private Runnable mUpdateProgress = new Runnable() {
@Override
public void run() {
long position = MusicPlayer.position();
mProgress.setProgress((int) position);
mSeekBar.setProgress((int) position);
mLyricView.setCurrentTimeMillis(position);
if (MusicPlayer.isPlaying()) {
mProgress.postDelayed(mUpdateProgress, 50);
} else mProgress.removeCallbacks(this);
}
};
private Runnable mUpdateElapsedTime = new Runnable() {
@Override
public void run() {
if (getActivity() != null) {
String time = ListenerUtil.makeShortTimeString(getActivity(), mSeekBar.getProgress() / 1000);
if (time.length() < 5) {
timelyView11.setVisibility(View.GONE);
timelyView12.setVisibility(View.GONE);
hourColon.setVisibility(View.GONE);
tv13(time.charAt(0) - '0');
tv14(time.charAt(2) - '0');
tv15(time.charAt(3) - '0');
} else if (time.length() == 5) {
timelyView12.setVisibility(View.VISIBLE);
tv12(time.charAt(0) - '0');
tv13(time.charAt(1) - '0');
tv14(time.charAt(3) - '0');
tv15(time.charAt(4) - '0');
} else {
timelyView11.setVisibility(View.VISIBLE);
hourColon.setVisibility(View.VISIBLE);
tv11(time.charAt(0) - '0');
tv12(time.charAt(2) - '0');
tv13(time.charAt(3) - '0');
tv14(time.charAt(5) - '0');
tv15(time.charAt(6) - '0');
}
mElapsedTimeHandler.postDelayed(this, 600);
}
}
};
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
injectDependences();
mPresenter.attachView(this);
}
private void injectDependences() {
ApplicationComponent applicationComponent = ((ListenerApp) getActivity().getApplication())
.getApplicationComponent();
QuickControlsComponent quickControlsComponent = DaggerQuickControlsComponent.builder()
.applicationComponent(applicationComponent)
.activityModule(new ActivityModule(getActivity()))
.quickControlsModule(new QuickControlsModule())
.build();
quickControlsComponent.inject(this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_playback_controls, container, false);
ButterKnife.bind(this, rootView);
return rootView;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ATE.apply(this, ATEUtil.getATEKey(getActivity()));
mSlidingUpPanelLayout = (SlidingUpPanelLayout) view.getParent().getParent();
setUpPopupMenu(popupMenu);
mLyricView.setLineSpace(15.0f);
mLyricView.setTextSize(17.0f);
mLyricView.setPlayable(false);
mLyricView.setTranslationY(DensityUtil.getScreenWidth(getActivity()) + DensityUtil.dip2px(getActivity(), 120));
mLyricView.setOnPlayerClickListener(new LyricView.OnPlayerClickListener() {
@Override
public void onPlayerClicked(long progress, String content) {
MusicPlayer.seek((long) progress);
if (!MusicPlayer.isPlaying()) {
mPresenter.onPlayPauseClick();
}
}
});
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) mProgress.getLayoutParams();
mProgress.measure(0, 0);
layoutParams.setMargins(0, -(mProgress.getMeasuredHeight() / 2), 0, 0);
mProgress.setLayoutParams(layoutParams);
ScaleDrawable scaleDrawable = (ScaleDrawable) ((LayerDrawable) mProgress.getProgressDrawable()).findDrawableByLayerId(R.id.progress);
GradientDrawable gradientDrawable = (GradientDrawable) scaleDrawable.getDrawable();
int colorAccent = ATEUtil.getThemeAccentColor(getActivity());
gradientDrawable.setColors(new int[]{colorAccent, colorAccent, colorAccent});
//清除默认的左右边距
mSeekBar.setPadding(0, DensityUtil.dip2px(getContext(), 36), 0, 0);
mSeekBar.setSecondaryProgress(mSeekBar.getMax());
songElapsedTime.setY((DensityUtil.getScreenWidth(getContext()) - songElapsedTime.getHeight()) / 2);
setUpTimelyView();
setSeekBarListener();
if (mPlayPauseView != null) {
if (MusicPlayer.isPlaying())
mPlayPauseView.Play();
else mPlayPauseView.Pause();
}
subscribeFavourateSongEvent();
subscribeMetaChangedEvent();
}
@Override
public void onDestroyView() {
super.onDestroyView();
mPresenter.unsubscribe();
sListener = null;
RxBus.getInstance().unSubscribe(this);
}
@Override
public void showLyric(File file) {
if (file == null) {
mLyricView.reset("暂无歌词");
} else {
mLyricView.setLyricFile(file, "UTF-8");
}
}
@Override
public void setPlayPauseButton(boolean isPlaying) {
if (isPlaying) {
mPlayPauseView.Play();
} else {
mPlayPauseView.Pause();
}
}
private void setUpTimelyView() {
if (timelyView11 != null) {
String time = ListenerUtil.makeShortTimeString(getActivity(), MusicPlayer.position() / 1000);
if (time.length() < 5) {
timelyView11.setVisibility(View.GONE);
timelyView12.setVisibility(View.GONE);
hourColon.setVisibility(View.GONE);
changeDigit(timelyView13, time.charAt(0) - '0');
changeDigit(timelyView14, time.charAt(2) - '0');
changeDigit(timelyView15, time.charAt(3) - '0');
} else if (time.length() == 5) {
timelyView12.setVisibility(View.VISIBLE);
changeDigit(timelyView12, time.charAt(0) - '0');
changeDigit(timelyView13, time.charAt(1) - '0');
changeDigit(timelyView14, time.charAt(3) - '0');
changeDigit(timelyView15, time.charAt(4) - '0');
} else {
timelyView11.setVisibility(View.VISIBLE);
hourColon.setVisibility(View.VISIBLE);
changeDigit(timelyView11, time.charAt(0) - '0');
changeDigit(timelyView12, time.charAt(2) - '0');
changeDigit(timelyView13, time.charAt(3) - '0');
changeDigit(timelyView14, time.charAt(5) - '0');
changeDigit(timelyView15, time.charAt(6) - '0');
}
}
if (timelyView11 != null) {
mElapsedTimeHandler = new Handler();
mElapsedTimeHandler.postDelayed(mUpdateElapsedTime, 600);
}
}
private void setUpPopupMenu(ImageView popupMenu) {
popupMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final PopupMenu menu = new PopupMenu(getContext(), v);
menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.popup_song_goto_album:
if (mSlidingUpPanelLayout != null) {
mSlidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
NavigationUtil.navigateToAlbum(getActivity(), MusicPlayer.getCurrentAlbumId(),
MusicPlayer.getAlbumName(), null);
}
break;
case R.id.popup_song_goto_artist:
if (mSlidingUpPanelLayout != null) {
mSlidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
NavigationUtil.navigateToAlbum(getActivity(), MusicPlayer.getCurrentArtistId(),
MusicPlayer.getArtistName(), null);
}
break;
case R.id.popup_song_addto_playlist:
ListenerUtil.showAddPlaylistDialog(getActivity(), new long[]{MusicPlayer.getCurrentAudioId()});
break;
case R.id.popup_song_delete:
long[] deleteIds = {MusicPlayer.getCurrentAudioId()};
ListenerUtil.showDeleteDialog(getContext(), MusicPlayer.getTrackName(), deleteIds,
new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
}
});
break;
}
return false;
}
});
menu.inflate(R.menu.menu_now_playing);
menu.show();
}
});
}
private void setSeekBarListener() {
if (mSeekBar != null)
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
if (songElapsedTime.getVisibility() == View.GONE) {
songElapsedTime.setVisibility(View.VISIBLE);
}
mProgress.removeCallbacks(mUpdateProgress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
songElapsedTime.setVisibility(View.GONE);
MusicPlayer.seek((long) seekBar.getProgress());
mProgress.postDelayed(mUpdateProgress, 10);
}
});
}
/**
* 返回暂停播放按钮的状态
*
* @return true表示按钮为待暂定状态, false表示按钮为待播放状态
*/
@Override
public boolean getPlayPauseStatus() {
return mPlayPauseView.isPlay();
}
@Override
public void startUpdateProgress() {
mProgress.postDelayed(mUpdateProgress, 10);
}
@Override
public void setProgressMax(int max) {
mProgress.setMax(max);
mSeekBar.setMax(max);
}
@Override
public void setAlbumArt(Bitmap albumArt) {
mAlbumArt.setImageBitmap(albumArt);
}
@Override
public void setAlbumArt(Drawable albumArt) {
mAlbumArt.setImageDrawable(albumArt);
if (TextUtils.isEmpty(MusicPlayer.getTrackName()) && TextUtils.isEmpty(MusicPlayer.getArtistName())) {
mAlbumArt.setForeground(null);
TypedValue paletteColor = new TypedValue();
getContext().getTheme().resolveAttribute(R.attr.album_default_palette_color, paletteColor, true);
topContainer.setBackgroundColor(paletteColor.data);
mPlayPauseView.setDrawableColor(ATEUtil.getThemeAccentColor(getActivity()));
mPlayPauseView.setEnabled(false);
next.setEnabled(false);
next.setColor(ATEUtil.getThemeAccentColor(getContext()));
if (sListener != null) {
sListener.onPaletteColorChange(paletteColor.data, ATEUtil.getThemeAccentColor(getActivity()));
}
}
}
@Override
public void setTitle(String title) {
mTitle.setText(title);
}
@Override
public void setArtist(String artist) {
mArtist.setText(artist);
}
@Override
public void setPalette(Palette palette) {
mSwatch = ColorUtil.getMostPopulousSwatch(palette);
int paletteColor;
if (mSwatch != null) {
paletteColor = mSwatch.getRgb();
int artistColor = mSwatch.getTitleTextColor();
mTitle.setTextColor(ColorUtil.getOpaqueColor(artistColor));
mArtist.setTextColor(artistColor);
} else {
mSwatch = palette.getMutedSwatch() == null ? palette.getVibrantSwatch() : palette.getMutedSwatch();
if (mSwatch != null) {
paletteColor = mSwatch.getRgb();
int artistColor = mSwatch.getTitleTextColor();
mTitle.setTextColor(ColorUtil.getOpaqueColor(artistColor));
mArtist.setTextColor(artistColor);
} else {
paletteColor = ATEUtil.getThemeAlbumDefaultPaletteColor(getContext());
mTitle.setTextColor(getResources().getColor(android.R.color.primary_text_light));
mArtist.setTextColor(getResources().getColor(android.R.color.secondary_text_light));
}
}
//set icon color
blackWhiteColor = ColorUtil.getBlackWhiteColor(paletteColor);
topContainer.setBackgroundColor(paletteColor);
if (bottomDialogFragment != null && mSwatch != null) {
bottomDialogFragment.setPaletteSwatch(mSwatch);
}
mLyricView.setHighLightTextColor(blackWhiteColor);
mLyricView.setDefaultColor(blackWhiteColor);
mLyricView.setTouchable(false);
mLyricView.setHintColor(blackWhiteColor);
mPlayPauseView.setDrawableColor(blackWhiteColor);
mPlayPauseView.setCircleColor(blackWhiteColor);
mPlayPauseView.setCircleAlpah(0);
mPlayPauseView.setEnabled(true);
next.setEnabled(true);
next.setColor(blackWhiteColor);
previous.setColor(blackWhiteColor);
next.setColor(blackWhiteColor);
iconPlayQueue.setColor(blackWhiteColor);
//set timely color
setTimelyColor(blackWhiteColor);
//set seekbar progressdrawable
ScaleDrawable scaleDrawable = (ScaleDrawable) ((LayerDrawable) mSeekBar.getProgressDrawable()).findDrawableByLayerId(R.id.progress);
GradientDrawable gradientDrawable = (GradientDrawable) scaleDrawable.getDrawable();
gradientDrawable.setColors(new int[]{blackWhiteColor, blackWhiteColor, blackWhiteColor});
mIsFavorite = FavoriteSong.getInstance(getContext()).isFavorite(MusicPlayer.getCurrentAudioId());
if (mIsFavorite) {
favorite.setColor(Color.parseColor("#E97767"));
} else {
favorite.setColor(blackWhiteColor);
}
//set albumart foreground
if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
mAlbumArt.setForeground(
ScrimUtil.makeCubicGradientScrimDrawable(
paletteColor, //颜色
8, //渐变层数
Gravity.CENTER_HORIZONTAL)); //起始方向
}
if (sListener != null) {
sListener.onPaletteColorChange(paletteColor, blackWhiteColor);
}
}
@OnClick(R.id.upIndicator)
public void onUpIndicatorClick() {
if (mSlidingUpPanelLayout != null) {
mSlidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
}
}
@OnClick(R.id.play_pause)
public void onPlayPauseClick() {
mPresenter.onPlayPauseClick();
}
@OnClick(R.id.next)
public void onNextClick() {
mPresenter.onNextClick();
}
@OnClick(R.id.previous)
public void onPreviousClick() {
mPresenter.onPreviousClick();
}
@OnClick(R.id.ic_play_queue)
public void onPlayQueueClick() {
FragmentManager fm = getActivity().getSupportFragmentManager();
if (bottomDialogFragment == null) {
bottomDialogFragment = new PlayqueueDialog();
}
bottomDialogFragment.show(fm, "fragment_bottom_dialog");
if (mSwatch != null) {
bottomDialogFragment.setPaletteSwatch(mSwatch);
}
}
@OnClick(R.id.heart)
public void onFavoriteClick() {
if (mIsFavorite) {
int num = FavoriteSong.getInstance(getContext()).removeFavoriteSong(new long[]{MusicPlayer.getCurrentAudioId()});
if (num == 1) {
favorite.setColor(blackWhiteColor);
mIsFavorite = false;
RxBus.getInstance().post(new FavourateSongEvent());
Toast.makeText(getContext(), R.string.remove_favorite_success, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), R.string.remove_favorite_fail, Toast.LENGTH_SHORT).show();
}
} else {
int num = FavoriteSong.getInstance(getContext()).addFavoriteSong(new long[]{MusicPlayer.getCurrentAudioId()});
if (num == 1) {
favorite.setColor(Color.parseColor("#E97767"));
mIsFavorite = true;
RxBus.getInstance().post(new FavourateSongEvent());
Toast.makeText(getContext(), R.string.add_favorite_success, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), R.string.add_favorite_fail, Toast.LENGTH_SHORT).show();
}
}
}
private void subscribeFavourateSongEvent() {
Subscription subscription = RxBus.getInstance()
.toObservable(FavourateSongEvent.class)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<FavourateSongEvent>() {
@Override
public void call(FavourateSongEvent event) {
mIsFavorite = FavoriteSong.getInstance(getContext()).isFavorite(MusicPlayer.getCurrentAudioId());
if (mIsFavorite) {
favorite.setColor(Color.parseColor("#E97767"));
} else {
favorite.setColor(blackWhiteColor);
}
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
}
});
RxBus.getInstance().addSubscription(this, subscription);
}
private void subscribeMetaChangedEvent() {
Subscription subscription = RxBus.getInstance()
.toObservable(MetaChangedEvent.class)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<MetaChangedEvent>() {
@Override
public void call(MetaChangedEvent event) {
mPresenter.updateNowPlayingCard();
mPresenter.loadLyric();
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
}
});
RxBus.getInstance().addSubscription(this, subscription);
}
public static void setPaletteColorChangeListener(PaletteColorChangeListener paletteColorChangeListener) {
sListener = paletteColorChangeListener;
}
private void changeDigit(TimelyView tv, int end) {
ObjectAnimator obja = tv.animate(end);
obja.setDuration(400);
obja.start();
}
private void setTimelyColor(@ColorInt int color) {
hourColon.setTextColor(color);
minuteColon.setTextColor(color);
timelyView11.setTextColor(color);
timelyView12.setTextColor(color);
timelyView13.setTextColor(color);
timelyView14.setTextColor(color);
timelyView15.setTextColor(color);
}
private void changeDigit(TimelyView tv, int start, int end) {
try {
ObjectAnimator obja = tv.animate(start, end);
obja.setDuration(400);
obja.start();
} catch (InvalidParameterException e) {
e.printStackTrace();
}
}
private void tv11(int a) {
if (a != timeArr[0]) {
changeDigit(timelyView11, timeArr[0], a);
timeArr[0] = a;
}
}
private void tv12(int a) {
if (a != timeArr[1]) {
changeDigit(timelyView12, timeArr[1], a);
timeArr[1] = a;
}
}
private void tv13(int a) {
if (a != timeArr[2]) {
changeDigit(timelyView13, timeArr[2], a);
timeArr[2] = a;
}
}
private void tv14(int a) {
if (a != timeArr[3]) {
changeDigit(timelyView14, timeArr[3], a);
timeArr[3] = a;
}
}
private void tv15(int a) {
if (a != timeArr[4]) {
changeDigit(timelyView15, timeArr[4], a);
timeArr[4] = a;
}
}
}