高仿网易云音乐二

上一篇播放主要的几个类也介绍的差不多了
下面就是一些我收集的好玩的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 ━━━
 * <p/>
 * Created by PangHaHa12138 on 2017/7/4.
 */
public class tantan1 extends AppCompatActivity {

    private ArrayList<CardMode> al;
    private CardAdapter adapter;
    private int i;
    private SwipeFlingAdapterView flingContainer;
    private List<List<Integer>> 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<Integer> s = new ArrayList<>();
            s.add(imageurl2[i]);
            list.add(s);
        }
        List<String> 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 ━━━
 * <p/>
 * 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

猜你喜欢

转载自blog.csdn.net/panghaha12138/article/details/75587208