高仿网易云音乐二

上一篇播放主要的几个类也介绍的差不多了
下面就是一些我收集的好玩的UI效果

朋友页面

仿探探

package com.panghaha.it.mymusicplayerdemo.UI;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import com.panghaha.it.mymusicplayerdemo.R;
import com.panghaha.it.mymusicplayerdemo.flingswipe.SwipeFlingAdapterView;
import com.panghaha.it.mymusicplayerdemo.swipecards.CardAdapter;
import com.panghaha.it.mymusicplayerdemo.swipecards.CardMode;

import java.util.ArrayList;
import java.util.List;

/***
 * ━━━━ Code is far away from ━━━━━━
 *     ()      ()
 *     ( )    ( )
 *     ( )    ( )
 *   ┏┛┻━━━┛┻┓
 *   ┃   ━   ┃
 *   ┃ ┳┛ ┗┳ ┃
 *   ┃   ┻   ┃
 *   ┗━┓   ┏━┛
 *     ┃   ┃
 *     ┃   ┗━━━┓
 *     ┃       ┣┓
 *     ┃       ┏┛
 *     ┗┓┓┏━┳┓┏┛
 *      ┃┫┫ ┃┫┫
 *      ┗┻┛ ┗┻┛
 * ━━━━ bug with the more protecting ━━━
 * 

* Created by PangHaHa12138 on 2017/7/4. */ public class tantan1 extends AppCompatActivity { private ArrayList al; private CardAdapter adapter; private int i; private SwipeFlingAdapterView flingContainer; private List> list = new ArrayList<>(); private ImageView left, right; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); left = (ImageView) findViewById(R.id.left); right = (ImageView) findViewById(R.id.right); left.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { left(); } }); right.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { right(); } }); al = new ArrayList<>(); for (int i = 0; i < imageurl2.length; i++) { List s = new ArrayList<>(); s.add(imageurl2[i]); list.add(s); } List yi; al.add(new CardMode("小姐姐", 16, list.get(0))); al.add(new CardMode("小姐姐", 21, list.get(1))); al.add(new CardMode("小姐姐", 18, list.get(2))); al.add(new CardMode("小姐姐", 21, list.get(3))); al.add(new CardMode("小姐姐", 23, list.get(4))); al.add(new CardMode("小姐姐", 21, list.get(5))); al.add(new CardMode("小姐姐", 21, list.get(6))); al.add(new CardMode("小姐姐", 25, list.get(7))); al.add(new CardMode("小姐姐", 21, list.get(8))); al.add(new CardMode("小姐姐", 23, list.get(9))); al.add(new CardMode("小姐姐", 21, list.get(10))); al.add(new CardMode("小姐姐", 22, list.get(11))); al.add(new CardMode("小姐姐", 21, list.get(12))); al.add(new CardMode("小姐姐", 21, list.get(13))); al.add(new CardMode("小姐姐", 25, list.get(14))); al.add(new CardMode("小姐姐", 21, list.get(15))); al.add(new CardMode("小姐姐", 24, list.get(16))); al.add(new CardMode("小姐姐", 21, list.get(17))); al.add(new CardMode("小姐姐", 21, list.get(18))); al.add(new CardMode("小姐姐", 22, list.get(19))); al.add(new CardMode("小姐姐", 21, list.get(20))); al.add(new CardMode("小姐姐", 22, list.get(21))); al.add(new CardMode("小姐姐", 21, list.get(22))); al.add(new CardMode("小姐姐", 23, list.get(23))); al.add(new CardMode("小姐姐", 21, list.get(24))); al.add(new CardMode("小姐姐", 21, list.get(25))); al.add(new CardMode("小姐姐", 25, list.get(26))); al.add(new CardMode("小姐姐", 21, list.get(27))); al.add(new CardMode("小姐姐", 26, list.get(28))); al.add(new CardMode("小姐姐", 21, list.get(29))); al.add(new CardMode("小姐姐", 21, list.get(30))); al.add(new CardMode("小姐姐", 24, list.get(31))); al.add(new CardMode("小姐姐", 21, list.get(32))); al.add(new CardMode("小姐姐", 23, list.get(33))); al.add(new CardMode("小姐姐", 22, list.get(34))); al.add(new CardMode("小姐姐", 21, list.get(35))); al.add(new CardMode("小姐姐", 21, list.get(36))); al.add(new CardMode("小姐姐", 21, list.get(37))); al.add(new CardMode("小姐姐", 20, list.get(38))); al.add(new CardMode("小姐姐", 21, list.get(39))); al.add(new CardMode("小姐姐", 20, list.get(40))); al.add(new CardMode("小姐姐", 21, list.get(41))); al.add(new CardMode("小姐姐", 20, list.get(42))); al.add(new CardMode("小姐姐", 21, list.get(43))); al.add(new CardMode("小姐姐", 20, list.get(44))); al.add(new CardMode("小姐姐", 20, list.get(45))); al.add(new CardMode("小姐姐", 21, list.get(46))); al.add(new CardMode("小姐姐", 21, list.get(47))); al.add(new CardMode("小姐姐", 25, list.get(48))); al.add(new CardMode("小姐姐", 21, list.get(49))); al.add(new CardMode("小姐姐", 23, list.get(50))); al.add(new CardMode("小姐姐", 21, list.get(51))); al.add(new CardMode("小姐姐", 21, list.get(52))); al.add(new CardMode("小姐姐", 23, list.get(53))); al.add(new CardMode("小姐姐", 21, list.get(54))); al.add(new CardMode("小姐姐", 23, list.get(55))); al.add(new CardMode("小姐姐", 21, list.get(56))); adapter = new CardAdapter(this, al); flingContainer = (SwipeFlingAdapterView) findViewById(R.id.frame); flingContainer.setAdapter(adapter); flingContainer.setFlingListener(new SwipeFlingAdapterView.onFlingListener() { @Override public void removeFirstObjectInAdapter() { al.remove(0); adapter.notifyDataSetChanged(); } @Override public void onLeftCardExit(Object dataObject) { makeToast(tantan1.this, "不喜欢"); } @Override public void onRightCardExit(Object dataObject) { makeToast(tantan1.this, "喜欢"); } @Override public void onAdapterAboutToEmpty(int itemsInAdapter) { al.add(new CardMode("循环测试", 18, list.get(itemsInAdapter % imageurl2.length - 1))); adapter.notifyDataSetChanged(); i++; } @Override public void onScroll(float scrollProgressPercent) { try { View view = flingContainer.getSelectedView(); view.findViewById(R.id.item_swipe_right_indicator).setAlpha(scrollProgressPercent < 0 ? -scrollProgressPercent : 0); view.findViewById(R.id.item_swipe_left_indicator).setAlpha(scrollProgressPercent > 0 ? scrollProgressPercent : 0); } catch (Exception e) { e.printStackTrace(); } } }); flingContainer.setOnItemClickListener(new SwipeFlingAdapterView.OnItemClickListener() { @Override public void onItemClicked(int itemPosition, Object dataObject) { makeToast(tantan1.this, "点击图片"); } }); } static void makeToast(Context ctx, String s) { Toast.makeText(ctx, s, Toast.LENGTH_SHORT).show(); } public void right() { flingContainer.getTopCardListener().selectRight(); } public void left() { flingContainer.getTopCardListener().selectLeft(); } public final int[] imageurl2 = new int[]{ R.drawable.ol1, R.drawable.ol2, R.drawable.ol3, R.drawable.ol4, R.drawable.ol5, R.drawable.ol6, R.drawable.ol7, R.drawable.ol8, R.drawable.ol9, R.drawable.ol10, R.drawable.ol11, R.drawable.ol12, R.drawable.ol13, R.drawable.ol14, R.drawable.ol15, R.drawable.ol16, R.drawable.ol17, R.drawable.ol18, R.drawable.ol19, R.drawable.ol20, R.drawable.ol21, R.drawable.ol22, R.drawable.ol23, R.drawable.ol24, R.drawable.ol25, R.drawable.ol26, R.drawable.ol27, R.drawable.ol28, R.drawable.ol29, R.drawable.ol30, R.drawable.ol31, R.drawable.ol32, R.drawable.ol33, R.drawable.ol34, R.drawable.ol35, R.drawable.ol36, R.drawable.ol37, R.drawable.ol38, R.drawable.ol39, R.drawable.ol40, R.drawable.ol41, R.drawable.ol42, R.drawable.ol43, R.drawable.ol44, R.drawable.ol45, R.drawable.ol46, R.drawable.ol47, R.drawable.ol48, R.drawable.ol49, R.drawable.ol50, R.drawable.ol51, R.drawable.ol52, R.drawable.ol53, R.drawable.ol54, R.drawable.ol55, R.drawable.ol56, R.drawable.ol57, };

