android一个弹出菜单的动画(二)
假设做一个弹出的控件,我们能够进行加入view:
写class SatelliteMenu extends FrameLayout
private void init(Context context, AttributeSet attrs, int defStyle) {
		inflate(context, R.layout.sat_main, this);
		imgMain = (ImageView) findViewById(R.id.sat_main);
		if(attrs != null){
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SatelliteMenu, defStyle, 0);
			satelliteDistance = typedArray.getDimensionPixelSize(R.styleable.SatelliteMenu_satelliteDistance, DEFAULT_SATELLITE_DISTANCE);
			totalSpacingDegree = typedArray.getFloat(R.styleable.SatelliteMenu_totalSpacingDegree, DEFAULT_TOTAL_SPACING_DEGREES);
			closeItemsOnClick = typedArray.getBoolean(R.styleable.SatelliteMenu_closeOnClick, DEFAULT_CLOSE_ON_CLICK);
			expandDuration = typedArray.getInt(R.styleable.SatelliteMenu_expandDuration, DEFAULT_EXPAND_DURATION);
			//float satelliteDistance = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 170, getResources().getDisplayMetrics());
			typedArray.recycle();
		}
		mainRotateLeft = SatelliteAnimationCreator.createMainButtonAnimation(context);
		mainRotateRight = SatelliteAnimationCreator.createMainButtonInverseAnimation(context);
		Animation.AnimationListener plusAnimationListener = new Animation.AnimationListener() {
			@Override
			public void onAnimationStart(Animation animation) {
			}
			@Override
			public void onAnimationRepeat(Animation animation) {
			}
			@Override
			public void onAnimationEnd(Animation animation) {
				plusAnimationActive.set(false);
			}
		};
		mainRotateLeft.setAnimationListener(plusAnimationListener);
		mainRotateRight.setAnimationListener(plusAnimationListener);
		imgMain.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				SatelliteMenu.this.onClick();
			}
		});
		internalItemClickListener = new InternalSatelliteOnClickListener(this);
	}
<? xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:id="@+id/sat_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/sat_main"
android:layout_gravity="bottom|left"
/>
</merge> <resources>
<declare-styleable name="SatelliteMenu">
<attr name="expandDuration" format="integer" />
<attr name="closeOnClick" format="boolean" />
<attr name="totalSpacingDegree" format="float" />
<attr name="satelliteDistance" format="dimension" />
<attr name="mainImage" format="reference" />
</declare-styleable>
</resources>
然后写加入Item的逻辑:
public void addItems(List<SatelliteMenuItem> items) {
		menuItems.addAll(items);
		this.removeView(imgMain);
		TextView tmpView = new TextView(getContext());
		tmpView.setLayoutParams(new FrameLayout.LayoutParams(0, 0));
		float[] degrees = getDegrees(menuItems.size());
		int index = 0;
		for (SatelliteMenuItem menuItem : menuItems) {
			int finalX = SatelliteAnimationCreator.getTranslateX(
					degrees[index], satelliteDistance);
			int finalY = SatelliteAnimationCreator.getTranslateY(
					degrees[index], satelliteDistance);
			ImageView itemView = (ImageView) LayoutInflater.from(getContext())
					.inflate(R.layout.sat_item_cr, this, false);
			ImageView cloneView = (ImageView) LayoutInflater.from(getContext())
					.inflate(R.layout.sat_item_cr, this, false);
			itemView.setTag(menuItem.getId());
			cloneView.setVisibility(View.GONE);
			itemView.setVisibility(View.GONE);
			cloneView.setOnClickListener(internalItemClickListener);
			cloneView.setTag(Integer.valueOf(menuItem.getId()));
			FrameLayout.LayoutParams layoutParams = getLayoutParams(cloneView);
			layoutParams.bottomMargin = Math.abs(finalY);
			layoutParams.leftMargin = Math.abs(finalX);
			cloneView.setLayoutParams(layoutParams);<strong>//这里是将cloneView置于itemview动画结束的位置</strong>
			if (menuItem.getImgResourceId() > 0) {
				itemView.setImageResource(menuItem.getImgResourceId());
				cloneView.setImageResource(menuItem.getImgResourceId());
			} else if (menuItem.getImgDrawable() != null) {
				itemView.setImageDrawable(menuItem.getImgDrawable());
				cloneView.setImageDrawable(menuItem.getImgDrawable());
			}
			Animation itemOut = SatelliteAnimationCreator.createItemOutAnimation(getContext(), index,expandDuration, finalX, finalY);
			Animation itemIn = SatelliteAnimationCreator.createItemInAnimation(getContext(), index, expandDuration, finalX, finalY);
			Animation itemClick = SatelliteAnimationCreator.createItemClickAnimation(getContext());
			menuItem.setView(itemView);
			menuItem.setCloneView(cloneView);
			menuItem.setInAnimation(itemIn);
			menuItem.setOutAnimation(itemOut);
			menuItem.setClickAnimation(itemClick);
			menuItem.setFinalX(finalX);
			menuItem.setFinalY(finalY);
			itemIn.setAnimationListener(new SatelliteAnimationListener(itemView, true, viewToItemMap));
			itemOut.setAnimationListener(new SatelliteAnimationListener(itemView, false, viewToItemMap));
			itemClick.setAnimationListener(new SatelliteItemClickAnimationListener(this, menuItem.getId()));
			this.addView(itemView);
			this.addView(cloneView);
			viewToItemMap.put(itemView, menuItem);
			viewToItemMap.put(cloneView, menuItem);
			index++;
		}
		this.addView(imgMain);
	}
