首页 > 系统 > Android > 正文

Android实现3D云标签效果

2019-10-22 18:10:22
字体:
来源:转载
供稿:网友

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

Android,3D云标签

一、自定义View

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) {         }   };  } } 

二、自定义迭代器

/**  * 自定义的迭代器  * @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;  }   } 

三、自定义数据

/**  * 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;  }  } 

四、调用

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; } 

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VEVB武林网。


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表