adapter类

package com.panghaha.it.mymusicplayerdemo.flingswipe;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.graphics.PointF;
import android.os.Build;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.Adapter;
import android.widget.FrameLayout;

import com.panghaha.it.mymusicplayerdemo.R;


/**
 * Created by dionysis_lorentzos on 5/8/14
 * for package com.lorentzos.swipecards
 * and project Swipe cards.
 * Use with caution dinosaurs might appear!
 */

public class SwipeFlingAdapterView extends BaseFlingAdapterView {


    private int MAX_VISIBLE = 4;
    private int MIN_ADAPTER_STACK = 6;
    private float ROTATION_DEGREES = 15.f;
    private float ITEM_SMALL_WIDTH = 20;
    private float ITEM_SMALL_HIGH = 32;

    private Adapter mAdapter;
    private int LAST_OBJECT_IN_STACK = 0;
    private onFlingListener mFlingListener;
    private AdapterDataSetObserver mDataSetObserver;
    private boolean mInLayout = false;
    private View mActiveCard = null;
    private OnItemClickListener mOnItemClickListener;
    private FlingCardListener flingCardListener;
    private PointF mLastTouchPoint;

    private float p = 0f;

    public SwipeFlingAdapterView(Context context) {
        this(context, null);
    }

    public SwipeFlingAdapterView(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.SwipeFlingStyle);
    }

    public SwipeFlingAdapterView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SwipeFlingAdapterView, defStyle, 0);
        MAX_VISIBLE = a.getInt(R.styleable.SwipeFlingAdapterView_max_visible, MAX_VISIBLE);
        MIN_ADAPTER_STACK = a.getInt(R.styleable.SwipeFlingAdapterView_min_adapter_stack, MIN_ADAPTER_STACK);
        ROTATION_DEGREES = a.getFloat(R.styleable.SwipeFlingAdapterView_rotation_degrees, ROTATION_DEGREES);
        a.recycle();
    }

    private float dpToPx(int sp) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sp, getContext().getResources().getDisplayMetrics());
    }

    /**
     * A shortcut method to set both the listeners and the adapter.
     *
     * @param context  The activity context which extends onFlingListener, OnItemClickListener or both
     * @param mAdapter The adapter you have to set.
     */
    public void init(final Context context, Adapter mAdapter) {
        if (context instanceof onFlingListener) {
            mFlingListener = (onFlingListener) context;
        } else {
            throw new RuntimeException("Activity does not implement SwipeFlingAdapterView.onFlingListener");
        }
        if (context instanceof OnItemClickListener) {
            mOnItemClickListener = (OnItemClickListener) context;
        }
        setAdapter(mAdapter);
    }

    @Override
    public View getSelectedView() {
        return mActiveCard;
    }


    @Override
    public void requestLayout() {
        if (!mInLayout) {
            super.requestLayout();
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        // if we don't have an adapter, we don't need to do anything
        if (mAdapter == null) {
            return;
        }

        mInLayout = true;
        final int adapterCount = mAdapter.getCount();

        if (adapterCount == 0) {
            removeAllViewsInLayout();
        } else {
            View topCard = getChildAt(LAST_OBJECT_IN_STACK);
            if (mActiveCard != null && topCard != null && topCard == mActiveCard) {
                if (this.flingCardListener.isTouching()) {
                    PointF lastPoint = this.flingCardListener.getLastPoint();
                    if (this.mLastTouchPoint == null || !this.mLastTouchPoint.equals(lastPoint)) {
                        this.mLastTouchPoint = lastPoint;
                        removeViewsInLayout(0, LAST_OBJECT_IN_STACK);
                        layoutChildren(1, adapterCount, 3);
                    }
                }
            } else {
                // Reset the UI and set top view listener
                removeAllViewsInLayout();
                layoutChildren(0, adapterCount, 3);
                setTopView();
            }
        }

        mInLayout = false;

        if (adapterCount <= MIN_ADAPTER_STACK) mFlingListener.onAdapterAboutToEmpty(adapterCount);
    }


    private void layoutChildren(int startingIndex, int adapterCount, int count) {

        while (startingIndex < Math.min(adapterCount, 4)) {
            View newUnderChild = mAdapter.getView(startingIndex, null, this);
            if (newUnderChild.getVisibility() != GONE) {
                makeAndAddView(startingIndex, newUnderChild);
                LAST_OBJECT_IN_STACK = startingIndex;
            }
            startingIndex++;
        }
    }

    /**
     * 跳转改变view 大小
     *
     * @param child
     * @param index
     */
    private void adjustChildView(View child, int index) {
        int n;
        if (index > 1)
            n = 2;
        else
            n = index;
        if (index == 3 && p > 0.5f) {
            n = index;
        }
        child.offsetTopAndBottom((int) (dpToPx((int) ITEM_SMALL_HIGH) * (n - p)));
        child.setScaleX(1 - 0.1f * (n - p));
        child.setScaleY(1 - 0.1f * (n - p));
    }

    /**
     * 绘制子View
     *
     * @param index
     * @param child
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    private void makeAndAddView(int index, View child) {

        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) child.getLayoutParams();
        addViewInLayout(child, 0, lp, true);

        final boolean needToMeasure = child.isLayoutRequested();
        if (needToMeasure) {
            int childWidthSpec = getChildMeasureSpec(getWidthMeasureSpec(), getPaddingLeft() + getPaddingRight() + lp.leftMargin + lp.rightMargin, lp.width);
            int childHeightSpec = getChildMeasureSpec(getHeightMeasureSpec(), getPaddingTop() + getPaddingBottom() + lp.topMargin + lp.bottomMargin, lp.height);
            child.measure(childWidthSpec, childHeightSpec);
        } else {
            cleanupLayoutState(child);
        }


        int w = child.getMeasuredWidth();
        int h = child.getMeasuredHeight();
        int gravity = lp.gravity;
        if (gravity == -1) {
            gravity = Gravity.TOP | Gravity.START;
        }
        int layoutDirection = getLayoutDirection();
        final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
        final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;

        int childLeft;
        int childTop;
        switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
            case Gravity.CENTER_HORIZONTAL:
                childLeft = (getWidth() + getPaddingLeft() - getPaddingRight() - w) / 2 + lp.leftMargin - lp.rightMargin;
                break;
            case Gravity.END:
                childLeft = getWidth() + getPaddingRight() - w - lp.rightMargin;
                break;
            case Gravity.START:
            default:
                int l = 0;
                childLeft = getPaddingLeft() + lp.leftMargin + l;
                break;
        }
        switch (verticalGravity) {
            case Gravity.CENTER_VERTICAL:
                childTop = (getHeight() + getPaddingTop() - getPaddingBottom() - h) / 2 +
                        lp.topMargin - lp.bottomMargin;
                break;
            case Gravity.BOTTOM:
                childTop = getHeight() - getPaddingBottom() - h - lp.bottomMargin;
                break;
            case Gravity.TOP:
            default:
                int top = 0;
                childTop = getPaddingTop() + lp.topMargin + top;
                break;
        }

        child.layout(childLeft, childTop, childLeft + w, childTop + h);
        adjustChildView(child, index);
    }


    /**
     * Set the top view and add the fling listener
     */
    private void setTopView() {
        if (getChildCount() > 0) {

            mActiveCard = getChildAt(LAST_OBJECT_IN_STACK);
            if (mActiveCard != null) {

                flingCardListener = new FlingCardListener(mActiveCard, mAdapter.getItem(0),
                        ROTATION_DEGREES, new FlingCardListener.FlingListener() {

                    @Override
                    public void onCardExited() {
                        mActiveCard = null;
                        p = 0f;
                        mFlingListener.removeFirstObjectInAdapter();
                    }

                    @Override
                    public void leftExit(Object dataObject) {
                        p = 0f;
                        mFlingListener.onLeftCardExit(dataObject);
                    }

                    @Override
                    public void rightExit(Object dataObject) {
                        mFlingListener.onRightCardExit(dataObject);
                    }

                    @Override
                    public void onClick(Object dataObject) {
                        if (mOnItemClickListener != null)
                            mOnItemClickListener.onItemClicked(0, dataObject);

                    }

                    @Override
                    public void onScroll(float scrollProgressPercent) {
                        mFlingListener.onScroll(scrollProgressPercent);

                    }

                    @Override
                    public void onMoveXY(float moveX, float moveY) {
                        float mX = (int) Math.abs(moveX);
                        float mY = (int) Math.abs(moveY);
                        if (mX > 50 || mY > 50) {
                            float m = Math.max(mX, mY);
                            p = (m - 50f) / 500f;
                            if (p > 1f) {
                                p = 1f;
                            }
                        } else {
                            p = 0f;
                        }
                        requestLayout();


                    }
                });

                mActiveCard.setOnTouchListener(flingCardListener);
            }
        }
    }

    public FlingCardListener getTopCardListener() throws NullPointerException {
        if (flingCardListener == null) {
            throw new NullPointerException();
        }
        return flingCardListener;
    }

    public void setMaxVisible(int MAX_VISIBLE) {
        this.MAX_VISIBLE = MAX_VISIBLE;
    }

    public void setMinStackInAdapter(int MIN_ADAPTER_STACK) {
        this.MIN_ADAPTER_STACK = MIN_ADAPTER_STACK;
    }

    @Override
    public Adapter getAdapter() {
        return mAdapter;
    }


    @Override
    public void setAdapter(Adapter adapter) {
        if (mAdapter != null && mDataSetObserver != null) {
            mAdapter.unregisterDataSetObserver(mDataSetObserver);
            mDataSetObserver = null;
        }

        mAdapter = adapter;

        if (mAdapter != null && mDataSetObserver == null) {
            mDataSetObserver = new AdapterDataSetObserver();
            mAdapter.registerDataSetObserver(mDataSetObserver);
        }
    }

    public void setFlingListener(onFlingListener onFlingListener) {
        this.mFlingListener = onFlingListener;
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.mOnItemClickListener = onItemClickListener;
    }


    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new FrameLayout.LayoutParams(getContext(), attrs);
    }


    private class AdapterDataSetObserver extends DataSetObserver {
        @Override
        public void onChanged() {
            requestLayout();
        }

        @Override
        public void onInvalidated() {
            requestLayout();
        }

    }


    public interface OnItemClickListener {
        void onItemClicked(int itemPosition, Object dataObject);
    }

    public interface onFlingListener {
        void removeFirstObjectInAdapter();

        void onLeftCardExit(Object dataObject);

        void onRightCardExit(Object dataObject);

        void onAdapterAboutToEmpty(int itemsInAdapter);

        void onScroll(float scrollProgressPercent);


    }


}