监听器:
	private static class SatelliteAnimationListener implements Animation.AnimationListener {
		private WeakReference<View> viewRef;
		private boolean isInAnimation;
		private Map<View, SatelliteMenuItem> viewToItemMap;
		public SatelliteAnimationListener(View view, boolean isIn, Map<View, SatelliteMenuItem> viewToItemMap) {
			this.viewRef = new WeakReference<View>(view);
			this.isInAnimation = isIn;
			this.viewToItemMap = viewToItemMap;
		}
		@Override
		public void onAnimationStart(Animation animation) {
			if (viewRef != null) {
				View view = viewRef.get();
				if (view != null) {
					SatelliteMenuItem menuItem = viewToItemMap.get(view);
					if (isInAnimation) {
						menuItem.getView().setVisibility(View.VISIBLE);
						menuItem.getCloneView().setVisibility(View.GONE);
					} else {
						menuItem.getCloneView().setVisibility(View.GONE);
						menuItem.getView().setVisibility(View.VISIBLE);
					}
				}
			}
		}
		@Override
		public void onAnimationRepeat(Animation animation) {
		}
		@Override
		public void onAnimationEnd(Animation animation) {
			if (viewRef != null) {
				View view = viewRef.get();
				if (view != null) {
					SatelliteMenuItem menuItem = viewToItemMap.get(view);
					if (isInAnimation) {
						menuItem.getView().setVisibility(View.GONE);
						menuItem.getCloneView().setVisibility(View.GONE);
					} else {
						menuItem.getCloneView().setVisibility(View.VISIBLE);
						menuItem.getView().setVisibility(View.GONE);
					}
				}
			}
		}
	}
必须重写onMeature:
	private void recalculateMeasureDiff() {
		int itemWidth = 0;
		if (menuItems.size() > 0) {
			itemWidth = menuItems.get(0).getView().getWidth();
		}
		measureDiff = Float.valueOf(satelliteDistance * 0.2f).intValue()
				+ itemWidth;
	}
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		recalculateMeasureDiff();
		int totalHeight = imgMain.getHeight() + satelliteDistance + measureDiff;
		int totalWidth = imgMain.getWidth() + satelliteDistance + measureDiff;
		System.out.println("====totalWidth="+totalWidth+"height="+totalHeight+"measureDiff="+measureDiff+"imgMain.getWidth()="+imgMain.getWidth());
		setMeasuredDimension(totalWidth, totalHeight);
	}
save和恢复activity的状态:
@Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState ss = new SavedState(superState);
ss.rotated = rotated;
ss.totalSpacingDegree = totalSpacingDegree;
ss.satelliteDistance = satelliteDistance;
ss.measureDiff = measureDiff;
ss.expandDuration = expandDuration;
ss.closeItemsOnClick = closeItemsOnClick;
return ss;
} @Override
protected void onRestoreInstanceState(Parcelable state) {
SavedState ss = (SavedState) state;
rotated = ss.rotated;
totalSpacingDegree = ss.totalSpacingDegree;
satelliteDistance = ss.satelliteDistance;
measureDiff = ss.measureDiff;
expandDuration = ss.expandDuration;
closeItemsOnClick = ss.closeItemsOnClick; super.onRestoreInstanceState(ss.getSuperState());
} static class SavedState extends BaseSavedState {
boolean rotated;
private float totalSpacingDegree;
private int satelliteDistance;
private int measureDiff;
private int expandDuration;
private boolean closeItemsOnClick; SavedState(Parcelable superState) {
super(superState);
} public SavedState(Parcel in) {
super(in);
rotated = Boolean.valueOf(in.readString());
totalSpacingDegree = in.readFloat();
satelliteDistance = in.readInt();
measureDiff = in.readInt();
expandDuration = in.readInt();
closeItemsOnClick = Boolean.valueOf(in.readString());
} @Override
public int describeContents() {
return 0;
} @Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(Boolean.toString(rotated));
out.writeFloat(totalSpacingDegree);
out.writeInt(satelliteDistance);
out.writeInt(measureDiff);
out.writeInt(expandDuration);
out.writeString(Boolean.toString(closeItemsOnClick));
} public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
} public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
效果图:
android一个弹出菜单的动画(二)的更多相关文章
- android一个弹出菜单的动画(一)
		先上效果图: 先写Layout文件: <?xml version="1.0" encoding="utf-8"? > <RelativeLay ... 
