【问题标题】:Activity transition animation on root layout is executing on every EditText click根布局上的活动过渡动画在每次 EditText 单击时执行
【发布时间】:2017-05-29 07:10:13
【问题描述】:

我在活动过渡上应用显示效果,当 startActivity 被称为通过显示效果显示的活动时。 Activity是注册Activity,包含3个editText、一个imageView和一个拍照按钮。

问题是每当我选择或单击editText时,就会应用显示效果动画。

动画应用于根布局,动画在 OnCreate 方法中启动,我也尝试通过其他生命周期方法(如 onStart 和 onResume 方法)应用动画,但它正在工作。

很高兴地接受了答案。 这是代码的快照。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_add_contact);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    Name = (EditText) findViewById(R.id.enter_name_id);
    Mobile = (EditText) findViewById(R.id.enter_mobile_id);
    Email = (EditText) findViewById(R.id.enter_email_id);
    imageView = (ImageView) findViewById(R.id.set_image);

    LinearLayout rootview = (LinearLayout) findViewById(R.id.rootview);

    rootview.addOnLayoutChangeListener(new View.OnLayoutChangeListener() 
    {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, 
        int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) 
        {

            float finalRadius=
            (float)Math.hypot(v.getWidth(),v.getHeight());
            int cx1 = (v.getLeft() + v.getRight()) / 2;
            int cy1 = (v.getTop() + v.getBottom()) / 2;
            Animator anim = ViewAnimationUtils.createCircularReveal(v, 
            cx1, cy1, 0, finalRadius);
            anim.setDuration(1000);
            anim.setInterpolator(new AccelerateDecelerateInterpolator());
            anim.start();
        }
    });
}

【问题讨论】:

    标签: android android-layout animation


    【解决方案1】:

    您可以使用 globalLayoutListener 等待:

    final LinearLayout rootview = (LinearLayout) findViewById(R.id.rootview);
    rootview .getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        rootview .getViewTreeObserver().removeOnGlobalLayoutListener(this);
        // remove listener
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            //noinspection deprecation
            imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        } else {
            imageView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
    
        float finalRadius=
        (float)Math.hypot(rootview.getWidth(),rootview.getHeight());
        int cx1 = (rootview.getLeft() + rootview.getRight()) / 2;
        int cy1 = (rootview.getTop() + rootview.getBottom()) / 2;
        Animator anim = ViewAnimationUtils.createCircularReveal(v, 
        cx1, cy1, 0, finalRadius);
        anim.setDuration(1000);
        anim.setInterpolator(new AccelerateDecelerateInterpolator());
        anim.start();
    }
    });
    

    您可能不需要检查您不支持的旧版本 id 低于 JELLY_BEAN

    【讨论】:

    • 我正在为根布局而不是图像视图应用侦听器,或者你的意思是我必须将代码的 imageView 替换为 rootView... ...?????。我没有得到解释请。
    • 监听器可以添加到任何视图中,当布局完成时,它只会被调用一次
    • 嗨,我有一个问题,下面的代码(sarthak Gandhi)也可以正常工作。在这两个答案中,哪一个是高效的......?
    • 这个更好,因为它只在布局完成时被调用,下面的 done 等待任意超时,所以在最好的情况下它等待太久,在最坏的情况下,它不会等待足够长的时间,根本不起作用。
    • Tx 解释一下。
    【解决方案2】:

    你可以这样试试

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        ...
        ...
    
        final LinearLayout rootview = (LinearLayout) findViewById(R.id.rootview);
        ViewTreeObserver observer = rootview.getViewTreeObserver();
    
        if (observer.isAlive()) {
            observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    showLayout(rootview)
                    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                        rootview.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    } else {
                        rootview.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    }
                }
            });
        }
    
        ...
        ...
    }
    
    private void showLayout(@NonNull View v) {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            circularReveal(v);
        } else {
            v.setVisibility(View.VISIBLE);
        }
    }
    
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void circularReveal(@NonNull final View v) {
        float finalRadius = (float) Math.hypot(v.getWidth(), v.getHeight());
        int cx1 = (v.getLeft() + v.getRight()) / 2;
        int cy1 = (v.getTop() + v.getBottom()) / 2;
        Animator anim = ViewAnimationUtils.createCircularReveal(v, cx1, cy1, 0, finalRadius);
        anim.setDuration(1000);
        anim.setInterpolator(new AccelerateDecelerateInterpolator());
        v.setVisibility(View.VISIBLE);
        anim.start();
    }
    

    在xml父布局中放这个android:visibility="invisible"

    【讨论】:

      【解决方案3】:

      问题是,每当您单击图像或编辑文本时,都会调用 onLayoutChange 方法。只需在 onCreate 中开始您的动画,而不是将其放入 onLayoutChanged 中。

          root.post(new Runnable() {
              @Override
              public void run() {
                  float finalRadius =
                          (float) Math.hypot(root.getWidth(), root.getHeight());
                  int cx1 = (root.getLeft() + root.getRight()) / 2;
                  int cy1 = (root.getTop() + root.getBottom()) / 2;
                  Animator anim = ViewAnimationUtils.createCircularReveal(root,
                          cx1, cy1, 0, finalRadius);
                  anim.setDuration(1000);
                  anim.setInterpolator(new AccelerateDecelerateInterpolator());
                  anim.start();
              }
          });
      

      请试试这个。

      【讨论】:

      • 我厌倦了它,但它给出了运行时异常。 Caused by: java.lang.IllegalStateException: Cannot start this animator on a detached view! 在这一行 Animator anim = ViewAnimationUtils.createCircularReveal(v, cx1, cy1, 0, finalRadius);
      猜你喜欢
      • 2021-09-26
      • 1970-01-01
      • 2021-03-17
      • 1970-01-01
      • 2017-06-02
      • 2011-09-24
      • 1970-01-01
      • 2019-09-21
      • 1970-01-01
      相关资源
      最近更新 更多