仿摩拜单车的卡包里滚动球效果(利用了一个jbox2d的物理引擎库)

package com.panghaha.it.mymusicplayerdemo.UI;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.MenuItem;
import android.widget.FrameLayout;
import android.widget.ImageView;

import com.mobike.library.Mobike;
import com.mobike.library.MobikeView;
import com.panghaha.it.mymusicplayerdemo.R;

public class MobikeDemo extends AppCompatActivity {

    private MobikeView mobikeView;
    private SensorManager sensorManager;
    private Sensor defaultSensor;

    private int[] imgs = {
            R.drawable.share_fb,
            R.drawable.share_kongjian,
            R.drawable.share_pyq,
            R.drawable.share_qq,
            R.drawable.share_tw,
            R.drawable.share_wechat,
            R.drawable.share_weibo,
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mobike_demo);
//        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//        getSupportActionBar().setTitle("摩拜单车Demo");
        mobikeView = (MobikeView) findViewById(R.id.mobike_view);

        initViews();

        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        defaultSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    }

    private void initViews() {
        FrameLayout.LayoutParams layoutParams =
                new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
                        FrameLayout.LayoutParams.WRAP_CONTENT);

        layoutParams.gravity = Gravity.CENTER;
        for(int i = 0; i < imgs.length  ; i ++){
            ImageView imageView = new ImageView(this);
            imageView.setImageResource(imgs[i]);
            imageView.setTag(R.id.mobike_view_circle_tag,true);
            mobikeView.addView(imageView,layoutParams);
        }
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if(item.getItemId() == android.R.id.home){
            finish();
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onStart() {
        super.onStart();
        mobikeView.getmMobike().onStart();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mobikeView.getmMobike().onStop();
    }

    @Override
    protected void onResume() {
        super.onResume();
        sensorManager.registerListener(listerner, defaultSensor, SensorManager.SENSOR_DELAY_UI);
    }

    @Override
    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(listerner);
    }

    private SensorEventListener listerner = new SensorEventListener(){

        @Override
        public void onSensorChanged(SensorEvent event) {
            if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER){
                float x =  event.values[0];
                float y =   event.values[1] * 2.0f;
                mobikeView.getmMobike().onSensorChanged(-x,y);
            }
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {

        }
    };
}

