上一篇播放主要的几个类也介绍的差不多了
下面就是一些我收集的好玩的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: 24750@163.com
*/
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: 24750@163.com
*/
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
网友评论