今天在慕课上又看了鸿洋大神的视频,学到了自定义卫星菜单。
大家点击如下链接就可进入慕课网看视频,很详细。
我在这里分享的是,我跟着鸿洋大神一起做的源码。
大概使用了4-5个小时,主要还是理解一些内容,和小bug的修改。
我呢,就把我所有写的全部放在这里,需要的朋友,直接复制就可以用了。
卫星菜单-慕课鸿洋大神
1.最重要的自定义控件:
package com.lgoutech.arcmenu.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import com.lgoutech.arcmenu.R;
import java.util.jar.Attributes;
/**
* Created by Administrator on 2017/11/29.
*/
public class ArcMenu extends ViewGroup implements View.OnClickListener {
private static final int POS_LEFT_TOP = 0;
private static final int POS_LEFT_BOTTOM = 1;
private static final int POS_RIGHT_TOP = 2;
private static final int POS_RIGHT_BOTTOM = 3;
private Position mPosition = Position.LEFT_BOTTOM;
private int mRadius;
/**
* 菜单的主按钮
*/
private View mCButton;
/**
* 菜单的状态
*/
private Status mCurrentStatus = Status.CLOSE;
public enum Status {
OPEN, CLOSE
}
private OnMenuItemClickListener mMenuItemClickListener;
/**
* 菜单的位置
*/
public enum Position {
LEFT_TOP, LEFT_BOTTOM, RIGHT_TOP, RIGHT_BOTTOM
}
/**
* 点击子菜单项的回调接口
*/
public interface OnMenuItemClickListener {
void onClick(View view, int pos);
}
public void setOnMenuItemClickListener(OnMenuItemClickListener mMenuItemClickListener) {
this.mMenuItemClickListener = mMenuItemClickListener;
}
// 使用this是为了调用第三个构造
public ArcMenu(Context context) {
this(context, null);
}
public ArcMenu(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ArcMenu(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//半径默认值
mRadius = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics());
//获取自定义属性的值
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ArcMenu, defStyleAttr, 0);
int pos = a.getInt(R.styleable.ArcMenu_position, POS_RIGHT_BOTTOM);
switch (pos) {
case POS_LEFT_TOP:
mPosition = Position.LEFT_TOP;
break;
case POS_LEFT_BOTTOM:
mPosition = Position.LEFT_BOTTOM;
break;
case POS_RIGHT_TOP:
mPosition = Position.RIGHT_TOP;
break;
case POS_RIGHT_BOTTOM:
mPosition = Position.RIGHT_BOTTOM;
break;
}
mRadius = (int) a.getDimension(R.styleable.ArcMenu_radius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics()));
Log.e("TAG", "position = " + mPosition + ",radius = " + mRadius);
a.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int count = getChildCount();
Log.e("Tag", "count=" + count);
for (int i = 0; i < count; i++) {
//测量child
measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed) {
layoutCButton();
int count = getChildCount();
for (int i = 0; i < count - 1; i++) {
View child = getChildAt(i + 1);
child.setVisibility(GONE);
// 子Item的位置
int cl = (int) (mRadius * Math.sin(Math.PI / 2 / (count - 2) * i));
int ct = (int) (mRadius * Math.cos(Math.PI / 2 / (count - 2) * i));
int cWidth = child.getMeasuredWidth();
int cHeight = child.getMeasuredHeight();
//如果菜单位置在底部,左下,右下
if (mPosition == Position.LEFT_BOTTOM || mPosition == Position.RIGHT_BOTTOM) {
ct = getMeasuredHeight() - cHeight - ct;
}
//右上,右下
if (mPosition == Position.RIGHT_TOP || mPosition == Position.RIGHT_BOTTOM) {
cl = getMeasuredWidth() - cWidth - cl;
}
child.layout(cl, ct, cl + cWidth, ct + cHeight);
}
}
}
/**
* 定位主菜单按钮
*/
private void layoutCButton() {
mCButton = getChildAt(0);
mCButton.setOnClickListener(this);
int l = 0;
int t = 0;
int width = mCButton.getMeasuredWidth();
int height = mCButton.getMeasuredHeight();
switch (mPosition) {
case LEFT_TOP:
l = 0;
t = 0;
break;
case LEFT_BOTTOM:
l = 0;
t = getMeasuredHeight() - height;
break;
case RIGHT_TOP:
//屏幕宽 - button 宽
l = getMeasuredWidth() - width;
t = 0;
break;
case RIGHT_BOTTOM:
l = getMeasuredWidth() - width;
t = getMeasuredHeight() - height;
break;
}
mCButton.layout(l, t, l + width, t + height);
}
@Override
public void onClick(View v) {
// mCButton = findViewById(R.id.id_button);
// if (mCButton == null) {
// mCButton=getChildAt(0)
// }
rotateCButton(v, 0f, 360f, 300);
toggleMenu(300);
}
/**
* 切换菜单
*/
public void toggleMenu(int duration) {
//为menuItem添加平移动画和旋转动画
int count = getChildCount();
for (int i = 0; i < count - 1; i++) {
final View childView = getChildAt(i + 1);
childView.setVisibility(VISIBLE);
int cl = (int) (mRadius * Math.sin(Math.PI / 2 / (count - 2) * i));
int ct = (int) (mRadius * Math.cos(Math.PI / 2 / (count - 2) * i));
int xflag = 1;
int yflag = 1;
if (mPosition == Position.LEFT_TOP || mPosition == Position.LEFT_BOTTOM) {
xflag = -1;
}
if (mPosition == Position.LEFT_TOP || mPosition == Position.RIGHT_TOP) {
yflag = -1;
}
AnimationSet animset = new AnimationSet(true);
Animation tranAnim = null;
if (mCurrentStatus == Status.CLOSE) {
tranAnim = new TranslateAnimation(xflag * cl, 0, yflag * ct, 0);
childView.setClickable(true);
childView.setFocusable(true);
} else {
tranAnim = new TranslateAnimation(0, xflag * cl, 0, yflag * ct);
childView.setClickable(false);
childView.setFocusable(false);
}
tranAnim.setFillAfter(true);
tranAnim.setDuration(duration);
tranAnim.setStartOffset(i * 100 / count);
tranAnim.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
if (mCurrentStatus == Status.CLOSE) {
childView.setVisibility(View.GONE);
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
//旋转动画
RotateAnimation rotateAnimation = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(duration);
rotateAnimation.setFillAfter(true);
animset.addAnimation(rotateAnimation);
animset.addAnimation(tranAnim);
childView.startAnimation(animset);
final int pos = i + 1;
childView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mMenuItemClickListener != null) {
mMenuItemClickListener.onClick(childView,pos);
}
menuItemAnim(pos-1);
changeStatus();
}
});
}
// 切换菜单状态
changeStatus();
}
/**
* 添加menuItem的点击动画
* @param
*/
private void menuItemAnim(int pos) {
for (int i=0;i
左下布局:
>
>
6.MainActivity:
package com.lgoutech.arcmenu;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import com.lgoutech.arcmenu.view.ArcMenu;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ListView mListView;
private List mDatas;
private ArcMenu mArcMenu;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initView();
mListView.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_activated_1, mDatas));
initEvent();
}
private void initView() {
mListView = findViewById(R.id.id_listview);
mArcMenu = findViewById(R.id.id_menu);
}
private void initEvent(){
mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (mArcMenu.isOpen()) {
mArcMenu.toggleMenu(500);
}
}
});
mArcMenu.setOnMenuItemClickListener(new ArcMenu.OnMenuItemClickListener() {
@Override
public void onClick(View view, int pos) {
Toast.makeText(MainActivity.this, pos + ":" + view.getTag(), Toast.LENGTH_SHORT).show();
}
});
}
private void initData() {
mDatas = new ArrayList<>();
for (int i = 'A'; i < 'Z'; i++) {
mDatas.add((char) i + "");
}
}
}
再次说一下:手抖了,资源分是5分,没有改,不好意思。
没有资源分的朋友请加我qq:657447928
注意备注:写上卫星菜单关联就可以。
大家还可以在慕课 鸿洋 卫星菜单中下载资源
也就是我上面的那个链接。
图片链接:http://download.csdn.net/download/lhk147852369/10137712