假设做一个弹出的控件,我们能够进行加入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];
}
};
}

效果图:

代码:http://download.csdn.net/detail/baidu_nod/7731115

android一个弹出菜单的动画(二)的更多相关文章

  1. android一个弹出菜单的动画(一)

    先上效果图: 先写Layout文件: <?xml version="1.0" encoding="utf-8"? > <RelativeLay ...

  2. 获得其他程序弹出菜单的内容(一个困扰许久的问题o(╯□╰)o)

    刚开始到现在公司的时候接到一个任务:开发一个activex控件,自动操作本地exe程序,当时遇到弹出菜单无法获取的问题,还好不影响,最近又遇到这个问题,绕不过去了,于是昨天花了一个上午百度了个遍,总算 ...

  3. 关于MFC主菜单和右键弹出菜单

    一.主菜单.弹出菜单和右键菜单的概念: 主菜单是窗口顶部的菜单,一个窗口或对话框只能有一个主菜单,但是主菜单可以被更改(SetMenu()更改): 创建方式:CMenu::CreateMenu(voi ...

  4. IOS实现弹出菜单效果MenuViewController(背景 景深 弹出菜单)

    在写项目时,要实现一个从下移上来的一个弹出菜单,并且背景变深的这么一个效果,在此分享给大家. 主要说一下思路及一些核心代码贴出来,要想下载源码, 请到:http://download.csdn.net ...

  5. win32进阶之路:程序托盘图标+右键弹出菜单

     开场白 本次介绍两个非常棒且实用的技巧:程序托盘图标和右键弹出菜单,效果如下图. 程序托盘图标用了迅雷的图标,右键点击时候会弹出三个选项的菜单. 程序托盘图标设置 我会用尽可能清晰明了的步骤介绍方式 ...

  6. Mui --- 弹出菜单

    mui框架内置了弹出菜单插件,弹出菜单显示内容不限,但必须包裹在一个含.mui-popover类的div中,如下即为一个弹出菜单内容: <div id="popover" c ...

  7. [译]GLUT教程 - 弹出菜单基础

    Lighthouse3d.com >> GLUT Tutorial >> Pop-up Menus >> Popup Menus 弹出菜单也是GLUT的一部分.虽然 ...

  8. 【Android UI设计与开发】7.底部菜单栏(四)PopupWindow 实现显示仿腾讯新闻底部弹出菜单

    前一篇文章中有用到 PopupWindow 来实现弹窗的功能.简单介绍以下吧. 官方文档是这样解释的:这就是一个弹出窗口,可以用来显示一个任意视图.出现的弹出窗口是一个浮动容器的当前活动. 1.首先来 ...

  9. 【Android】创建Popwindow弹出菜单的两种方式

    方法一的Activity package com.app.test02; import android.app.Activity; import android.os.Bundle; import a ...

随机推荐

  1. C++ const 限定符

    C++ const 限定符 作用:把一个对象转换成一个常量 用法:const type name = value; 性质:1. 定义时必须初始化,定义后不能被修改.2. 类中的const成员变量必须通 ...

  2. 我用过的linux命令--安装Hadoop

    1. hadoop软件传送给虚拟机 还是利用WinSCP把hadoop软件安装包,放到linux的Downloads文件夹中. 2. 选择安装目录 把hadoop安装包copy到这个安装目录中,这里我 ...

  3. bzoj 1196: [HNOI2006]公路修建问题 二分+并查集

    题目链接 1196: [HNOI2006]公路修建问题 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1576  Solved: 909[Submit ...

  4. jQuery File Upload 插件 php代码分析

    jquery file upload php代码分析首先进入构造方法 __construct() 再进入 initialize()因为我是post方式传的数据  在进入initialize()中的po ...

  5. Windows下Python中的中文路径和中文输出问题

    这几天有个项目需要写一点类似于脚本的小程序,就用Python写了,涉及到中文路径和中文输出的问题,整理一下. 有一个问题我觉得需要先强调一下,在写Python程序的时候,一定保证编码是utf-8,然后 ...

  6. 3_Guess Fingers

    3 // // ViewController.swift // Guess Fingers // // Created by ZC on 16/1/8. // Copyright © 2016年 ZC ...

  7. nginx 重写 rewrite 基础及实例(转)

    nginx rewrite 正则表达式匹配 大小写匹配 ~ 为区分大小写匹配 ~* 为不区分大小写匹配 !~和!~*分别为区分大小写不匹配及不区分大小写不匹配 文件及目录匹配 -f和!-f用来判断是否 ...

  8. python开发_大小写转换,首字母大写,去除特殊字符

    这篇blog主要是总结我们在平常开发过程中对字符串的一些操作: #字母大小写转换 #首字母转大写 #去除字符串中特殊字符(如:'_','.',',',';'),然后再把去除后的字符串连接起来 #去除' ...

  9. BZOJ 1192 鬼谷子的钱袋 (二进制思想)

    题解:鉴于二进制的思想来划分 #include <cstdio> int main(){ int n,d=0;scanf("%d",&n); while(1&l ...

  10. Noip2010提高组总结

    将Noip2010重新做了一遍,第一遍做下来居然只有290分,比当年浙江的一等线低了20分,因为各种坏习惯丢掉了许多分数,Noip时需要特别注意! T1:机器翻译 第一题直接暴力,内存足够所以不用循环 ...