效果:
本人爱好做android各种好玩的效果和交互,欢迎大家交流。
引用大神的成果
http://www.open-open.com/lib/view/open1455706317480.html
原来的效果是这样的
虽然我添加了3D翻转,还有光照背景,看起来华丽,但其实不知道在什么地方用得上。又修改了代码,添加了滑动停止后,自动锁定最靠近中央的item,作为一个选择菜单使用,跟日期选择控件有点类似。
给这个控件的每个item添加触发点击事件,应该是不太需要的吧。
毕竟,每个都要点击,然后触发比如查看大图之类,还不如用最直观的gridview呢。
代码:
从大神的工程的基础上重构了实体类Tag.java的一些属性名字,比如用简单的x,y,z表示子控件的3d空间坐标
public class Tag {
private int popularity; //this is the importance/popularity of the Tag
public float x, y, z; //the center of the 3D Tag
private float loc2DX, loc2DY;
private float scale;
private float[] argb;
private static final int DEFAULT_POPULARITY = 5;
修改了TagCloudView.java。
去掉onLayout方法,改沿用继承FrameLayout了,修改updateChild方法,view的位置,大小,透明度,X,Y旋转计算直接完成,然后invalidate()重新绘制。
修改onTouchEvent,不再根据触摸点离中心有多远,而是根据手指滑动距离,决定X,Y方向的角度偏转修改对惯性摩擦阻力的一些参数(run方法),由于修改了角度偏转方法,如果还按原来的参数,则阻力太小,根本停不下来
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import com.dxtx.common.R;
/**
* Copyright © 2016 moxun
* <p/>
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the “Software”),
* to deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* <p/>
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
* <p/>
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
* OR OTHER DEALINGS IN THE SOFTWARE.
*/
public class TagCloudView extends FrameLayout implements Runnable, TagsAdapter.OnDataSetChangeListener {
// private final float TOUCH_SCALE_FACTOR = .8f;
private final float TOUCH_SCALE_FACTOR = 12f;
private final float TRACKBALL_SCALE_FACTOR = 10;
private float tspeed = 2f;
private TagCloud mTagCloud;
private float mAngleX = 0.5f;
private float mAngleY = 0.5f;
private float centerX, centerY;
private float radius;
private float radiusPercent = 0.9f;
private float[] darkColor = new float[]{
1f, 0f, 0f, 1};
private float[] lightColor = new float[]{
0.9412f, 0.7686f, 0.2f, 1};
private int sphereColor = Color.WHITE;
private State touch_state = State.Scroll;
private Tag selectTag;
private int selectIndex;
private float minLockError;
private enum State {
Touch, Calm, AutoLock, Scroll
}
private boolean autoSelect = false;
private Handler handler = new Handler(Looper.getMainLooper());
private TagsAdapter tagsAdapter;
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint glancePaint;
private RectF glanceRect = new RectF();
private RectF shadowRect = new RectF();
private Bitmap glanceBitmap, shadowBitmap;
public TagCloudView(Context context) {
super(context);
setFocusableInTouchMode(true);
init(context, null);
}
public TagCloudView(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusableInTouchMode(true);
init(context, attrs);
}
public TagCloudView(Context context, AttributeSet attrs, int defStyleAttr) {