SoFunction
Updated on 2025-04-06

Android custom viewGroup to achieve click animation effect

This article shares the specific code for viewGroup to realize click animation effect display for your reference. The specific content is as follows

public class MyCustomView extends ViewGroup implements  {

  private OnMenuItemClickListener mMenuItemClickListener;

  /**
    * Click the callback interface of the submenu item
    */
  public interface OnMenuItemClickListener {
    void onClick(View view, int pos);
  }

  public void setOnMenuItemClickListener(
      OnMenuItemClickListener mMenuItemClickListener) {
     = mMenuItemClickListener;
  }

  public enum Status {
    OPEN, CLOSE
  }

  private int mRadius;
  /**
    * Menu status
    */
  private Status mCurrentStatus = ;
  /**
    * Main button of the menu
    */
  private View mCButton;

  public MyCustomView(Context context) {//Call through new object    this(context, null);
    ("jj", "super(context)");
  }

  public MyCustomView(Context context, AttributeSet attrs) {//Called when used in layout    this(context, attrs, 0);
    ("jj", "super(context, attrs)");
  }

  public MyCustomView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    ("jj", "super(context, attrs, defStyleAttr)");
    mRadius = (int) (TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics());
    ("jj", "mRadius1: " + mRadius);
    // Get the value of the custom attribute    TypedArray a = (attrs, , defStyleAttr, 0);
    mRadius = (int) (.MyCustomView_radius, TypedValue
        .applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100,
            getResources().getDisplayMetrics()));
    ("jj", "mRadius: " + mRadius);
    ();
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int count = getChildCount();
    for (int i = 0; i < count; i++) {
      // Measuring child      measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec);
    }
    (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);
        ();
        int cl = (int) (mRadius * ( / 2 / (count - 2)
            * i));
        int ct = (int) (mRadius * ( / 2 / (count - 2)
            * i));
        int cWidth = ();
        int cHeight = ();
        ct = getMeasuredHeight() - cHeight - ct;
        cl = getMeasuredWidth() - cWidth - cl;
        (cl, ct, cl + cWidth, ct + cHeight);
      }
    }
  }

  private void layoutCButton() {
    mCButton = getChildAt(0);
    (this);
    int width = ();
    int height = ();
    int l = getMeasuredWidth() - width;
    int t = getMeasuredHeight() - height;
    (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);
    (duration);
    (true);
    (anim);
  }

  /**
    * Switch menu
    */
  public void toggleMenu(int duration) {
    // Add pan and rotation animation to menuItem    int count = getChildCount();
    for (int i = 0; i < count - 1; i++) {
      final View childView = getChildAt(i + 1);
      ();
      int cl = (int) (mRadius * ( / 2 / (count - 2) * i));
      int ct = (int) (mRadius * ( / 2 / (count - 2) * i));

      AnimationSet animset = new AnimationSet(true);
      Animation tranAnim = null;
      int xflag = 1;
      int yflag = 1;
      // to open
      if (mCurrentStatus == ) {
        tranAnim = new TranslateAnimation(xflag * cl, 0, yflag * ct, 0);
        (true);
        (true);

      } else
      // to close
      {
        tranAnim = new TranslateAnimation(0, xflag * cl, 0, yflag * ct);
        (false);
        (false);
      }
      (true);
      (duration);
      ((i * 100) / count);
      (new () {

        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {
          if (mCurrentStatus == ) {
            ();
          }
        }
      });
      // Rotate animation      RotateAnimation rotateAnim = new RotateAnimation(0, 720,
          Animation.RELATIVE_TO_SELF, 0.5f,
          Animation.RELATIVE_TO_SELF, 0.5f);
      (duration);
      (true);
      (rotateAnim);
      (tranAnim);
      (animset);
      final int pos = i + 1;
      (new OnClickListener() {
        @Override
        public void onClick(View v) {
          if (mMenuItemClickListener != null)
            (childView, pos);
          menuItemAnim(pos - 1);
          changeStatus();

        }
      });
    }
    // Toggle menu status    changeStatus();
  }


  /**
    * Add menuItem click animation
    *
    * @param
    */
  private void menuItemAnim(int pos) {
    for (int i = 0; i < getChildCount() - 1; i++) {

      View childView = getChildAt(i + 1);
      if (i == pos) {
        (scaleBigAnim(300));
      } else {
        (scaleSmallAnim(300));
      }

      (false);
      (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);
    (scaleAnim);
    (alphaAnim);
    (duration);
    (true);
    return animationSet;

  }

  /**
    * Set an animation for larger and reduced transparency for the currently clicked 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);

    (scaleAnim);
    (alphaAnim);

    (duration);
    (true);
    return animationSet;

  }


  public boolean isOpen() {
    return mCurrentStatus == ;
  }


  /**
    * Toggle menu status
    */
  private void changeStatus() {
    mCurrentStatus = (mCurrentStatus ==  ? 
        : );
  }


}

:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <attr name="radius" format="dimension" />
  <declare-styleable name="MyCustomView">
    <attr name="radius" />
  </declare-styleable>
</resources>

Menu layout file:

< xmlns:andro
  xmlns:hyman="/apk/res-auto"
  xmlns:tools="/tools"
  android:
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  hyman:radius="160dp">

  <RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/composer_button">

    <ImageView
      android:
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_centerInParent="true"
      android:src="@drawable/composer_icn_plus" />
  </RelativeLayout>

  <ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/composer_music"
    android:tag="Music" />

  <ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/composer_place"
    android:tag="Place" />

  <ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/composer_sleep"
    android:tag="Sleep" />

  <ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/composer_thought"
    android:tag="Sun" />

  <ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/composer_with"
    android:tag="People" />

</>

Main interface layout file:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:andro
  android:layout_width="match_parent" android:layout_height="match_parent">

  <include layout="@layout/menu_right_bottom"/>

</RelativeLayout>

Use directly in the main program:

mMenu = (MyCustomView) findViewById(.id_menu);
(new () {
  @Override
  public void onClick(View view, int pos) {
    (, pos + ":" + (), Toast.LENGTH_SHORT).show();
  }
});
(new () {
  @Override
  public boolean onTouch(View v, MotionEvent event) {
    if(()){
      (300);
    }
    return false;
  }
});

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.