zoukankan      html  css  js  c++  java
  • 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;
    	}

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

  • 相关阅读:
    poj 3528 (三维几何求凸包+凸包表面积)
    dijkstra模板(好像是斐波那契额堆优化,但我为什么看起来像优先队列优化,和spfa一样)
    最大空凸包模板
    ICPC 2017–2018, NEERC, Northern Subregional Contest St Petersburg, November 4, 2017 I题
    hdu 5248 序列变换
    hdu 2063(二分图模板测试)
    组合数
    85. Maximal Rectangle 由1拼出的最大矩形
    750. Number Of Corner Rectangles四周是点的矩形个数
    801. Minimum Swaps To Make Sequences Increasing 为使两个数组严格递增,所需要的最小交换次数
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5137595.html
Copyright © 2011-2022 走看看