2017-03-12 3 views
4

私は、インターフェイス内の1つのメソッドだけが大半の時間を使用するアニメーションリスナーを自分のコードに持っています。Javaで非機能インターフェイスでのラムダ式の使用

だから私はこのラッパーを作成しました:

public class AnimationWrapper { 
    private Animation mAnimation; 

    public AnimationWrapper(Animation animation) { 
     mAnimation = animation; 
    } 

    public Animation getAnimation() { 
     return mAnimation; 
    } 

    public interface OnAnimationEnd { 
     void onAnimationEnd(Animation animation); 
    } 

    public interface OnAnimationStart { 
     void onAnimationStart(Animation animation); 
    } 

    public void setAnimationEndListener(OnAnimationEnd listener) { 
     mAnimation.setAnimationListener(new Animation.AnimationListener() { 
      @Override 
      public void onAnimationStart(Animation animation) { 

      } 

      @Override 
      public void onAnimationEnd(Animation animation) { 
       listener.onAnimationEnd(animation); 
      } 

      @Override 
      public void onAnimationRepeat(Animation animation) { 

      } 
     }); 
    } 

    public void setAnimationStartListener(OnAnimationStart listener) { 
     mAnimation.setAnimationListener(new Animation.AnimationListener() { 
      @Override 
      public void onAnimationStart(Animation animation) { 
       listener.onAnimationStart(animation); 
      } 

      @Override 
      public void onAnimationEnd(Animation animation) { 

      } 

      @Override 
      public void onAnimationRepeat(Animation animation) { 

      } 
     }); 
    } 
} 

このようなその方法コード:

Animation animation = AnimationUtils.loadAnimation(context, R.anim.my_animation); 

animation.setAnimationListener(new Animation.AnimationListener() { 
    @Override 
    public void onAnimationStart(Animation animation) { 

    } 

    @Override 
    public void onAnimationEnd(Animation animation) { 
     doSomething(); 
    } 

    @Override 
    public void onAnimationRepeat(Animation animation) { 

    } 
}); 

はこのように見て終了します。

AnimationWrapper wrapper = new AnimationWrapper(AnimationUtils.loadAnimation(context, R.anim.my_animation)); 
    wrapper.setAnimationEndListener(a -> doSomething()); 

があるかどうか私は思ったんだけど1つの方法で非機能的なインターフェースを別々のインターフェースに分割し、それぞれの方法を使用できるようにするより良い方法ラムダ式とは別にただ

public interface OnAnimationEnd { 
    void onAnimationEnd(Animation animation); 
} 

public interface OnAnimationStart { 
    void onAnimationStart(Animation animation); 
} 

public class AnimationListeners { 
    public static Animation.AnimationListener adapt(OnAnimationStart oas) { 
     return new Animation.AnimationListener() { 
      @Override 
      public void onAnimationStart(Animation animation) { 
      } 

      @Override 
      public void onAnimationEnd(Animation animation) { 
       oas.onAnimationStart(animation); 
      } 

      @Override 
      public void onAnimationRepeat(Animation animation) { 
      } 
     }); 
    } 

    // same for the end 
} 

そして、あなたでしょう:

+0

空のメソッドを実装する抽象的なAnimationAdapterクラスはありますか? –

答えて

4

代わりにアニメーションをラップで、私は「本当」、マルチメソッドリスナー(つまりは、アダプタのデザインパターンを適用)に機能的な、ワンメソッドリスナーを包むだろうがこの方法を適応させるの静的インポートを

animation.setAnimationListener(AnimationListeners.adapt(a -> doSomething())); 

を使用し、それが

animation.setAnimationListener(adapt(a -> doSomething())); 
+0

コンパイラがあいまいであると不平を言うため、アダプタのメソッドに異なる名前を使用する必要がありました。 'onAnimationStartListener(OnAnimationStart oas)'、 'OnAnimationEndListener(OnAnimationEnd oas)'に変更されました。 – rraallvv

2
なり

AnimationListenerインスタンスを構築するためにbuilderパターンを適用することをお勧めします。便利なメソッドはConsumer<Application>です。それらをフィールドに保持し、最後のbuildフェーズでこれらの値を使用します。

既にConsumerが存在するため、独自のインターフェイスを掛ける必要はありません(すべての場合、3つの新しいConcumer<Animation>コピーが作成されます)。

私はAndroid APIに精通していないので、すぐに自分のクラスを書きました。アイデアは同じです。

class Animation {} 

// an analogue of the Animation.AnimationListener class 
interface AnimationListener { 
    void onAnimationStart(Animation animation); 
    void onAnimationEnd(Animation animation); 
} 

class AnimationListenerBuilder { 

    // do nothing by default (avoiding a NPE from the build method) 
    private Consumer<Animation> onAnimationStartCallback = animation -> {}; 
    private Consumer<Animation> onAnimationEndCallback = animation -> {}; 

    public AnimationListenerBuilder setOnAnimationStartCallback(Consumer<Animation> supplier) { 
     onAnimationStartCallback = supplier; 
     return this; 
    } 

    public AnimationListenerBuilder setOnAnimationEndCallback(Consumer<Animation> supplier) { 
     onAnimationEndCallback = supplier; 
     return this; 
    } 

    private AnimationListener build() { 
     return new AnimationListener() { 
      @Override 
      public void onAnimationStart(Animation animation) { 
       onAnimationStartCallback.accept(animation); 
      } 

      @Override 
      public void onAnimationEnd(Animation animation) { 
       onAnimationEndCallback.accept(animation); 
      } 

     }; 
    } 

    public static void main(String[] args) { 

     AnimationListenerBuilder builder = new AnimationListenerBuilder(); 

     AnimationListener listener = builder 
       .setOnAnimationEndCallback(animation -> {}) 
       .setOnAnimationEndCallback(animation -> {}) 
       .build(); 
    } 

} 
0

チェックアウトAnimatorListenerAdapter。これは、空のメソッドを提供することによってAnimation.AnimationListenerを実装する抽象クラスです。 AnimatorListenerAdapterを拡張するときは、必要なメソッドだけを実装する必要があります。このようなアダプターは、Javaイベント処理の共通パターンです。

+0

API 11で追加されたと思いますが、API 8が必要です。 – rraallvv

関連する問題