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


    效果图:




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

  • 相关阅读:
    使用YApi搭建API接口管理工具(docker安装)
    Redis 的持久化
    Typora编写markdown插入本地图片时自动上传图片到博客园
    关于python docker镜像环境下无法apt安装wkhtml2pdf的解决方案
    10分钟搞定让你困惑的 Jenkins 环境变量
    基于docker 搭建Prometheus+Grafana的过程详解
    docker方式搭建ELK日志平台
    ingress-nginx跨域解决
    k8s中pod优雅关闭进程
    java反编译命令
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5175987.html
Copyright © 2011-2022 走看看