动画底部底图的布局更改

问题描述:

在我的应用程序中,我使用底部工作表(来自支持库),该工作表非常棒。现在我想在拖动表单的同时为布局更改设置动画。为此,我已经创建的BottomSheetCallback一个子类(这是normaly一个内部类片段的所以不在此CALSS使用的所有对象都在这里初始化):动画底部底图的布局更改

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; 
    } 
} 

正如你可以看到我还创建了两个Scene从不同布局文件和自定义Transition,以便在具有TransitionManager的场景之间进行动画制作。我的问题是,Transition应该基于slideOffset参数(范围为0-1),但TransitionManager在背景中使用Animation类,后者通常基于Android的时间。

我试图创建自定义Intapolator,但这不能正常工作。那么如何创建基于外部变量而不是准时的Transition

+3

您能否提供一个视觉示例。截图例子? –

+0

我不认为这是可能的。 BottomSheet偏移量的值从-1到1,并不总是在0和1或-1和0之间反弹。在某些情况下,它将从0.3开始并上升到1.0f。我过去也有同样的问题。我必须根据时间倾听状态变化事件的动画。 –

+0

您需要哪种类型的动画。 – Khemraj

我不确定这是否是您想要的,但可能不是使用过渡,您可以使用函数animate(),因为使用此功能可以更改有关动画的所有内容(时间,可见性等)。

## 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); 
} 

为了容易地滑动的东西关闭屏幕的底部,可以用代码,例如:

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

其中cardContainer是视图你正试图滑出屏幕。

查看完整示例中的blog post。请注意,您也可以使用translationY而不是yBy。另外,这样做的更通用的方法是使用下面的代码:

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)); 
} 

根据您的描述,我觉得你是想实现像谷歌地图底片的行为。随着底部片被拖动,布局改变。

如果这是你想什么来实现,那么你并不需要强制执行自定义动画,如bottomsheetdialog本身有一个父协调布局内部采用当这些动画行为。

以下是我如何实现相同行为的示例代码。这也使得FloatingActionButton无形当bottomsheet拖动到全屏幕大小:

  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 
    } 
    

    希望这可以解决您试图实现的目标。