不包含音乐播放代码。主要目的是其中的展开和收缩逻辑。
浮窗部分继承自
FloatingMagnetView
主要逻辑
public class FloatingMusicPlayerView extends FloatingMagnetView {
private int expandWidth = 0;
private boolean isExpand = false;
private boolean isLeftSide = true;
private ImageView image;
private ExpandFloatingMusicPlayerView expandPlayerView;
private final AnimatorSet animatorSet = new AnimatorSet();
private MusicControlCallback callback;
private final static int MARGIN = 13;
private final static int ORIGIN_WINDOW_SIZE_DP = 50;
private final static int EXPAND_WINDOW_HEIGHT_DP = 90;
private final static int EXPAND_WINDOW_WIDTH_DP = 280;
public FloatingMusicPlayerView(Context context, MusicControlCallback callback) {
this(context, null, callback);
}
public FloatingMusicPlayerView(Context context, AttributeSet attributeSet, MusicControlCallback callback) {
super(context, attributeSet);
this.callback = callback;
initViews();
}
private void initViews() {
setBackgroundColor(Color.TRANSPARENT);
image = new ImageView(getContext());
image.setImageResource(R.drawable.ic_music_view_not_playing);
image.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
FrameLayout.LayoutParams p = new LayoutParams(SizeUtils.dp2px(ORIGIN_WINDOW_SIZE_DP), SizeUtils.dp2px(ORIGIN_WINDOW_SIZE_DP));
p.gravity = Gravity.CENTER_VERTICAL;
addView(image, p);
initExpandView();
this.setMagnetViewListener(new MagnetViewListener() {
@Override
public void onRemove(FloatingMagnetView magnetView) {
}
@Override
public void onClick(FloatingMagnetView magnetView) {
if (!isExpand) {
transform();
}
}
});
animatorSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
updateSize();
moveToEdge();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
private void initExpandView() {
expandWidth = SizeUtils.dp2px(EXPAND_WINDOW_WIDTH_DP);
expandPlayerView = new ExpandFloatingMusicPlayerView(getContext(), callback);
FrameLayout.LayoutParams p = new LayoutParams(0, SizeUtils.dp2px(EXPAND_WINDOW_HEIGHT_DP));
p.gravity = Gravity.CENTER_VERTICAL;
expandPlayerView.setLayoutParams(p);
addView(expandPlayerView);
expandPlayerView.setAlpha(0);
}
public void setExpandWidth(float width) {
LayoutParams p = (LayoutParams) expandPlayerView.getLayoutParams();
p.width = (int) width;
expandPlayerView.setLayoutParams(p);
if (isLeftSide) {
setX(MARGIN);
} else {
setX(ScreenUtils.getScreenWidth() - p.width - MARGIN);
}
}
private void transform() {
if (isExpand) {
collapse();
removeFillZone();
} else {
expand();
setFillZone();
}
}
private void collapse() {
if (!isExpand) {
return;
}
isExpand = false;
isLeftSide = isNearestLeft();
final ObjectAnimator alphaAnimation = ObjectAnimator.ofFloat(image, "alpha", 0, 1F);
final ObjectAnimator collapseAnim = ObjectAnimator.ofFloat(this, "expandWidth", expandWidth, SizeUtils.dp2px(ORIGIN_WINDOW_SIZE_DP));
final ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(expandPlayerView, "alpha", 1F, 0F);
animatorSet.playTogether(alphaAnimation, collapseAnim, alphaAnim);
animatorSet.start();
}
private void expand() {
if (isExpand) {
return;
}
isExpand = true;
isLeftSide = isNearestLeft();
final ObjectAnimator alphaAnimation = ObjectAnimator.ofFloat(image, "alpha", 1F, 0);
final ObjectAnimator expandAnim = ObjectAnimator.ofFloat(this, "expandWidth", SizeUtils.dp2px(ORIGIN_WINDOW_SIZE_DP), expandWidth);
final ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(expandPlayerView, "alpha", 0F, 1F);
animatorSet.playTogether(alphaAnimation, expandAnim, alphaAnim);
animatorSet.start();
}
public void destroy() {
animatorSet.removeAllListeners();
animatorSet.cancel();
}
public void setPlayingView() {
if (!ObjectUtils.isEmpty(image)) {
WGImageLoader.displayImage(GIF_URL, image);
image.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
}
expandPlayerView.setButtonPause();
}
public void setNotPlayingView() {
if (!ObjectUtils.isEmpty(image)) {
image.setImageResource(R.drawable.ic_music_view_not_playing);
image.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
}
expandPlayerView.setButtonPlay();
}
public void setIcon(@NonNull String url) {
expandPlayerView.setIcon(url);
}
public void setTitle(@NonNull String title) {
expandPlayerView.setTitle(title);
}
public void setTotalTime(@NonNull long duration) {
expandPlayerView.setTotalTime(duration);
}
public void setCurTime(@NonNull long progress) {
expandPlayerView.setCurTime(progress);
}
//
private Activity getTopActivity() {
try {
Activity activity = ActivityStackManager.getInstance().getTopActivity();
if (activity == null) {
activity = ActivityUtils.getTopActivity();
}
return activity;
} catch (Exception e) {
TLog.printStackTrace(e);
}
return null;
}
private View fillView;
private void setFillZone() {
Activity activity = getTopActivity();
if (ObjectUtils.isEmpty(activity)) {
return;
}
FrameLayout baseView = activity.getWindow().getDecorView().findViewById(android.R.id.content);
fillView = new View(getContext());
FrameLayout.LayoutParams params = new LayoutParams(ScreenUtils.getScreenWidth(), ScreenUtils.getScreenHeight());
fillView.setLayoutParams(params);
fillView.setBackgroundColor(Color.TRANSPARENT);
fillView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
transform();
return false;
}
});
baseView.addView(fillView, 1);
}
public void removeFillZone() {
Activity activity = getTopActivity();
if (ObjectUtils.isEmpty(activity)) {
return;
}
if (!ObjectUtils.isEmpty(fillView)) {
FrameLayout baseView = activity.getWindow().getDecorView().findViewById(android.R.id.content);
fillView.setOnTouchListener(null);
baseView.removeView(fillView);
fillView = null;
}
}
}
展开界面
public class ExpandFloatingMusicPlayerView extends ConstraintLayout {
private MusicControlCallback callback;
public ExpandFloatingMusicPlayerView(Context context, MusicControlCallback callback) {
super(context);
this.callback = callback;
init();
}
public ExpandFloatingMusicPlayerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ExpandFloatingMusicPlayerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private void init() {
View.inflate(getContext(), R.layout.view_floating_music_player_expand_view, this);
//设置跑马灯
findViewById(R.id.music_view_title).setSelected(true);
//播放
findViewById(R.id.music_view_play).setOnClickListener(new SafeClickListener() {
@Override
protected void onClicked(View v) {
if (ObjectUtils.isEmpty(callback)) {
return;
}
if (callback.getState() == MusicPlayerState.STATE_NONE || callback.getState() == MusicPlayerState.STATE_STOPPED || callback.getState() == MusicPlayerState.STATE_PAUSED) {
callback.play();
} else if (callback.getState() == MusicPlayerState.STATE_PLAYING) {
callback.pause();
} else {
callback.next();
}
}
});
//下一首
findViewById(R.id.music_view_next).setOnClickListener(new SafeClickListener() {
@Override
protected void onClicked(View v) {
if (ObjectUtils.isEmpty(callback)) {
return;
}
callback.next();
((ImageView) findViewById(R.id.music_view_play)).setImageResource(R.drawable.ic_music_expand_view_pause);
}
});
//关闭
findViewById(R.id.music_view_close).setOnClickListener(new SafeClickListener() {
@Override
protected void onClicked(View v) {
if (!ObjectUtils.isEmpty(callback)) {
callback.stop();
}
}
});
}
public void setButtonPlay() {
((ImageView) findViewById(R.id.music_view_play)).setImageResource(R.drawable.ic_music_expand_view_play);
}
public void setButtonPause() {
((ImageView) findViewById(R.id.music_view_play)).setImageResource(R.drawable.ic_music_expand_view_pause);
}
public void setIcon(@NonNull String url) {
WGImageLoader.displayImage(url, findViewById(R.id.music_view_icon));
}
public void setTitle(@NonNull String title) {
((TextView) findViewById(R.id.music_view_title)).setText(title);
}
public void setTotalTime(@NonNull long duration) {
((TextView) findViewById(R.id.music_view_total_time)).setText(DateUtils.formatElapsedTime((duration / 1000)));
}
public void setCurTime(@NonNull long progress) {
((TextView) findViewById(R.id.music_view_cur_time)).setText(DateUtils.formatElapsedTime((progress / 1000)));
}
}