- 获得其他程序弹出菜单的内容(一个困扰许久的问题o(╯□╰)o)
		刚开始到现在公司的时候接到一个任务:开发一个activex控件,自动操作本地exe程序,当时遇到弹出菜单无法获取的问题,还好不影响,最近又遇到这个问题,绕不过去了,于是昨天花了一个上午百度了个遍,总算 ... 
- 关于MFC主菜单和右键弹出菜单
		一.主菜单.弹出菜单和右键菜单的概念: 主菜单是窗口顶部的菜单,一个窗口或对话框只能有一个主菜单,但是主菜单可以被更改(SetMenu()更改): 创建方式:CMenu::CreateMenu(voi ... 
- IOS实现弹出菜单效果MenuViewController(背景 景深 弹出菜单)
		在写项目时,要实现一个从下移上来的一个弹出菜单,并且背景变深的这么一个效果,在此分享给大家. 主要说一下思路及一些核心代码贴出来,要想下载源码, 请到:http://download.csdn.net ... 
- win32进阶之路:程序托盘图标+右键弹出菜单
		开场白 本次介绍两个非常棒且实用的技巧:程序托盘图标和右键弹出菜单,效果如下图. 程序托盘图标用了迅雷的图标,右键点击时候会弹出三个选项的菜单. 程序托盘图标设置 我会用尽可能清晰明了的步骤介绍方式 ... 
- Mui --- 弹出菜单
		mui框架内置了弹出菜单插件,弹出菜单显示内容不限,但必须包裹在一个含.mui-popover类的div中,如下即为一个弹出菜单内容: <div id="popover" c ... 
- [译]GLUT教程 - 弹出菜单基础
		Lighthouse3d.com >> GLUT Tutorial >> Pop-up Menus >> Popup Menus 弹出菜单也是GLUT的一部分.虽然 ... 
- 【Android UI设计与开发】7.底部菜单栏(四)PopupWindow 实现显示仿腾讯新闻底部弹出菜单
		前一篇文章中有用到 PopupWindow 来实现弹窗的功能.简单介绍以下吧. 官方文档是这样解释的:这就是一个弹出窗口,可以用来显示一个任意视图.出现的弹出窗口是一个浮动容器的当前活动. 1.首先来 ... 
- 【Android】创建Popwindow弹出菜单的两种方式
		方法一的Activity package com.app.test02; import android.app.Activity; import android.os.Bundle; import a ... 
随机推荐
- HDU 4861	 Couple doubi(找规律|费马定理)
			Couple doubi Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit ... 
- eclipse中tomcat启动项目 修改java代码不重启服务
			1.双击tomcat 2.选择modules 3.选中项目点击edit 4.去掉勾.去除auto reloading enabled 的选中 ,点击OK, 
- 【LINUX】SHELL syntax error:unexpected end of file
			解决思路: DOS下文件和Linux下文件格式差异问题导致的. DOS下的文本文件是以\r\n作为断行标志的,表示成十六进制就是0D 0A.而Unix下的文本文件是以\n作为断行标志的,表示成十六进制 ... 
- php知识(第2天)
			运算符 PHP中运算符一共分为9类: 赋值运算符, 算术运算符,比较运算符, 逻辑运算符, 错误抑制符, 三目运算符, 位运算符, 自操作运算符, 连接操作符 算术运算符 算术运算: 基本运算符: + ... 
- bmfont制作数字
			http://blog.csdn.net/z104207/article/details/20136401 
- 文件上传 PHP
			参考http://www.w3school.com.cn/php/php_file_upload.asp 文件上传实际上是一个文件复制的过程 当我们选中一个文件之后 php默认的tmp文件夹中就有 ... 
- 射频识别技术漫谈(11)——Mifare系列卡的共性
			Mifare是NXP公司生产的一系列遵守ISO14443A标准的射频卡,包Mifare S50.Mifare S70.Mifare UltraLight.Mifare Pro.Mifare Desfi ... 
- HDU 3415 Max Sum of Max-K-sub-sequence
			题目大意:找长度不超过k的最大字段和. 题解:单调队列维护之前k的最小值,思想是对于每一个入队的新元素,如果队尾元素比其大则一直删减,然后插入新元素,对于队首的元素若与当前枚举两相差超过k则直接删去. ... 
- Sicily-1153 解题报告
			一.原题中文大意. 1 2 3 4 5 6 7 8 9 10 11 12 13 ... 
- OC学习那些事:点语法
			1.使用自定义的方法创建get/set方法 Person.h文件: #import <Foundation/Foundation.h> @interface Person : NSObje ... 
