2012-06-25 11 views
20

Ở lần nhấp đầu tiên của một nút, tôi muốn trượt View dọc theo trục x (bằng 200 pixel ở bên phải, hãy nói). Và trên nút bấm thứ hai của nút, tôi muốn trượt View quay lại trục x về vị trí ban đầu của nó.Cách tạo hoạt ảnh cho bản dịch của Chế độ xem

Các View.setTranslationX(float) phương pháp nhảy View đến các địa điểm ngang mục tiêu với các cuộc gọi myView.setTranslationX(200);myView.setTranslationX(0); tương ứng. Bất cứ ai cũng biết cách tôi có thể trượt các View đến vị trí ngang mục tiêu thay thế?

Lưu ý 1: Một TranslateAnimation là không tốt vì nó không thực sự di chuyển các View nhưng chỉ trình bày những ảo ảnh của nó di chuyển.

Note 2: Tôi đã không nhận ra tại thời điểm đặt ra câu hỏi rằng setTranslationX(float)setTranslationY(float) phương pháp được giới thiệu như là API Cấp 11. Nếu bạn đang nhắm mục tiêu Honeycomb (API Level 11) trở lên, sau đó Gautam Câu trả lời của K là đủ. Nếu không, hãy xem câu trả lời của tôi cho một giải pháp được đề xuất.

Trả lời

5

Điều này đã khiến tôi bối rối trong một vài ngày tới (làm việc trước Ice Cream Sandwich) nhưng tôi nghĩ Tôi cuối cùng cũng đã đến đó!(nhờ Gautam K và Mike Israel dẫn đầu) Cuối cùng tôi đã mở rộng View (FrameLayout) để bắt đầu dịch các hoạt ảnh phải/trái theo yêu cầu và nghe phần cuối của hoạt ảnh để di chuyển FrameLayout phải của tôi/trái như thích hợp, như sau:

public class SlidingFrameLayout extends FrameLayout 
{ 
    private final int durationMilliseconds = 1000; 
    private final int displacementPixels = 200; 

    private boolean isInOriginalPosition = true; 
    private boolean isSliding = false; 

    public SlidingFrameLayout(Context context) 
    { 
    super(context); 
    } 

    public SlidingFrameLayout(Context context, AttributeSet attrs) 
    { 
    super(context, attrs); 
    } 

    public SlidingFrameLayout(Context context, AttributeSet attrs, int defStyle) 
    { 
    super(context, attrs, defStyle); 
    } 

    @Override 
    protected void onAnimationEnd() 
    { 
    super.onAnimationEnd(); 

    if (isInOriginalPosition) 
     offsetLeftAndRight(displacementPixels); 
    else 
     offsetLeftAndRight(-displacementPixels); 

    isSliding = false; 
    isInOriginalPosition = !isInOriginalPosition; 
    } 

    @Override 
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) 
    { 
    super.onLayout(changed, left, top, right, bottom); 

    // need this since otherwise this View jumps back to its original position 
    // ignoring its displacement 
    // when (re-)doing layout, e.g. when a fragment transaction is committed 
    if (changed && !isInOriginalPosition) 
     offsetLeftAndRight(displacementPixels); 
    } 

    public void toggleSlide() 
    { 
    // check whether frame layout is already sliding 
    if (isSliding) 
     return; // ignore request to slide 

    if (isInOriginalPosition) 
     startAnimation(new SlideRightAnimation()); 
    else 
     startAnimation(new SlideLeftAnimation()); 

    isSliding = true; 
    } 

    private class SlideRightAnimation extends TranslateAnimation 
    { 
    public SlideRightAnimation() 
    { 
     super(
      Animation.ABSOLUTE, 0, 
      Animation.ABSOLUTE, displacementPixels, 
      Animation.ABSOLUTE, 0, 
      Animation.ABSOLUTE, 0); 

     setDuration(durationMilliseconds); 
     setFillAfter(false); 
    } 
    } 

    private class SlideLeftAnimation extends TranslateAnimation 
    { 
    public SlideLeftAnimation() 
    { 
     super(
      Animation.ABSOLUTE, 0, 
      Animation.ABSOLUTE, -displacementPixels, 
      Animation.ABSOLUTE, 0, 
      Animation.ABSOLUTE, 0); 

     setDuration(durationMilliseconds); 
     setFillAfter(false); 
    } 
    } 
} 

