2013-08-06 36 views

Trả lời

52

Predraw nghe, còn gọi là Safeway

Dưới đây là ví dụ người nghe predraw. Nó theo nghĩa đen sẽ bắt đầu hoạt hình ngay sau khi nó có thể có một chút quá nhanh. Bạn có thể muốn làm một sự kết hợp của điều này với một runnable hiển thị thứ hai. Tôi sẽ không hiển thị hai kết hợp, chỉ riêng biệt.

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    ... 
    // Building NavDrawer logic here. Just a method call would be best. 
    ... 

    ViewTreeObserver vto = drawer.getViewTreeObserver(); 
    if (vto != null) vto.addOnPreDrawListener(new ShouldShowListener(drawer)); 
} 

private static class ShouldShowListener implements OnPreDrawListener { 

    private final DrawerLayout drawerLayout; 

    private ShouldShowListener(DrawerLayout drawerLayout) { 
     this.drawerLayout= drawerLayout; 
    } 

    @Override 
    public boolean onPreDraw() { 
     if (view != null) { 
      ViewTreeObserver vto = view.getViewTreeObserver(); 
      if (vto != null) { 
       vto.removeOnPreDrawListener(this); 
      } 
     } 

     drawerLayout.openDrawer(Gravity.LEFT); 
     return true; 
    } 
} 

PostDelay Runnable, aka sống nguy hiểm

// Delay is in milliseconds 
static final int DRAWER_DELAY = 200; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    ... 
    // Building NavDrawer logic here. Just a method call would be best. 
    ... 
    new Handler().postDelayed(openDrawerRunnable(), DRAWER_DELAY); 
} 

private Runnable openDrawerRunnable() { 
    return new Runnable() { 

     @Override 
     public void run() { 
      drawerLayout.openDrawer(Gravity.LEFT); 
     } 
    } 
} 

CẢNH BÁO

Nếu họ xoay về sự bắt đầu của ứng dụng lần đầu tiên BOOM! Đọc bài đăng trên blog này để biết thêm thông tin http://corner.squareup.com/2013/12/android-main-thread-2.html. Điều tốt nhất để làm là sử dụng trình thu thập trước hoặc loại bỏ runnable của bạn trong onPause.

+1

Nếu 200ms không đủ trong mọi trường hợp thì sao? – Zordid

+0

Sau đó, làm cho nó bất cứ điều gì chiều dài bạn cần. – MinceMan

+1

Đó không phải là ý tôi. Cách tiếp cận này không tốt - nó không thành công bất cứ khi nào việc chuẩn bị mất nhiều thời gian hơn dự kiến. "Chúc may mắn" như bạn đặt nó thực sự phù hợp ... :-) – Zordid

6

Bạn có thể gọi openDrawer(int gravity) trên DrawerLayout để làm cho nó mở ngăn chứa bằng hoạt ảnh.

+0

Tôi gọi nó trong phương thức onStart() của Hoạt động phân đoạn, ngăn kéo hiển thị mà không có hoạt ảnh. Tôi đang gọi sai địa điểm hay tôi nên đặt giá trị trọng lực nào cho tham số? – benleung

+0

Nếu nó sắp ra bên trái ứng dụng của bạn, như là điển hình, hãy sử dụng Gravity.LEFT. Xem nếu điều đó giúp. Nếu không, hãy thử gọi nó sau này trong vòng đời của phân đoạn, chẳng hạn như onResume. – Brayden

+0

Nếu tôi gọi nó trong onResume(), điều đó có nghĩa là ngăn kéo sẽ mở ngay cả khi chuyển đổi nhiều tác vụ? – benleung

0

Bạn cần gọi số drawerLayout.openDrawer(Gravity.LEFT) để tạo hiệu ứng cho ngăn mở ngăn. Ngăn kéo sẽ không hoạt ảnh nếu bạn thực hiện cuộc gọi quá sớm trong vòng đời Hoạt động.

Giải pháp đơn giản nhất là chỉ cần đặt cờ trong onCreate() và hành động trên nó trong onResume().

Bạn muốn đảm bảo rằng bạn chỉ đặt cờ khi savedInstanceState là null cho biết Activity không được tiếp tục từ nền. Bạn không muốn ngăn kéo trượt ra mỗi khi bạn thay đổi hướng hoặc chuyển đổi ứng dụng.

public class MainActivity extends ActionBarActivity { 
    private DrawerLayout drawerLayout; 
    private boolean firstResume = false; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     drawerLayout = (DrawerLayout)findViewById(R.id.drawer); 

     if(savedInstanceState == null){ 
      firstResume = true; 
     } 
    } 

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

     if(firstResume) { 
      drawerLayout.openDrawer(Gravity.LEFT); 
     } 

     firstResume = false; 
    } 
} 

Bạn cũng có thể sử dụng một OnPreDrawListener nhưng tôi cảm thấy đó là một chút không cần thiết phức tạp như onPreDraw được gọi là nhiều lần, do đó bạn cần phải loại bỏ người nghe sau khi mở ngăn kéo. Bạn cũng giả định rằng preDraw là một thời điểm thích hợp để kích hoạt ngăn kéo, đó là việc thực hiện nội bộ của bố cục ngăn kéo. Triển khai trong tương lai có thể không hoạt ảnh chính xác cho đến sau khi onDraw chẳng hạn.

Việc trì hoãn việc mở ngăn bằng một số tùy ý mili giây là một cách nguy hiểm để giải quyết vấn đề này. Trong trường hợp xấu nhất, lệnh gọi để mở ngăn kéo có thể xảy ra sau khi onDestroy nếu người dùng điều hướng nhanh chóng.