2017-08-13 19 views
25

Trong ứng dụng của tôi, tôi sử dụng trang tính đáy (từ thư viện hỗ trợ) hoạt động tốt. Bây giờ tôi muốn tạo hiệu ứng thay đổi bố cục trong khi trang tính được kéo lên. Đối với điều này tôi đã tạo ra một lớp con của BottomSheetCallback (đây là normaly một lớp bên trong của một Fragment nên không phải tất cả đối tượng sử dụng trong calss này được khởi tạo ở đây):Thay đổi bố cục animate của trang tính dưới

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

Như bạn có thể thấy tôi cũng tạo ra hai Scene từ khác nhau tệp bố cục và tùy chỉnh Transition để tạo hoạt ảnh giữa các cảnh với TransitionManager. Vấn đề của tôi là Transition phải dựa trên thông số slideOffset (trong khoảng 0-1) nhưng TransitionManager sử dụng lớp Animation trong nền thường là thời gian dựa trên Android.

Tôi đã cố gắng tạo Intapolator tùy chỉnh nhưng điều này không hoạt động đúng cách. Vậy làm cách nào để tạo một Transition dựa trên biến số bên ngoài và không đúng giờ?

+3

Bạn có thể cung cấp ví dụ trực quan hay không. Ảnh chụp màn hình chẳng hạn? –

+0

Tôi không nghĩ điều đó là có thể. BottomSheet offset có giá trị từ -1 đến 1 và nó không phải luôn luôn bị trả giữa 0 và 1 hoặc -1 và 0. Trong một số trường hợp, nó sẽ bắt đầu ở 0,3 và tăng lên tới 1,0f. Tôi đã có cùng một vấn đề trong quá khứ. Tôi đã phải lắng nghe các sự kiện thay đổi nhà nước animate dựa trên thời gian. –

+0

Loại animate nào bạn cần. – Khemraj

Trả lời

0

Tôi không chắc nếu đó là những gì bạn muốn nhưng có thể thay vì sử dụng chuyển tiếp, bạn có thể sử dụng chức năng animate() vì với chức năng này, bạn có thể thay đổi tất cả mọi thứ về hoạt ảnh của bạn (thời gian, khả năng hiển thị, vv).

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> 

## Main Hoạt động ##

@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

Để dễ dàng trượt một cái gì đó ra khỏi đáy của màn hình, bạn có thể sử dụng mã như:

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

nơi cardContainer là quan điểm bạn đang cố gắng trượt khỏi màn hình.

Xem ví dụ này blog post để có ví dụ hoàn chỉnh. Lưu ý rằng bạn cũng có thể sử dụng translationY thay vì yBy. Một cách khác, chung chung hơn để thực hiện việc đó là với mã này:

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

Dựa trên mô tả của bạn, tôi nghĩ bạn đang cố gắng đạt được điều gì đó như hành vi bản đồ dưới cùng của bản đồ google. Bố cục thay đổi khi bảng màu dưới cùng được kéo lên.

Nếu đó là những gì bạn đang cố gắng để đạt được thì bạn không cần phải thi hành hình động tùy chỉnh, như bottomsheetdialog chính nó có những hành vi hoạt khi kết hợp bên trong một mẹ Điều phối Giao diện.

Đây là mã mẫu về cách tôi triển khai cùng một hành vi.Nó cũng làm cho FloatingActionButton vô hình khi bottomsheet được kéo lên đến kích thước màn hình đầy đủ:

  1. Tạo một bottomsheetdialog mà bạn muốn sử dụng bên trong bố trí chính của bạn

    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. Gọi BottomSheet này từ hoạt động của bạn:

    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 
    } 
    

    Hy vọng điều này sẽ giải quyết những gì bạn đang cố gắng đạt được.

Các vấn đề liên quan