滚动球控件类

package com.mobike.library;


import android.content.Context;
import android.graphics.Canvas;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.FrameLayout;

/**
 * Created by kimi on 2017/7/8 0008.
 * Email: [email protected]
 */

public class MobikeView extends FrameLayout {

    private Mobike mMobike;

    public MobikeView(@NonNull Context context) {
        this(context,null);
    }

    public MobikeView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        setWillNotDraw(false);
        mMobike = new Mobike(this);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mMobike.onSizeChanged(w,h);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        mMobike.onLayout(changed);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mMobike.onDraw(canvas);
    }

    public Mobike getmMobike(){
        return this.mMobike;
    }
}

package com.mobike.library;


import android.graphics.Canvas;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import org.jbox2d.collision.shapes.CircleShape;
import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.collision.shapes.Shape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.FixtureDef;
import org.jbox2d.dynamics.World;

import java.util.Random;

/**
 * Created by kimi on 2017/7/8 0008.
 * Email: [email protected]
 */

public class Mobike {

    public static final String TAG = Mobike.class.getSimpleName();

    private World world;
    private float dt = 1f / 60f;
    private int velocityIterations = 3;
    private int positionIterations = 10;
    private float friction = 0.3f,density = 0.5f,restitution = 0.3f,ratio = 50;
    private int width,height;
    private boolean enable = true;
    private final Random random = new Random();

