android一个弹出菜单的动画(二)「建议收藏」

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一个弹出菜单的动画(二)「建议收藏」

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/116085.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • spring整合log4j_spring连接数据库的配置

    spring整合log4j_spring连接数据库的配置常用日志框架log4j、log4j2(log4j的升级版,最常用的)、logback(spring boot默认)、Jboss-logging…等slf4 是日志接口规范,代码对接slf4,实现和具体日志框架解耦,无需修改编码即可切换日志框架。修改pom依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-st

  • android bioset 进程,kthrotlds(WatchDogs变种)查杀方法「建议收藏」

    android bioset 进程,kthrotlds(WatchDogs变种)查杀方法「建议收藏」virus&period;win32&period;parite&period;H病毒的查杀方法virus.win32.parite.H病毒的查杀方法昨天电脑中了virus.win32.parite.H病毒,搞了2个多小时最终搞定了.以下记录下我的解决方法.第一步:下载Win32.Parit…Linux系统木马后门查杀方法详解木马和后门的查杀是系统管理员一项长期需…

  • 国产达梦数据库学习笔记(一):NeoKylin7.0安装及配置与常用基础命令

    国产达梦数据库学习笔记(一):NeoKylin7.0安装及配置与常用基础命令国产达梦数据库学习笔记(一):NeoKylin7.0安装及配置与常用基础命令以VMwareWorkstationPro15环境下的NeoKylin7.0与DM8为例中标麒麟系统NeoKylin7.0安装1.安装包下载NeoKynlin7.0官网下载(填写表格内容即可):中标麒麟系统官网注意:ISO存放路径中避免出现中文2.在VMware上创建虚拟机在VMware主页选择“创建新的虚拟机”,出现以下页面选择“自定义(高机)”选择“安装程序光盘映像文件(iso)”,选择在中

  • MapReduce编程实例(一)

    MapReduce编程实例(一)前提准备:1.hadoop安装运行正常,请参考2.集成开发环境正常,请参考Ubuntu搭建Hadoop源码阅读环境开发示例:WordCount本示例详细的介绍如何在集成环境中运行第一个MapReduce程序WordCount

  • hashmap底层实现原理和源码分析(python底层源码)

    HashMap是Java开发中常用的集合,那么从我们创建一个空集合到,put添加、get获取元素经历了那些步骤呢?说明:以下源码基于JDK1.7,32位0.HashMap底层的数据结构是数组加链表的形式,存储结构如下图:1.创建一个新的HashMap集合的构造函数://初始默认数组的大小staticfinalintDEFAULT_INITIAL_CAPACITY=1&lt;&lt;…

  • 无显示屏 配置树莓派教程[通俗易懂]

    无显示屏 配置树莓派教程[通俗易懂]<无显示屏>配置树莓派教程0.相关链接#SDCardFormatter官网下载链接https://www.sdcard.org/downloads/formatter/eula_windows/index.html#Win32DiskImager下载链接https://sourceforge.net/projects/win32diskimager/#树莓派…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号