如果做一个弹出的控件,我们可以进行添加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];
}
};
}