    private ViewGroup mViewgroup;

    public Mobike(ViewGroup viewgroup) {
        this.mViewgroup = viewgroup;
        density = viewgroup.getContext().getResources().getDisplayMetrics().density;
    }

    public void onSizeChanged(int width,int height){
        this.width = width;
        this.height = height;
    }

    public void onDraw(Canvas canvas) {
        if(!enable){
            return;
        }
        world.step(dt,velocityIterations,positionIterations);
        int childCount = mViewgroup.getChildCount();
        for(int i = 0; i < childCount; i++){
            View view = mViewgroup.getChildAt(i);
            Body body = (Body) view.getTag(R.id.mobike_body_tag);
            if(body != null){
                view.setX(metersToPixels(body.getPosition().x) - view.getWidth() / 2);
                view.setY(metersToPixels(body.getPosition().y) - view.getHeight() / 2);
                view.setRotation(radiansToDegrees(body.getAngle() % 360));
            }
        }
        mViewgroup.invalidate();
    }

    public void onLayout(boolean changed) {
        createWorld(changed);
    }

    public void onStart(){
        setEnable(true);
    }

    public void onStop(){
        setEnable(false);
    }

    public void update(){
        world = null;
        onLayout(true);
    }

    private void createWorld(boolean changed) {
        if(world == null){
            world = new World(new Vec2(0, 10.0f));
            createTopAndBottomBounds();
            createLeftAndRightBounds();
        }
        int childCount = mViewgroup.getChildCount();
        for(int i = 0; i < childCount; i++){
            View view = mViewgroup.getChildAt(i);
            Body body = (Body) view.getTag(R.id.mobike_body_tag);
            if(body == null || changed){
                createBody(world,view);
            }
        }
    }