Và, cuối cùng, để trượt SlidingFrameLayout phải/trái, tất cả các bạn phải làm là gọi phương thức SlidingFrameLayout.toggleSlide(). Tất nhiên bạn có thể tinh chỉnh số này SlidingFrameLayout cho mục đích của bạn để trượt nhiều pixel hơn, để trượt lâu hơn, nhưng điều này là đủ để bạn bắt đầu :)

25

Hãy thử nhìn vào ObjectAnimator và siêu lớp Giá trị Animator nó

bạn có thể làm một cái gì đó như thế này ObjectAnimator anim = ObjectAnimator.ofFloat(this, "translationX", 0,200); và sau đó anim.start();

Sử dụng một giá trị boolean và chuyển đổi nó với 200,0 trong đối tượng làm phim hoạt hình để trượt lại

PS: bạn có thể sử dụng setDuration phương pháp để thiết lập bao lâu hình ảnh động cần thực hiện để hoàn thành

Edit:

Hãy thử nhìn vào support library mà cung cấp khả năng tương thích ngược.

Sửa

Như @AdilHussain chỉ ra có một thư viện gọi là nineoldandroids mà có thể được sử dụng với cùng mục đích trên android cũ.

+0

@AdilHussain: sau đó bạn phải triển khai chức năng với chuỗi trên điện thoại không hỗ trợ. Chỉ cần kiểm tra xem điện thoại có hỗ trợ hay viết một số dự phòng đơn giản. Đó là lựa chọn tốt nhất. – Gautam

+1

Tìm thấy thư viện tuyệt vời này, công việc: [http://nineoldandroids.com] (http://nineoldandroids.com). Thư viện có sẵn để tải xuống dưới dạng 'jar' từ đây: [https://github.com/JakeWharton/NineOldAndroids/downloads](https://github.com/JakeWharton/NineOldAndroids/downloads) –

+1

Có vẻ như tôi đã nói quá sớm. Khi thực hiện việc dịch bằng thư viện [nineoldandroids] (https://github.com/JakeWharton/NineOldAndroids) trên điện thoại cũ (pre-Honeycomb), các nút trong chế độ xem đã dịch dường như đã di chuyển nhưng vẫn có thể nhấp được ở vị trí cũ của chúng (và không phải vị trí mới của họ). Tôi đã gửi email cho tác giả của thư viện nhưng chưa nhận được phản hồi. –

2

Tôi gặp sự cố tương tự, TranslateAnimation thực sự di chuyển chế độ xem nếu bạn gọi setFillAfter now (android bug). Tôi đã phải làm một cái gì đó tương tự như vậy tôi đã nói, hey cho phép sử dụng một người nghe hoạt hình và sau đó chỉ cần di chuyển mọi thứ đến vị trí chính xác. Thật không may có một lỗi trên người nghe hoạt hình là tốt (stackoverflow solution). Vì vậy, tôi đã tạo lớp bố cục của riêng mình theo giải pháp trong số stackoverflow solution và tôi đã sẵn sàng để sử dụng :)

+0

Cảm ơn bạn đã trả lời và liên kết. Đi để cho thấy rằng bằng cách sử dụng 'TranslateAnimation' cho điều này là một chút lộn xộn. Khi tôi nói 'TranslateAnimation' không thực sự di chuyển khung nhìn (mặc dù sử dụng 'setFillAfter (true)'), tôi có nghĩa là các mục có thể nhấp vẫn còn ở vị trí ban đầu của chúng. Xem video này để biết ví dụ về ý tôi: [http://www.youtube.com/watch?v=VY3kMFrA3wU](http://www.youtube.com/watch?v=VY3kMFrA3wU) –

+1

yeah như lỗi với fillAfter. Mặc dù nút đầu tiên không hoạt động, sự khác biệt giữa hai nút là gì? – MikeIsrael

+1

Giải pháp mà tôi đề xuất vẫn nên hoạt động đối với tất cả các phiên bản. Tôi đã xây dựng một lớp bố trí tùy chỉnh mà Overrides onAnimationEnd() và ở đó tôi thay đổi marginleft của đối tượng khi cần thiết để di chuyển nó đến vị trí chính xác. – MikeIsrael