2011-11-02 30 views
8

Vì vậy, tôi có bố trí khác nhau cho Hoạt động này.Injectview (Roboguice) không hoạt động với nhiều bố cục

Và tôi có các lớp khác nhau mà mỗi lớp mở và làm việc với bố cục.

Tôi tiêm các lớp này vào Hoạt động qua @Inject. Tất cả điều này là không có vấn đề.

Nhưng khi tôi cố gắng sử dụng @InjectView trên một trong các điều khiển nằm trong bố cục không hoạt động, tôi gặp lỗi.

11-02 19: 17: 31,086: ERROR/AndroidRuntime (1326): Nguyên nhân: java.lang.NullPointerException: Không thể bơm giá trị null vào lớp be.baes.notes.View.EditNoteImpl .saveButton khi trường không phải là @Nullable

Đây sẽ là mã.

public class EditNoteImpl implements EditNote { 
    @Inject CancelEditNoteClickListener cancelEditNoteClickListener; 
    @Inject SaveNoteClickListener saveNoteClickListener; 
    @Inject Provider<Activity> activity; 
    @InjectView(R.id.saveButton) Button saveButton; 

    /* (non-Javadoc) 
    * @see be.baes.notes.EditNote#activateEditNote() 
    */ 
    @Override 
    public void activateEditNote() 
    { 
     activity.get().setContentView(R.layout.editnote); 

     this.saveButton.setOnClickListener(saveNoteClickListener); 
    } 
} 

Tuy nhiên, tôi có thể thực hiện việc này.

public class EditNoteImpl implements EditNote { 
    @Inject CancelEditNoteClickListener cancelEditNoteClickListener; 
    @Inject SaveNoteClickListener saveNoteClickListener; 
    @Inject Provider<Activity> activity; 
    private Button saveButton; 

    /* (non-Javadoc) 
    * @see be.baes.notes.EditNote#activateEditNote() 
    */ 
    @Override 
    public void activateEditNote() 
    { 
     activity.get().setContentView(R.layout.editnote); 
     saveButton = (Button)activity.get().findViewById(R.id.saveButton); 

     this.saveButton.setOnClickListener(saveNoteClickListener); 
    } 
} 

Có cách nào tốt hơn để thực hiện việc này không?

+0

Có lý do gì khiến nút @Nullable không phải là một tùy chọn không? –

+0

Tôi đã thử điều đó, nhưng điều đó cũng không tiêm nút. – chrissie1

+0

Bạn đang sử dụng RoboGuice 2.0? Điều này * có thể * làm việc trong 2.0 – emmby

Trả lời

4

Tôi vừa bắt đầu sử dụng roboguice để người khác có kinh nghiệm hơn có thể có thể đưa ra một câu trả lời tốt hơn, nhưng đây là những gì tôi tìm thấy cho đến nay:

  • Trong roboguice-1.1.2 (các bản phát hành ổn định hiện tại), @InjectView mục được tiêm chỉ khi setContentView() được gọi là lần đầu tiên trong Hoạt động. Vì mã của bạn gọi setContentView() động từ các lớp phụ trợ, các mục được tiêm sẽ không được tiêm chính xác.

  • Trong roboguice-2.0b2 (bản beta hiện tại), có hỗ trợ cho nhiều cuộc gọi setContentView() và mã của bạn sẽ hoạt động. Tuy nhiên, các khung nhìn được tiêm vẫn được gắn với ngữ cảnh Hoạt động (thay vì lớp khai báo), vì vậy, mỗi @InjectView cũng có thể cần phải là @Nullable trên tất cả các lớp phụ trợ chia sẻ cùng một Hoạt động.

Kể từ khi vấn đề ở đây dường như được bắt nguồn từ cách bố trí nhiều (và do đó nhiều setContentView() cuộc gọi) trong một Hoạt động duy nhất, một cách khác để làm những gì bạn muốn là để tránh nó như sau:

  • Thay vì có nhiều bố trí, sử dụng một cách bố trí đơn sử dụng thẻ <include/> để tải tất cả các bố trí thành một FrameLayout mẹ:
<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" > 

    <include layout="@layout/layout1" /> 

    <include layout="@layout/layout2" /> 

    <!-- other layouts... --> 

</FrameLayout> 
  • sau đó, thay vì gọi setContentView(), sử dụng một phương pháp mà sẽ chuyển đổi cách bố trí có thể nhìn thấy trên các hoạt động, một cái gì đó như thế này:
// instead of: activity.setContentView(R.layout.layout1); 
// use: activity.showLayout(R.id.layoutview1); 
public void showLayout(int layoutViewId) { 
    final View view = findViewById(layoutViewId); 
    final ViewGroup root = (ViewGroup) view.getParent(); 
    for (int i = 0; i < root.getChildCount(); i++) { 
     final View v = root.getChildAt(i); 
     v.setVisibility(v == view ? View.VISIBLE : View.GONE); 
    } 
} 

Giải pháp thay thế trên nên làm việc cho cả bản phát hành roboguice ổn định và beta. Sự cân bằng ở đây là chúng tôi đang tải nhiều bố cục cùng một lúc thay vì tải từng bố cục tại nhiều thời điểm khác nhau. Dường như nó hoạt động tốt cho tôi (mặc dù nó có thể khác với nhu cầu của bạn).

Một điều tôi nên lưu ý là trên hiện hành "Upgrading from RoboGuice 1.1 to 2.0" trang, sau đây được đề cập:

Khả năng sử dụng @InjectView trong lần xem (mặc dù bạn sẽ cần phải gọi RoboGuice.injectMembers() chính bạn, vì không có lớp cơ sở RoboView và có lẽ sẽ không bao giờ có).

Dường như điều này sẽ cho phép bạn thực hiện các lớp học phụ trợ của bạn để được bắt nguồn từ Xem và làm @InjectView trong số họ làm việc tốt hơn (hy vọng không cần phải để họ có @Nullable vì chúng ít gắn liền với hoạt động). Tuy nhiên, nhìn vào mã hiện tại, tính năng này dường như chưa được triển khai (mặc dù tôi có thể đã nhìn nhầm địa điểm).

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