    private void createBody(World world, View view) {
        BodyDef bodyDef = new BodyDef();
        bodyDef.setType(BodyType.DYNAMIC);

        bodyDef.position.set(pixelsToMeters(view.getX() + view.getWidth() / 2) ,
                             pixelsToMeters(view.getY() + view.getHeight() / 2));
        Shape shape = null;
        Boolean isCircle = (Boolean) view.getTag(R.id.mobike_view_circle_tag);
        if(isCircle != null && isCircle){
            shape = createCircleShape(view);
        }else{
            shape = createPolygonShape(view);
        }
        FixtureDef fixture = new FixtureDef();
        fixture.setShape(shape);
        fixture.friction = friction;
        fixture.restitution = restitution;
        fixture.density = density;

        Body body = world.createBody(bodyDef);
        body.createFixture(fixture);
        view.setTag(R.id.mobike_body_tag,body);
        body.setLinearVelocity(new Vec2(random.nextFloat(),random.nextFloat()));
    }

    private Shape createCircleShape(View view){
        CircleShape circleShape = new CircleShape();
        circleShape.setRadius(pixelsToMeters(view.getWidth() / 2));
        return circleShape;
    }

    private Shape createPolygonShape(View view){
        PolygonShape polygonShape = new PolygonShape();
        polygonShape.setAsBox(pixelsToMeters(view.getWidth() / 2),pixelsToMeters(view.getHeight() / 2));
        return polygonShape;
    }

