自定义viewGroup实现点击动画效果
2016-11-13 23:41
591 查看
public class MyCustomView extends ViewGroup implements View.OnClickListener { private OnMenuItemClickListener mMenuItemClickListener; /** * 点击子菜单项的回调接口 */ public interface OnMenuItemClickListener { void onClick(View view, int pos); } public void setOnMenuItemClickListener( OnMenuItemClickListener mMenuItemClickListener) { this.mMenuItemClickListener = mMenuItemClickListener; } public enum Status { OPEN, CLOSE } private int mRadius; /** * 菜单的状态 */ private Status mCurrentStatus = Status.CLOSE; /** * 菜单的主按钮 */ private View mCButton; public MyCustomView(Context context) {//通过new对象来调用 this(context, null); Log.i("jj", "super(context)"); } public MyCustomView(Context context, AttributeSet attrs) {//在布局中使用时调用 this(context, attrs, 0); Log.i("jj", "super(context, attrs)"); } public MyCustomView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); Log.i("jj", "super(context, attrs, defStyleAttr)"); mRadius = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics()); Log.i("jj", "mRadius1: " + mRadius); // 获取自定义属性的值 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView, defStyleAttr, 0); mRadius = (int) a.getDimension(R.styleable.MyCustomView_radius, TypedValue .applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics())); Log.i("jj", "mRadius: " + mRadius); a.recycle(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int count = getChildCount(); 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(View.GONE); 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(); ct = getMeasuredHeight() - cHeight - ct; cl = getMeasuredWidth() - cWidth - cl; child.layout(cl, ct, cl + cWidth, ct + cHeight); } } } private void layoutCButton() { mCButton = getChildAt(0); mCButton.setOnClickListener(this); int width = mCButton.getMeasuredWidth(); int height = mCButton.getMeasuredHeight(); int l = getMeasuredWidth() - width; int t = getMeasuredHeight() - height; mCButton.layout(l, t, l + width, t + width); } @Override public void onClick(View v) { rotateCButton(v, 0f, 360f, 300); toggleMenu(300); } private void rotateCButton(View v, float start, float end, int duration) { RotateAnimation anim = new RotateAnimation(start, end, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); anim.setDuration(duration); anim.setFillAfter(true); v.startAnimation(anim); } /** * 切换菜单 */ 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(View.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)); AnimationSet animset = new AnimationSet(true); Animation tranAnim = null; int xflag = 1; int yflag = 1; // to open if (mCurrentStatus == Status.CLOSE) { tranAnim = new TranslateAnimation(xflag * cl, 0, yflag * ct, 0); childView.setClickable(true); childView.setFocusable(true); } else // to close { 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 onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { if (mCurrentStatus == Status.CLOSE) { childView.setVisibility(View.GONE); } } }); // 旋转动画 RotateAnimation rotateAnim = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); rotateAnim.setDuration(duration); rotateAnim.setFillAfter(true); animset.addAnimation(rotateAnim); 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 < getChildCount() - 1; i++) { View childView = getChildAt(i + 1); if (i == pos) { childView.startAnimation(scaleBigAnim(300)); } else { childView.startAnimation(scaleSmallAnim(300)); } childView.setClickable(false); childView.setFocusable(false); } } private Animation scaleSmallAnim(int duration) { AnimationSet animationSet = new AnimationSet(true); ScaleAnimation scaleAnim = new ScaleAnimation(1.0f, 0.0f, 1.0f, 0.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); AlphaAnimation alphaAnim = new AlphaAnimation(1f, 0.0f); animationSet.addAnimation(scaleAnim); animationSet.addAnimation(alphaAnim); animationSet.setDuration(duration); animationSet.setFillAfter(true); return animationSet; } /** * 为当前点击的Item设置变大和透明度降低的动画 * * @param duration * @return */ private Animation scaleBigAnim(int duration) { AnimationSet animationSet = new AnimationSet(true); ScaleAnimation scaleAnim = new ScaleAnimation(1.0f, 4.0f, 1.0f, 4.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); AlphaAnimation alphaAnim = new AlphaAnimation(1f, 0.0f); animationSet.addAnimation(scaleAnim); animationSet.addAnimation(alphaAnim); animationSet.setDuration(duration); animationSet.setFillAfter(true); return animationSet; } public boolean isOpen() { return mCurrentStatus == Status.OPEN; } /** * 切换菜单状态 */ private void changeStatus() { mCurrentStatus = (mCurrentStatus == Status.CLOSE ? Status.OPEN : Status.CLOSE); } } attrs.xml: <?xml version="1.0" encoding="utf-8"?> <resources> <attr name="radius" format="dimension" /> <declare-styleable name="MyCustomView"> <attr name="radius" /> </declare-styleable> </resources>菜单布局文件:<com.admom.mycanvas.view.MyCustomView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:hyman="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/id_menu"android:layout_width="match_parent"android:layout_height="match_parent"hyman:radius="160dp"><RelativeLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/composer_button"><ImageViewandroid:id="@+id/id_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_icn_plus" /></RelativeLayout><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/composer_music"android:tag="Music" /><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/composer_place"android:tag="Place" /><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/composer_sleep"android:tag="Sleep" /><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/composer_thought"android:tag="Sun" /><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/composer_with"android:tag="People" /></com.admom.mycanvas.view.MyCustomView>
主界面布局文件:
在主程序直接使用:mMenu = (MyCustomView) findViewById(R.id.id_menu);mMenu.setOnMenuItemClickListener(new MyCustomView.OnMenuItemClickListener() {@Overridepublic void onClick(View view, int pos) {Toast.makeText(MainActivity.this, pos + ":" + view.getTag(), Toast.LENGTH_SHORT).show();}});<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent" android:layout_height="match_parent"><include layout="@layout/menu_right_bottom"/></RelativeLayout>
mMenu.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {if(mMenu.isOpen()){mMenu.toggleMenu(300);}return false;}});
相关文章推荐
- Android自定义viewGroup实现点击动画效果
- Android开发 自定义ViewGroup 实现微信九格图功能(图片不同排布不同) 和 一种图片点击变暗效果
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu[转]
- 自定义ViewGroup 实现拖动跟快速滚动的效果
- 自定义控件之ImageView实现点击之后有阴影效果
- 自定义RecyclerView动画——实现remove飞出效果
- 安卓中自定义view控件代替radiogroup实现颜色渐变效果的写法
- 自定义ViewGroup 实现拖动跟快速滚动的效果
- RecyclerView介绍(五)----实现点击效果以及动画
- 自定义view实现阻尼效果的加载动画
- Android中使用自定义selector来实现view的点击效果以及view的显示样式
- Android自定义ViewGroup实现绚丽的仿支付宝咻一咻雷达脉冲效果
- TextView实现超链接并自定义点击效果
- Android自定义View: 如何实现类钟摆的动画效果?
- Android自定义控件系列五:自定义ViewGroup(一)实现ViewPager效果
- [置顶] 自定义view实现阻尼效果的加载动画
- Android属性动画与自定义View——实现vivo x6更新系统的动画效果
- android TextView 实现自定义文字点击效果
- 【安卓自定义控件】自定义ViewGroup实现透明背景的ViewPager效果
- 自定义ViewGroup实现水平布局空间不足自动换行的效果