2017-08-13 13 views
25

私のアプリケーションでは、(サポートライブラリの)ボトムシートを使用しています。今、私は、シートが上にドラッグされている間、レイアウトの変更をアニメートしたいと思います。このために私は(これはnormalyこのcalssで使用されているすべてのオブジェクトがここに初期化されているそうではない断片の内部クラスです)BottomSheetCallbackのサブクラスを作成しました:ボトムシートのアニメーションレイアウト変更

public class MyBehavior extends BottomSheetBehavior.BottomSheetCallback { 

    Transition transition; 
    float lastOffset = 0; 
    Scene scene; 

    public PlayerBehavior() { 
     TransitionInflater inflater = TransitionInflater.from(getContext()); 
     transition = inflater.inflateTransition(R.transition.player); 
     //transition.setDuration(300); 

     scene = fullLayout; 

     transition.setInterpolator(new Interpolator() { 
      @Override 
      public float getInterpolation(float v) { 
       return lastOffset; 
      } 
     }); 
    } 

    @Override 
    public void onStateChanged(@NonNull View bottomSheet, int newState) { 
     if(newState == BottomSheetBehavior.STATE_DRAGGING) { 
      TransitionManager.go(scene, transition); 
     } 
    } 

    @Override 
    public void onSlide(View bottomSheet, final float slideOffset) { 
     scene = (slideOffset > lastOffset) ? smallLayout : fullLayout; 
     lastOffset = slideOffset; 
    } 
} 

私はまた異なるから2 Sceneを作成する見ることができるようにレイアウトファイルとカスタムTransitionを使用してTransitionManagerのシーン間でアニメーションを作成します。私の問題は、TransitionslideOffsetパラメータ(0-1の範囲)に基づいているべきですが、TransitionManagerは、通常はAndroidで時間ベースであるバックグラウンドでAnimationクラスを使用しています。

カスタムインターポレーターを作成しようとしましたが、これは正しく機能しません。ですから、外部変数に基づいており、時間通りではなく、Transitionをどのように作成できますか?

+3

視覚的な例がありますか。例えばスクリーンショット? –

+0

私はそれが可能ではないと思います。 BottomSheetオフセットは-1から1までの値を持ち、常に0と1または-1と0の間でバウンスするとは限りません。場合によっては、0.3から始まり1.0fまで上がる場合もあります。私は過去に同じ問題を抱えていました。私は時間に基づいて状態変化のイベントをアニメートする必要がありました。 –

+0

必要なアニメーションの種類。 – Khemraj

答えて

0

トランジションを使用するのではなく、この機能を使用することができますが、animate()という機能を使用することができます。この機能を使用すると、アニメーション(時間、可視性など)に関するすべてのことを変更できます。

0
## Translation Animation ## 
<?xml version="1.0" encoding="utf-8"?> 
<set 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:interpolator="@android:anim/accelerate_decelerate_interpolator" 
    android:fillAfter="true" 
    > 
    <translate 
     android:fromYDelta="100%p" 
     android:toYDelta="-30%p" 
     android:duration="900" /> 
</set> 

【主な活動】

@Override 
protected void onResume() { 
    super.onResume(); 
    Animation am= AnimationUtils.loadAnimation(this,R.anim.fadeout); 
    tv5.startAnimation(am); 
    Animation myanim= AnimationUtils.loadAnimation(this,R.anim.translate); 
    tv1.startAnimation(myanim); 
    myanim.setStartOffset(500); 
    Animation animation= AnimationUtils.loadAnimation(this,R.anim.translate); 
    animation.setStartOffset(1000); 
    tv2.startAnimation(animation); 
    Animation an= AnimationUtils.loadAnimation(this,R.anim.translate); 
    an.setStartOffset(1500); 
    tv3.startAnimation(an); 
    Animation ab= AnimationUtils.loadAnimation(this,R.anim.translate); 
    ab.setStartOffset(2000); 
    tv4.startAnimation(ab); 
    Animation ac= AnimationUtils.loadAnimation(this,R.anim.fadein); 
    ac.setStartOffset(2500); 
    btn1.startAnimation(ac); 
} 
0

を簡単に画面の下部をオフに何かをスライドするには、次のようなコードを使用することができます。

cardContainerが表示され
final int activityHeight = findViewById(android.R.id.content).getHeight(); 
cardContainer.animate().yBy(activityHeight - cardContainer.getY()).setDuration(SLIDE_OUT_DURATION); 