    private void createTopAndBottomBounds() {
        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyType.STATIC;

        PolygonShape box = new PolygonShape();
        float boxWidth = pixelsToMeters(width);
        float boxHeight =  pixelsToMeters(ratio);
        box.setAsBox(boxWidth, boxHeight);

        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = box;
        fixtureDef.density = 0.5f;
        fixtureDef.friction = 0.3f;
        fixtureDef.restitution = 0.5f;

        bodyDef.position.set(0, -boxHeight);
        Body topBody = world.createBody(bodyDef);
        topBody.createFixture(fixtureDef);

        bodyDef.position.set(0, pixelsToMeters(height)+boxHeight);
        Body bottomBody = world.createBody(bodyDef);
        bottomBody.createFixture(fixtureDef);
    }

    private void createLeftAndRightBounds() {
        float boxWidth = pixelsToMeters(ratio);
        float boxHeight = pixelsToMeters(height);

        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyType.STATIC;

        PolygonShape box = new PolygonShape();
        box.setAsBox(boxWidth, boxHeight);
        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = box;
        fixtureDef.density = 0.5f;
        fixtureDef.friction = 0.3f;
        fixtureDef.restitution = 0.5f;

        bodyDef.position.set(-boxWidth, boxHeight);
        Body leftBody = world.createBody(bodyDef);
        leftBody.createFixture(fixtureDef);


        bodyDef.position.set(pixelsToMeters(width) + boxWidth, 0);
        Body rightBody = world.createBody(bodyDef);
        rightBody.createFixture(fixtureDef);
    }

    private float radiansToDegrees(float radians) {
        return radians / 3.14f * 180f;
    }

    private float degreesToRadians(float degrees){
        return (degrees / 180f) * 3.14f;
    }

    public float metersToPixels(float meters) {
        return meters * ratio;
    }

    public float pixelsToMeters(float pixels) {
        return pixels / ratio;
    }

    public void random() {
        int childCount = mViewgroup.getChildCount();
        for (int i = 0; i < childCount; i++) {
            Vec2 impulse = new Vec2(random.nextInt(1000) - 1000, random.nextInt(1000) - 1000);
            View view = mViewgroup.getChildAt(i);
            Body body = (Body) view.getTag(R.id.mobike_body_tag);
            if(body != null){
                body.applyLinearImpulse(impulse, body.getPosition(),true);
            }
        }
    }

    public void onSensorChanged(float x,float y) {
        int childCount = mViewgroup.getChildCount();
        for (int i = 0; i < childCount; i++) {
            Vec2 impulse = new Vec2(x, y);
            View view = mViewgroup.getChildAt(i);
            Body body = (Body) view.getTag(R.id.mobike_body_tag);
            if(body != null){
                body.applyLinearImpulse(impulse, body.getPosition(),true);
            }
        }
    }

    public float getFriction() {
        return friction;
    }

    public void setFriction(float friction) {
        if(friction >= 0){
            this.friction = friction;
        }
    }

    public float getDensity() {
        return density;
    }

    public void setDensity(float density) {
        if(density >= 0){
            this.density = density;
        }
    }

    public float getRestitution() {
        return restitution;
    }

    public void setRestitution(float restitution) {
        if(restitution >= 0){
            this.restitution = restitution;
        }
    }

    public float getRatio() {
        return ratio;
    }

    public void setRatio(float ratio) {
        if(ratio >= 0){
            this.ratio = ratio;
        }
    }

    public boolean getEnable() {
        return enable;
    }

    public void setEnable(boolean enable) {
        this.enable = enable;
        mViewgroup.invalidate();
    }
}

仿ofo效果

package com.panghaha.it.mymusicplayerdemo.UI;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.view.View;

import com.panghaha.it.mymusicplayerdemo.R;

