前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android实现3D云标签效果

Android实现3D云标签效果

作者头像
砸漏
发布2020-11-05 09:59:26
1.3K0
发布2020-11-05 09:59:26
举报
文章被收录于专栏:恩蓝脚本

本文实例为大家分享了Android实现3D云标签效果的具体代码,供大家参考,具体内容如下

一、自定义View

代码语言:javascript
复制
public class TagCloudView extends RelativeLayout { 
RelativeLayout navigation_bar; 
TextView mTextView1; 
private final float TOUCH_SCALE_FACTOR = .8f; 
private float tspeed; 
private TagCloud mTagCloud; 
private float mAngleX =0; 
private float mAngleY =0; 
private float centerX, centerY; 
private float radius; 
private Context mContext; 
private List<TextView  mTextView; 
private List<RelativeLayout.LayoutParams  mParams; 
private int shiftLeft; 
float dowx = 0; 
float dowy = 0; 
float cutx=100; 
float cuty=100; 
public TagCloudView(Context mContext, int width, int height, List<Tag  tagList) { 
this(mContext, width, height, tagList, 6 , 34, 1); 
} 
public TagCloudView(Context mContext, int width, int height, List<Tag  tagList, 
int textSizeMin, int textSizeMax, int scrollSpeed) { 
super(mContext); 
this.mContext= mContext; 
tspeed = scrollSpeed; 
centerX = width / 2; 
centerY = height / 2; 
radius = Math.min(centerX * 0.95f , centerY * 0.95f ); 
shiftLeft = (int)(Math.min(centerX * 0.15f , centerY * 0.15f )); 
mTagCloud = new TagCloud(tagList, (int) radius , textSizeMin, textSizeMax); 
float[] tempColor1 = {0.9412f,0.7686f,0.2f,1}; //rgb Alpha 
//{1f,0f,0f,1} red  {0.3882f,0.21568f,0.0f,1} orange 
//{0.9412f,0.7686f,0.2f,1} light orange 
float[] tempColor2 = {1f,0f,0f,1}; //rgb Alpha 
//{0f,0f,1f,1} blue  {0.1294f,0.1294f,0.1294f,1} grey 
//{0.9412f,0.7686f,0.2f,1} light orange 
mTagCloud.setTagColor1(tempColor1);//higher color 
mTagCloud.setTagColor2(tempColor2);//lower color 
mTagCloud.setRadius((int) radius); 
mTagCloud.create(true); 
mTagCloud.setAngleX(mAngleX); 
mTagCloud.setAngleY(mAngleY); 
mTagCloud.update(); 
mTextView = new ArrayList<TextView (); 
mParams = new ArrayList<RelativeLayout.LayoutParams (); 
Iterator<?  it=mTagCloud.iterator(); 
Tag tempTag; 
int i=0; 
//取出每个数据放到TexView里 
while (it.hasNext()){ 
tempTag= (Tag) it.next();    
tempTag.setParamNo(i); 
mTextView.add(new TextView(this.mContext)); 
mTextView.get(i).setText(tempTag.getText()); 
mParams.add(new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 
mParams.get(i).addRule(RelativeLayout.ALIGN_PARENT_LEFT); 
mParams.get(i).addRule(RelativeLayout.ALIGN_PARENT_TOP); 
mParams.get(i).setMargins((int) (centerX -shiftLeft + tempTag.getLoc2DX()),(int) (centerY + tempTag.getLoc2DY()),0,0); 
mTextView.get(i).setLayoutParams(mParams.get(i)); 
mTextView.get(i).setSingleLine(true); 
int mergedColor = Color.argb((int)(tempTag.getAlpha() * 255), (int) (tempTag.getColorR() * 255), (int) (tempTag.getColorG() * 255),(int) (tempTag.getColorB() * 255)); 
mTextView.get(i).setTextColor(mergedColor); 
mTextView.get(i).setTextSize((int)(tempTag.getTextSize() * tempTag.getScale())); 
addView(mTextView.get(i)); 
mTextView.get(i).setOnClickListener(OnTagClickListener(tempTag.getUrl())); 
//设置每个TexView有自己指定的标签为自己的位置,以便后期操作 
mTextView.get(i).setTag(i); 
i++; 
} 
/** 用来自动播放的*/ 
new Timer().schedule(new TimerTask() { 
@Override 
public void run() { 
handler.sendEmptyMessage(1); 
} 
}, 0,200); 
} 
@SuppressLint("HandlerLeak") 
Handler handler=new Handler(){ 
@Override 
public void handleMessage(Message msg) { 
super.handleMessage(msg); 
mAngleX = (cuty/radius) *tspeed * TOUCH_SCALE_FACTOR; 
mAngleY = (-cutx/radius) *tspeed * TOUCH_SCALE_FACTOR; 
changPosition(); 
} 
}; 
@Override 
protected void onDraw(Canvas canvas){ 
super.onDraw(canvas); 
} 
/** 
* 触发事件 
*/ 
@Override 
public boolean onTouchEvent(MotionEvent e) { 
switch (e.getAction()) { 
case MotionEvent.ACTION_DOWN: 
dowx=e.getX(); 
dowy=e.getY(); 
break; 
case MotionEvent.ACTION_UP: 
float upx=e.getX(); 
float upy=e.getY(); 
cutx=upx-dowx; 
cuty=upy-dowy; 
break; 
case MotionEvent.ACTION_MOVE:  
mAngleX = (cuty/radius) *tspeed * TOUCH_SCALE_FACTOR; 
mAngleY = (-cutx/radius) *tspeed * TOUCH_SCALE_FACTOR; 
changPosition(); 
break; 
} 
return true; 
} 
/** 
* 改变位置 
*/ 
private void changPosition(){ 
mTagCloud.setAngleX(mAngleX); 
mTagCloud.setAngleY(mAngleY); 
mTagCloud.update(); 
Iterator<?  it=mTagCloud.iterator(); 
Tag tempTag; 
while (it.hasNext()){ 
tempTag= (Tag) it.next();    
mParams.get(tempTag.getParamNo()).setMargins(  
(int) (centerX -shiftLeft + tempTag.getLoc2DX()), 
(int) (centerY + tempTag.getLoc2DY()), 
0, 
0); 
mTextView.get(tempTag.getParamNo()).setTextSize((int)(tempTag.getTextSize() * tempTag.getScale())); 
int mergedColor = Color.argb( (int) (tempTag.getAlpha() * 255), 
(int) (tempTag.getColorR() * 255), 
(int) (tempTag.getColorG() * 255), 
(int) (tempTag.getColorB() * 255)); 
mTextView.get(tempTag.getParamNo()).setTextColor(mergedColor); 
mTextView.get(tempTag.getParamNo()).bringToFront(); 
} 
} 
/** 
* 点击事件 
* @param url 
* @return 
*/ 
View.OnClickListener OnTagClickListener(final String url){ 
return new View.OnClickListener(){ 
@Override 
public void onClick(View v) { 
} 
}; 
} 
} 

二、自定义迭代器

代码语言:javascript
复制
/** 
* 自定义的迭代器 
* @author Administrator 
* 
*/ 
public class TagCloud implements Iterable<Object { 
private List<Tag  tagCloud; 
private int radius; 
private static final int DEFAULT_RADIUS = 3; 
private static final int TEXT_SIZE_MAX = 30 , TEXT_SIZE_MIN= 4; 
private static final float[] DEFAULT_COLOR1= { 0.886f, 0.725f, 0.188f, 1f}; 
private static final float[] DEFAULT_COLOR2= { 0.3f, 0.3f, 0.3f, 1f}; 
private float[] tagColor1; 
private float[] tagColor2; 
private int textSizeMax, textSizeMin; 
private float sin_mAngleX,cos_mAngleX,sin_mAngleY,cos_mAngleY,sin_mAngleZ,cos_mAngleZ; 
private float mAngleZ=0; 
private float mAngleX =0; 
private float mAngleY =0; 
private int size=0; 
private int smallest,largest; 
private boolean distrEven = true; 
public TagCloud(){ 
this(new ArrayList<Tag ()); 
} 
public TagCloud(List<Tag  tags){ 
this(tags,DEFAULT_RADIUS); 
} 
public TagCloud(List<Tag  tags, int radius){ 
this( tags, radius, DEFAULT_COLOR1, DEFAULT_COLOR2, TEXT_SIZE_MIN, TEXT_SIZE_MAX); 
} 
public TagCloud(List<Tag  tags, int radius,int textSizeMin, int textSizeMax){ 
this( tags, radius, DEFAULT_COLOR1, DEFAULT_COLOR2, textSizeMin, textSizeMax); 
} 
public TagCloud(List<Tag  tags, int radius,float[] tagColor1, float[] tagColor2){ 
this( tags, radius, tagColor1, tagColor2, TEXT_SIZE_MIN, TEXT_SIZE_MAX); 
}   
public TagCloud(List<Tag  tags, int radius, float[] tagColor1, float[] tagColor2, 
int textSizeMin, int textSizeMax){ 
this.tagCloud=tags;  
this.radius = radius; 
this.tagColor1 = tagColor1; 
this.tagColor2 = tagColor2; 
this.textSizeMax = textSizeMax; 
this.textSizeMin = textSizeMin; 
} 
/** 
* 重写的方法 
*/ 
@Override 
public Iterator iterator() { 
return tagCloud.iterator(); 
} 
/** 
* 创建 
* @param distrEven 
*/ 
public void create(boolean distrEven){ 
this.distrEven =distrEven; 
positionAll(distrEven); 
sineCosine( mAngleX, mAngleY, mAngleZ); 
updateAll(); 
smallest = 9999; 
largest = 0; 
for (int i=0; i< tagCloud.size(); i++){ 
int j = tagCloud.get(i).getPopularity(); 
largest = Math.max(largest, j); 
smallest = Math.min(smallest, j); 
} 
Tag tempTag; 
for (int i=0; i< tagCloud.size(); i++){ 
tempTag = tagCloud.get(i); 
int j = tempTag.getPopularity(); 
float percentage = ( smallest == largest ) ? 1.0f : ((float)j-smallest) / ((float)largest-smallest); 
float[] tempColor = getColorFromGradient( percentage ); //(rgb Alpha) 
int tempTextSize = getTextSizeGradient( percentage ); 
tempTag.setColorR(tempColor[0]); 
tempTag.setColorG(tempColor[1]); 
tempTag.setColorB(tempColor[2]); 
tempTag.setTextSize(tempTextSize); 
}   
this.size= tagCloud.size(); 
} 
/** 
* create创建完,就需要update 
*/ 
public void update(){ 
if( Math.abs(mAngleX)   .1 || Math.abs(mAngleY)   .1 ){ 
sineCosine( mAngleX, mAngleY, mAngleZ); 
updateAll(); 
} 
} 
/** 
* 计算每个Tag的 
* @param distrEven 是否根据字计算位置 true为是,否则字有覆盖的 
*/ 
private void positionAll(boolean distrEven){ 
double phi = 0; 
double theta = 0; 
int max = tagCloud.size(); 
for (int i=1; i<max+1; i++){ 
if (distrEven){ 
phi = Math.acos(-1.0 + (2.0*i -1.0)/max); 
theta = Math.sqrt(max*Math.PI) * phi; 
} else{ 
phi = Math.random()*(Math.PI); 
theta = Math.random()*(2 * Math.PI); 
} 
tagCloud.get(i-1).setLocX((int)( (radius * Math.cos(theta) * Math.sin(phi)))); 
tagCloud.get(i-1).setLocY((int)(radius * Math.sin(theta) * Math.sin(phi))); 
tagCloud.get(i-1).setLocZ((int)(radius * Math.cos(phi))); 
}   
}  
/** 
* 更新所有的Tag位置 
*/ 
private void updateAll(){ 
int max = tagCloud.size(); 
for (int j=0; j<max; j++){ 
float rx1 = (tagCloud.get(j).getLocX()); 
float ry1 = (tagCloud.get(j).getLocY()) * cos_mAngleX + 
tagCloud.get(j).getLocZ() * -sin_mAngleX; 
float rz1 = (tagCloud.get(j).getLocY()) * sin_mAngleX + 
tagCloud.get(j).getLocZ() * cos_mAngleX;       
float rx2 = rx1 * cos_mAngleY + rz1 * sin_mAngleY; 
float ry2 = ry1; 
float rz2 = rx1 * -sin_mAngleY + rz1 * cos_mAngleY; 
float rx3 = rx2 * cos_mAngleZ + ry2 * -sin_mAngleZ; 
float ry3 = rx2 * sin_mAngleZ + ry2 * cos_mAngleZ; 
float rz3 = rz2; 
tagCloud.get(j).setLocX(rx3); 
tagCloud.get(j).setLocY(ry3); 
tagCloud.get(j).setLocZ(rz3); 
int diameter = 2 * radius; 
float per = diameter / (diameter+rz3); 
tagCloud.get(j).setLoc2DX((int)(rx3 * per)); 
tagCloud.get(j).setLoc2DY((int)(ry3 * per)); 
tagCloud.get(j).setScale(per); 
tagCloud.get(j).setAlpha(per / 2); 
}  
//给Tag排序 
Collections.sort(tagCloud);  
}  
/** 
* 计算字体颜色 
* @param perc 
* @return 
*/ 
private float[] getColorFromGradient(float perc){ 
float[] tempRGB = new float[4]; 
tempRGB[0] = ( perc * ( tagColor1[0] ) ) + ( (1-perc) * ( tagColor2[0] ) ); 
tempRGB[1] = ( perc * ( tagColor1[1] ) ) + ( (1-perc) * ( tagColor2[1] ) ); 
tempRGB[2] = ( perc * ( tagColor1[2] ) ) + ( (1-perc) * ( tagColor2[2] ) ); 
tempRGB[3] = 1; 
return tempRGB; 
} 
/** 
* 计算字体的大小 
* @param perc 
* @return 
*/ 
private int getTextSizeGradient(float perc){ 
int size; 
size = (int)( perc*textSizeMax + (1-perc)*textSizeMin ); 
return size; 
} 
/** 
* 计算圆形的x y z坐标 
* @param mAngleX 
* @param mAngleY 
* @param mAngleZ 
*/ 
private void sineCosine(float mAngleX,float mAngleY,float mAngleZ) { 
double degToRad = (Math.PI / 180); 
sin_mAngleX= (float) Math.sin( mAngleX * degToRad); 
cos_mAngleX= (float) Math.cos( mAngleX * degToRad); 
sin_mAngleY= (float) Math.sin( mAngleY * degToRad); 
cos_mAngleY= (float) Math.cos( mAngleY * degToRad); 
sin_mAngleZ= (float) Math.sin( mAngleZ * degToRad); 
cos_mAngleZ= (float) Math.cos( mAngleZ * degToRad); 
} 
/** 
* 以下是get set方法 
* @return 
*/ 
public int getRadius() { 
return radius; 
} 
public void setRadius(int radius) { 
this.radius = radius; 
} 
public float[] getTagColor1() { 
return tagColor1; 
} 
public void setTagColor1(float[] tagColor) { 
this.tagColor1 = tagColor; 
} 
public float[] getTagColor2() { 
return tagColor2; 
} 
public void setTagColor2(float[] tagColor2) { 
this.tagColor2 = tagColor2; 
} 
public float getRvalue(float[] color) { 
if (color.length 0) 
return color[0]; 
else 
return 0; 
} 
public float getGvalue(float[] color) { 
if (color.length 0) 
return color[1]; 
else 
return 0; } 
public float getBvalue(float[] color) { 
if (color.length 0) 
return color[2]; 
else 
return 0; } 
public float getAlphaValue(float[] color) { 
if (color.length  = 4) 
return color[3]; 
else 
return 0;  
}   
public float getAngleX() { 
return mAngleX; 
} 
public void setAngleX(float mAngleX) { 
this.mAngleX = mAngleX; 
} 
public float getAngleY() { 
return mAngleY; 
} 
public void setAngleY(float mAngleY) { 
this.mAngleY = mAngleY; 
} 
public int getSize() { 
return size; 
}  
} 

三、自定义数据

代码语言:javascript
复制
/** 
* Comparable接口 可以自定义排序方式 
* @author Administrator 
* 
*/ 
public class Tag implements Comparable<Tag { 
private String text, url; 
private int popularity; 
private int textSize; 
private float locX, locY, locZ; 
private float loc2DX, loc2DY; 
private float scale; 
private float colorR, colorG, colorB, alpha; 
private static final int DEFAULT_POPULARITY = 1; 
private int paramNo; 
public Tag(String text, int popularity) { 
this(text, 0f, 0f, 0f, 1.0f, popularity, ""); 
}  
public Tag(String text, int popularity, String url) { 
this(text, 0f, 0f, 0f, 1.0f, popularity, url); 
}  
public Tag(String text,float locX, float locY, float locZ) { 
this(text, locX, locY, locZ, 1.0f, DEFAULT_POPULARITY, ""); 
} 
public Tag(String text,float locX, float locY, float locZ, float scale) { 
this(text, locX, locY, locZ, scale, DEFAULT_POPULARITY, ""); 
} 
public Tag(String text,float locX, float locY, float locZ, float scale, int popularity, 
String url) { 
this.text = text; 
this.locX = locX; 
this.locY = locY; 
this.locZ = locZ; 
this.loc2DX = 0; 
this.loc2DY=0; 
this.colorR= 0.5f; 
this.colorG= 0.5f; 
this.colorB= 0.5f; 
this.alpha = 1.0f; 
this.scale = scale; 
this.popularity= popularity; 
this.url = url; 
}  
@Override 
public int compareTo(Tag another) { 
//排序方式 
return (int)(another.locZ - locZ); 
} 
public float getLocX() { 
return locX; 
} 
public void setLocX(float locX) { 
this.locX = locX; 
} 
public float getLocY() { 
return locY; 
} 
public void setLocY(float locY) { 
this.locY = locY; 
} 
public float getLocZ() { 
return locZ; 
} 
public void setLocZ(float locZ) { 
this.locZ = locZ; 
} 
public float getScale() { 
return scale; 
} 
public void setScale(float scale) { 
this.scale = scale; 
} 
public String getText() { 
return text; 
} 
public void setText(String text) { 
this.text = text; 
} 
public float getColorR() { 
return colorR; 
} 
public void setColorR(float colorR) { 
this.colorR = colorR; 
} 
public float getColorG() { 
return colorG; 
} 
public void setColorG(float colorG) { 
this.colorG = colorG; 
} 
public float getColorB() { 
return colorB; 
} 
public void setColorB(float colorB) { 
this.colorB = colorB; 
} 
public float getAlpha() { 
return alpha; 
} 
public void setAlpha(float alpha) { 
this.alpha = alpha; 
} 
public int getPopularity() { 
return popularity; 
} 
public void setPopularity(int popularity) { 
this.popularity = popularity; 
} 
public int getTextSize() { 
return textSize; 
} 
public void setTextSize(int textSize) { 
this.textSize = textSize; 
} 
public float getLoc2DX() { 
return loc2DX; 
} 
public void setLoc2DX(float loc2dx) { 
loc2DX = loc2dx; 
} 
public float getLoc2DY() { 
return loc2DY; 
} 
public void setLoc2DY(float loc2dy) { 
loc2DY = loc2dy; 
} 
public int getParamNo() { 
return paramNo; 
} 
public void setParamNo(int paramNo) { 
this.paramNo = paramNo; 
} 
public String getUrl() { 
return url; 
} 
public void setUrl(String url) { 
this.url = url; 
} 
} 

四、调用

代码语言:javascript
复制
private TagCloudView mTagCloudView; 
public void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
WindowManager.LayoutParams.FLAG_FULLSCREEN); 
Display display = getWindowManager().getDefaultDisplay(); 
@SuppressWarnings("deprecation") 
int width = display.getWidth(); 
@SuppressWarnings("deprecation") 
int height = display.getHeight(); 
List<Tag  myTagList= createTags(); 
mTagCloudView = new TagCloudView(this, width, height, myTagList ); 
setContentView(mTagCloudView); 
mTagCloudView.requestFocus(); 
mTagCloudView.setFocusableInTouchMode(true); 
} 
private List<Tag  createTags(){ 
List<Tag  tempList = new ArrayList<Tag (); 
tempList.add(new Tag("Google", 7, "http://www.google.com")); 
tempList.add(new Tag("Yahoo", 3, "www.yahoo.com")); 
tempList.add(new Tag("CNN", 4, "www.cnn.com")); 
tempList.add(new Tag("MSNBC", 5, "www.msnbc.com")); 
tempList.add(new Tag("CNBC", 5, "www.CNBC.com")); 
tempList.add(new Tag("Facebook", 7, "www.facebook.com")); 
tempList.add(new Tag("Youtube", 3, "www.youtube.com")); 
tempList.add(new Tag("BlogSpot", 5, "www.blogspot.com")); 
tempList.add(new Tag("Bing", 3, "www.bing.com")); 
tempList.add(new Tag("Wikipedia", 8, "www.wikipedia.com")); 
tempList.add(new Tag("Twitter", 5, "www.twitter.com")); 
tempList.add(new Tag("Msn", 1, "www.msn.com")); 
tempList.add(new Tag("Amazon", 3, "www.amazon.com")); 
tempList.add(new Tag("Ebay", 7, "www.ebay.com")); 
tempList.add(new Tag("LinkedIn", 5, "www.linkedin.com")); 
tempList.add(new Tag("Live", 7, "www.live.com")); 
tempList.add(new Tag("Microsoft", 3, "www.microsoft.com")); 
tempList.add(new Tag("Flicker", 1, "www.flicker.com")); 
tempList.add(new Tag("Apple", 5, "www.apple.com")); 
tempList.add(new Tag("Paypal", 5, "www.paypal.com")); 
tempList.add(new Tag("Craigslist", 7, "www.craigslist.com")); 
tempList.add(new Tag("Imdb", 2, "www.imdb.com")); 
tempList.add(new Tag("Ask", 4, "www.ask.com")); 
tempList.add(new Tag("Weibo", 1, "www.weibo.com")); 
tempList.add(new Tag("Tagin!", 8, "http://scyp.idrc.ocad.ca/projects/tagin")); 
tempList.add(new Tag("Shiftehfar", 8, "www.shiftehfar.org")); 
tempList.add(new Tag("Soso", 5, "www.google.com")); 
tempList.add(new Tag("XVideos", 3, "www.xvideos.com")); 
tempList.add(new Tag("BBC", 5, "www.bbc.co.uk")); 
return tempList; 
} 

源码下载地址点击打开链接

以上就是本文的全部内容,希望对大家的学习有所帮助。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-09-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档