Like Netease cloud music player (Disk turns, virtual background, etc.), Netease music player

Source: Internet
Author: User

Like Netease cloud music player (Disk turns, virtual background, etc.), Netease music player

Let's look at the results first. CSDN's git is always not moved, so I don't know why.


Main ideas:

1. In addition to the start/stop, first and next icons, you can see a ViewGroup with a circular cover, a black circle disk, a record, and a Gaussian Blur background image.

2. comment out the effect of disk rotation together. The current solution is not the best. If you want to implement it, you can combine the circular cover and disk into a picture (preferably in the CicicleImageView ). Give a rotation animation. For two animations and two views, the frame frequency is not that high.

3. commented out the animation effect of the gradient during the previous and next switching. The source image ranges from 1 to 0, and the new image ranges from 0 to 1. An error is reported on the simulator, mainly because an error is reported when the background of the ImageView is changed. I do not know the specific reason. It seems that the underlying layer has a wild pointer.

You are welcome to optimize and modify the above questions. If you change the questions, you must contact me.

The following is the code structure:



CircleImageView: generate a circular image

GaussianBlurUtil: Gaussian blur

MusicPlayView: Player View

MainActivity: main control class


There are two la s, one is the master, and the other is the View of the player. You can see the idea of the master.

One player and three buttons

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"     >    <include layout="@layout/media_play_view"        android:id="@+id/layout_media_play_view"             />         <Button            android:id="@+id/btn_play_pause"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/fm_btn_play"            android:layout_centerInParent="true"/><Button            android:id="@+id/btn_previous"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/bg_play_previous"            android:layout_centerVertical="true"            android:layout_alignParentLeft="true"/>                <Button            android:id="@+id/btn_next"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/bg_play_next"            android:layout_centerVertical="true"            android:layout_alignParentRight="true"/></RelativeLayout>

Player source code, which looks at a lot of code.