/***
 * ━━━━ Code is far away from ━━━━━━
 *     ()      ()
 *     ( )    ( )
 *     ( )    ( )
 *   ┏┛┻━━━┛┻┓
 *   ┃   ━   ┃
 *   ┃ ┳┛ ┗┳ ┃
 *   ┃   ┻   ┃
 *   ┗━┓   ┏━┛
 *     ┃   ┃
 *     ┃   ┗━━━┓
 *     ┃       ┣┓
 *     ┃       ┏┛
 *     ┗┓┓┏━┳┓┏┛
 *      ┃┫┫ ┃┫┫
 *      ┗┻┛ ┗┻┛
 * ━━━━ bug with the more protecting ━━━
 * 

* Created by PangHaHa12138 on 2017/7/10. */ public class OFOActivity extends AppCompatActivity { public static final String TAG = OFOActivity.class.getSimpleName(); private SensorManager sensorManager; private Sensor defaultSensor; private View lefteye,righteye; private float normalSpace ; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.ofolayout); lefteye = findViewById(R.id.lefteye); righteye = findViewById(R.id.righteye); normalSpace = getResources().getDimension(R.dimen.dimen20); sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); defaultSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); //完美做法,需要对dimens进行不同屏幕的适配即可 /* 传感器类型说明如下: #define SENSOR_TYPE_ACCELEROMETER 1 //加速度 #define SENSOR_TYPE_MAGNETIC_FIELD 2 //磁力 #define SENSOR_TYPE_ORIENTATION 3 //方向 #define SENSOR_TYPE_GYROSCOPE 4 //陀螺仪 #define SENSOR_TYPE_LIGHT 5 //光线感应 #define SENSOR_TYPE_PRESSURE 6 //压力 #define SENSOR_TYPE_TEMPERATURE 7 //温度 #define SENSOR_TYPE_PROXIMITY 8 //接近 #define SENSOR_TYPE_GRAVITY 9 //重力 #define SENSOR_TYPE_LINEAR_ACCELERATION 10//线性加速度 #define SENSOR_TYPE_ROTATION_VECTOR 11//旋转矢量 */ } @Override protected void onResume() { super.onResume(); sensorManager.registerListener(listerner, defaultSensor, SensorManager.SENSOR_DELAY_UI); /* 第三个参数如下: * get sensor data as fast as possible public static final int SENSOR_DELAY_FASTEST = 0; * rate suitable for games public static final int SENSOR_DELAY_GAME = 1; * rate suitable for the user interface public static final int SENSOR_DELAY_UI = 2; * rate (default) suitable for screen orientation changes public static final int SENSOR_DELAY_NORMAL = 3; */ } @Override protected void onPause() { super.onPause(); sensorManager.unregisterListener(listerner); } private SensorEventListener listerner = new SensorEventListener(){ private float x,y; @Override public void onSensorChanged(SensorEvent event) { /* 加速度传感器说明: 加速度传感器又叫G-sensor,返回x、y、z三轴的加速度数值。 该数值包含地心引力的影响,单位是m/s^2。 将手机平放在桌面上,x轴默认为0,y轴默认0,z轴默认9.81。 将手机朝下放在桌面上,z轴为-9.81。 将手机向左倾斜,x轴为正值。 将手机向右倾斜,x轴为负值。 将手机向上倾斜,y轴为负值。 将手机向下倾斜,y轴为正值。 加速度传感器可能是最为成熟的一种mems产品,市场上的加速度传感器种类很多。 手机中常用的加速度传感器有BOSCH(博世)的BMA系列,AMK的897X系列,ST的LIS3X系列等。 这些传感器一般提供±2G至±16G的加速度测量范围,采用I2C或SPI接口和MCU相连,数据精度小于16bit。 */ if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER){ x -= 7.0f * event.values[0]; y += 7.0f * event.values[1]; //越界处理 if(x < -normalSpace ){ x = -normalSpace; } if(x > 0){ x = 0; } if(y > 0){ y = 0; } if(y < -normalSpace){ y = -normalSpace; } lefteye.setTranslationY(y); lefteye.setTranslationX(x); lefteye.setRotation(x); righteye.setTranslationX(x); righteye.setTranslationY(y); righteye.setRotation(x); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; }

最后是 个人中心 的页面

SweetAlertDialog

非常好用效果很漂亮 的dialog

 new SweetAlertDialog(getActivity(), SweetAlertDialog.WARNING_TYPE)
                        .setTitleText("确认打赏?")
                        .setContentText("打赏100元人民币")
                        .setConfirmText("Yes,do it!")
                        .setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
                            @Override
                            public void onClick(SweetAlertDialog sDialog) {
                                sDialog
                                        .setTitleText("打赏!")
                                        .setContentText("已打赏100元人名币!")
                                        .setConfirmText("OK")
                                        .setConfirmClickListener(null)
                                        .changeAlertType(SweetAlertDialog.SUCCESS_TYPE);
                            }
                        })
                        .show();

this all
thanks
http://www.jianshu.com/p/cb54990219d9
http://blog.csdn.net/qq_28268507/article/details/74892372
http://blog.csdn.net/shallcheek/article/details/46606523

你可能感兴趣的:(高仿网易云音乐二)