あなたは画面からスライドしようとしています。

完全な例はblog postを参照してください。 yByの代わりにtranslationYを使用することもできます。それをやってのもう一つの、より一般的な方法は、このコードを使用することです:

あなたの説明に基づいて
public static ViewPropertyAnimator slideOutToBottom(Context ctx, View view) { 
    final int screenHeight = ctx.getResources().getDisplayMetrics().heightPixels; 
    int[] coords = new int[2]; 
    view.getLocationOnScreen(coords); 
    return view.animate().translationY(screenHeight - coords[Y_INDEX]).setDuration(SLIDE_OUT_DURATION); 
} 

public static ViewPropertyAnimator slideInFromBottom(Context ctx, View view) { 
    final int screenHeight = ctx.getResources().getDisplayMetrics().heightPixels; 
    int[] coords = new int[2]; 
    view.getLocationOnScreen(coords); 
    view.setTranslationY(screenHeight - coords[Y_INDEX]); 
    return view.animate().translationY(0).setDuration(SLIDE_IN_DURATION).setInterpolator(new OvershootInterpolator(1f)); 
} 
1

、私は、Googleがボトムシートの挙動をマップするような何かを達成しようとしていると思います。 ボトムシートが上にドラッグされると、レイアウトが変更されます。

それはあなたが親コーディネーターレイアウトの内側に組み込まれた場合bottomsheetdialog自体がそれらのアニメーションの動作を持っているとして、あなたは、カスタムアニメーションを強制する必要はありません達成しようとしているものである場合。

ここでは、同じ動作を実装する方法のサンプルコードを示します。bottomsheetはフルスクリーンサイズまでドラッグすると、それはまた、目に見えないFloatingActionButtonを行います

  1. はあなたのメインのレイアウト内で使用したいbottomsheetdialogを作成

    public class CustomBottomDialog extends BottomSheetDialogFragment { 
    
    String mSomeName; 
    @Override 
    public void onCreate(@Nullable Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        // if some arguments are passed from the calling activity 
        mSomeName = getArguments().getString("some_name"); 
    
    
    } 
    
    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
        View bottomSheet = inflater.inflate(R.layout.bottomsheet_layout, container, false); 
        // initialise your bottomsheet_layout items here 
        TextView tvName = bottomSheet.findViewById(R.id.display_name); 
        tvName.setText(mSomeName); 
        tvName.setOnClickListener(new View.OnClickListener() { 
         @Override 
         public void onClick(View view) { 
          // do something here 
          ((MainActivity)getActivity()).doSomething(); 
         } 
        }); 
    
        return bottomSheet; 
    } 
    } 
    
  2. bottomsheet_layout:

    <android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
    
    <android.support.design.widget.FloatingActionButton 
    android:id="@+id/nav" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:src="@drawable/navigation_tilt_grey" 
    app:backgroundTint="@color/colorAccent" 
    app:elevation="3dp" 
    app:fabSize="normal" 
    android:layout_marginEnd="@dimen/activity_horizontal_margin" 
    app:layout_anchor="@+id/live_dash" 
    app:layout_anchorGravity="top|right" /> 
    
    <!--BottomSheet--> 
    
    <android.support.v4.widget.NestedScrollView 
    android:id="@+id/live_dash" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:background="#F3F3F3" 
    android:clipToPadding="true" 
    app:layout_behavior="android.support.design.widget.BottomSheetBe 
    havior" 
    tools:layout_editor_absoluteY="150dp"> 
    
    <!--Include your items here, the height of all items combined 
    will take the main screen layout size with animation--> 
    
    </android.support.v4.widget.NestedScrollView> 
    
    </android.support.design.widget.CoordinatorLayout> 
    
  3. あなたの活動からこのボトムシートを呼び出す:

    public void notifyBottomSheet(String somename){ 
    
    BottomSheetDialogFragment customDialogFragment = new CustomBottomDialog(); 
    Bundle args = new Bundle(); 
    args.putString("some_name", somename); 
    customDialogFragment.setArguments(args); 
    customDialogFragment.show(getSupportFragmentManager(), customDialogFragment.getTag()); 
    customDialogFragment.setCancelable(false); // if you don't wish to hide 
    } 
    

    これは、あなたが達成しようとしていることを解決したいと考えています。

関連する問題