/*** Code Description: 1. comment out the effect of disk rotation together. The current solution is not the best. If you want to implement it, you can combine the circular cover and disk into a picture (preferably in the CicicleImageView ). Give a rotation animation. Two animations and two views, the frame frequency is not that high * 2. comment out the animation effect of the gradient when the previous and next switches. The source image ranges from 1 to 0, and the new image ranges from 0 to 1. An error is reported on the simulator, mainly because an error is reported when the background of the ImageView is changed. * @ Author xiu **/public class MusicPlayView extends RelativeLayout {private Context mContext; // The time used to rotate a week is private static final int ROTATE_TIME = 12*1000; // The number of times that an animation is repeatedly executed. The number of iterations indicates that there are no infinitely executed attributes. Therefore, a large number is used to indicate private static final int ROTATE_COUNT = 10000; // animation time private static final int NEEDLE_TIME = 1*500; // animation execution angle private static final int NEEDLE_RADIUS = 30; // gradient animation private static final int AVATART_DISC_ALPHA_TIME = 1*300; private static final float AVATART_DISC_ALPHA_PERCENT = 0.3f; // background private ImageView mBackground; // recording needle private ImageView mNeedle; // recording // private ImageView mDisc; // cover private CircleImageView mAvatar; private boolean isPlay = false; // recording animation ObjectAnimator mAniNeedle; // disk and cover rotation animation // ObjectAnimator mAniDisc; ObjectAnimator mAniAvatar; /// gradient effect during cover replacement /objectanimator else; // ObjectAnimator mAniAlphaAvatarShow; ///// gradient effect when the background is changed // ObjectAnimator watermark; float mValueAvatar; float mValueDisc; float mValueNeedle; // private int watermark = 0; // public MusicPlay mMusicPlayListener; public MusicPlayView (Context context, AttributeSet attrs) {super (context); mContext = context;} public MusicPlayView (Context context) {super (context ); mContext = context;} public MusicPlayView (Context context, AttributeSet attrs, int defStyle) {super (context, attrs, defStyle); mContext = context ;} /* public interface MusicPlay {void onAvatarChange (); void onDiscbgChange ();} * // * public void setMusicPlayerListener (MusicPlay listener) {this. mMusicPlayListener = listener;} */@ Override protected void onFinishInflate () {super. onFinishInflate (); mBackground = (ImageView) findViewById (R. id. bg); mAvatar = (CircleImageView) findViewById (R. id. avatar); // Bitmap conformBitmap = toConformBitmap (BitmapFactory. decodeResource (getResources (), R. drawable. fm_play_disc), mAvatar. getBitmap (); // mAvatar. setImageBitmap (conformBitmap); // mAvatar. setBackgroundDrawable (new BitmapDrawable (conformBitmap); // mAvatar. setBackgroundDrawable (getResources (). getDrawable (R. drawable. fm_play_disc); // mDisc = (ImageView) findViewById (R. id. disc); mNeedle = (ImageView) findViewById (R. id. needle); // mDisc. setVisibility (View. GONE); initAvatarAnimation (0f); // initDiscAnimation (0f); initNeedleAnimation (0f); // cover page animation // mAniAlphaAvatarHide = ObjectAnimator. ofFloat (mAvatar, "alpha", 1, AVATART_DISC_ALPHA_PERCENT ). setDuration (AVATART_DISC_ALPHA_TIME); // mAniAlphaAvatarHide. addListener (avatarAlphaHideListener); // mAniAlphaAvatarShow = ObjectAnimator. ofFloat (mAvatar, "alpha", AVATART_DISC_ALPHA_PERCENT, 1 ). setDuration (AVATART_DISC_ALPHA_TIME); // mAniAlphaDiscBgHide = ObjectAnimator. ofFloat (mBackground, "alpha", 1, AVATART_DISC_ALPHA_PERCENT ). setDuration (AVATART_DISC_ALPHA_TIME); // mAniAlphaDiscBgHide. addListener (discbgAlphaHideListener); // mAniAlphaDiscBgShow = ObjectAnimator. ofFloat (mBackground, "alpha", AVATART_DISC_ALPHA_PERCENT, 1 ). setDuration (duration);}/* AnimatorListener listener = new AnimatorListener () {@ Overridepublic void onAnimationStart (Animator arg0) {}@ Overridepublic void onAnimationRepeat (Animator arg0) {}@ Overridepublic void onAnimationEnd (Animator arg0) {mMusicPlayListener. onAvatarChange (); mAniAlphaAvatarShow. start () ;}@ Overridepublic void onAnimationCancel (Animator arg0) {}}; AnimatorListener listener = new AnimatorListener () {@ Overridepublic void onAnimationStart (Animator arg0) {}@ Overridepublic void onAnimationRepeat (Animator arg0) {}@ Overridepublic void onAnimationEnd (Animator arg0) {mMusicPlayListener. onDiscbgChange (); mAniAlphaDiscBgShow. start () ;}@ Overridepublic void onAnimationCancel (Animator arg0) {}}; * // ***** set the background * @ param d */public void setBackgroundDrawable (Drawable d) {mBackground. setBackgroundDrawable (d);}/***** set the background * @ param d */public void setBackgroundResource (int resourece) {Bitmap bmp = GaussianBlurUtil. drawableToBitmap (getResources (). getDrawable (resourece); mBackground. setBackgroundDrawable (GaussianBlurUtil. boxBlurFilter (bmp);} public void setAvatarImageResource (int resourceid) {mAvatar. setImageDrawable (getResources (). getDrawable (resourceid);}/*** play */public void play () {initNeedleAnimation (0f); AnimatorSet animSet = new AnimatorSet (); // animSet. playTogether (mAniAvatar, mAniDisc); animSet. play (mAniAvatar ). after (mAniNeedle); animSet. start (); setPlay (true);}/*** pause */public void pause () {initNeedleAnimation (NEEDLE_RADIUS); mAniNeedle. start (); mAniAvatar. cancel (); // mAniDisc. cancel (); initAvatarAnimation (mValueAvatar); // initDiscAnimation (mValueDisc); setPlay (false);}/*** next song */public void next (int resourceId) {// mAniAlphaAvatarHide. start (); // mAniAlphaDiscBgHide. start (); changeImage (resourceId); // pause (); // initAvatarAnimation (0f); // initDiscAnimation (0f); // initNeedleAnimation (0f ); // play ();} private void changeImage (final int resourceId) {postDelayed (new Runnable () {@ Overridepublic void run () {setBackgroundResource (resourceId ); setAvatarImageResource (resourceId) ;}}, 0) ;}private Bitmap toConformBitmap (Bitmap background, Bitmap foreground) {if (background = null) {return null;} int bgWidth = background. getWidth (); int bgHeight = background. getHeight (); // int fgWidth = foreground. getWidth (); // int fgHeight = foreground. getHeight (); // create the new blank bitmap to create a new Bitmap with the same length and width as SRC newbmp = Bitmap. createBitmap (bgWidth, bgHeight, Config. RGB_565); Canvas cv = new Canvas (newbmp); // draw bg into cv. drawBitmap (background, 0, 0, null); // draw bg at coordinates 0, 0 // draw fg into cv. drawBitmap (foreground, 0, 0, null); // you can draw fg at coordinates 0, 0, and save all clip cv. save (Canvas. ALL_SAVE_FLAG); // save // store cv. restore (); // store return newbmp;}/*** previous song */public void previous (int resourceId) {// mAniAlphaAvatarHide. start (); // mAniAlphaDiscBgHide. start (); pause (); changeImage (resourceId); // pause (); // initAvatarAnimation (0f); // initDiscAnimation (0f); // initNeedleAnimation (0f ); // play ();} public boolean isPlay () {return isPlay;} public void setPlay (boolean isPlay) {this. isPlay = isPlay;}/*** initialize the animation object for rotating the cover * @ param start */private void initAvatarAnimation (float start) {mAniAvatar = ObjectAnimator. ofFloat (mAvatar, "rotation", start, 360f + start); mAniAvatar. addUpdateListener (new AnimatorUpdateListener () {@ Overridepublic void onAnimationUpdate (ValueAnimator animation) {mValueAvatar = (Float) animation. getAnimatedValue ("rotation"); Log. e ("", "angle:" + mValueAvatar) ;}}); mAniAvatar. setDuration (ROTATE_TIME); mAniAvatar. setInterpolator (new LinearInterpolator (); mAniAvatar. setRepeatCount (ROTATE_COUNT);}/*** initialize the rotation disk animation object * @ param start * // * private void initDiscAnimation (float start) {mAniDisc = ObjectAnimator. ofFloat (mDisc, "rotation", start, 360f + start); mAniDisc. addUpdateListener (new AnimatorUpdateListener () {@ Overridepublic void onAnimationUpdate (ValueAnimator animation) {mValueDisc = (Float) animation. getAnimatedValue ("rotation") ;}}); mAniDisc. setDuration (ROTATE_TIME); mAniDisc. setInterpolator (new LinearInterpolator (); mAniDisc. setRepeatCount (ROTATE_COUNT);} * // *** initialize the animation ** @ param start */private void initNeedleAnimation (float start) {mAniNeedle = ObjectAnimator. ofFloat (mNeedle, "rotation", start, NEEDLE_RADIUS-start ). setDuration (NEEDLE_TIME );}}


Source code download: http://download.csdn.net/detail/u013651247/8270811



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.