2015-06-11 13 views
13

Tôi có câu hỏi về "lập trình thích hợp" trong Android.Nguyên tắc cơ bản về Android Fragments: tại sao? Đây có phải là khái niệm sai?

Tôi hiện đang phát triển một ứng dụng bằng cách sử dụng các phân đoạn. Nó bao gồm các phân đoạn động được thêm vào Hoạt động, các đoạn bị thổi phồng từ XML, các đoạn lồng nhau từ XML hoặc được thêm động. Hãy nói, một chút của tất cả mọi thứ.

Khái niệm mà câu hỏi này tập trung vào là quá trình giao tiếp liên quan đến các phân đoạn. Vì vậy, tôi đã đọc các tài liệu và đây không phải là lần đầu tiên tôi cố gắng sử dụng các mảnh vỡ.

Cảm giác chung (và tài liệu) cho biết nếu một Fragment muốn nói hoặc giao tiếp với hoạt động của nó, chúng ta nên sử dụng một giao diện.

Ví dụ:

TestFragment

public class TestFragment extends Fragment { 

    private TestFragmentInterface listener; 

    public interface TestFragmentInterface { 

     void actionMethod(); 

    } 


    @Override 
    public void onViewCreated(View view, Bundle savedInstanceState) { 

     if (getActivity() instanceof TestFragmentInterface) { 
      listener = (TestFragmentInterface) getActivity(); 
     } 

     // sending the event 
     if (listener != null) listener.actionMethod(); 
    } 

} 

TestActivity

public class Test implements TestFragmentInterface { 

    @Override 
    public void actionMethod() { 
    .. 
    } 
} 

Tất cả những gì tốt đẹp ở đây.

Điều này cải thiện khả năng sử dụng lại, vì TestFragment của tôi theo cách này có thể tương tác với bất kỳ loại Hoạt động nào, do Hoạt động triển khai giao diện mà tôi khai báo.

Cách khác xung quanh, Hoạt động có thể tương tác với đoạn bằng cách giữ tham chiếu và gọi phương thức công khai của nó. Đây cũng là cách được đề xuất để liên lạc từng đoạn, sử dụng Hoạt động như một cây cầu.

Điều này thật tuyệt, nhưng đôi khi cảm giác như sử dụng giao diện cho điều này chỉ là một chút "quá nhiều".

Câu hỏi Một

Trong kịch bản các mảnh vỡ tôi đính kèm có một vai trò khá tập trung, có nghĩa là chúng được thực hiện cho rằng hoạt động cụ thể và sẽ không được sử dụng bằng cách khác, nó là khái niệm sai lầm khi bỏ qua việc thực hiện giao diện và chỉ cần làm điều gì đó như

((TestActivity) getActivity().myCustomMethod(); 

?

Điều này cũng xảy ra trong trường hợp (không phải trường hợp của tôi, nhưng chỉ coi nó là "tồi tệ nhất") hoạt động của tôi phải xử lý nhiều loại mảnh KHÁC, nghĩa là nó nên thực hiện một phương pháp cho mọi mảnh cần xử lý. Điều này mang lại mã cho một mớ hỗn độn lớn của "dòng có khả năng không cần thiết".

Di chuyển thêm: vẫn còn sử dụng các đoạn "tập trung", nhằm mục đích chỉ hoạt động theo cách nhất định, điều gì xảy ra với việc sử dụng các đoạn lồng nhau?

thêm họ như

public class TestFragment extends Fragment { 


    private void myTestMethod() { 

    NestedFragment nested = new NestedFragment(); 

    getChildFragmentManager() 
     .beginTransaction() 
     .add(R.id.container, nested) 
     .commit(); 
    } 

} 

này liên kết với NestedFragment để TestFragment. Tôi nói lại lần nữa, NestedFragment, giống như TestFragment, chỉ được sử dụng theo cách này, nó không có ý nghĩa để làm việc khác.

Quay lại câu hỏi, tôi nên xử lý như thế nào trong tình huống này?

Câu hỏi B

1) Tôi cần cung cấp một giao diện trong NestedFragment, và làm sao cho TestFragments thực hiện NestedFragmentInterface? Trong trường hợp này tôi sẽ đóng vai trò như sau

NestedFragment

public class NestedFragment extends Fragment { 

    private NestedFragmentInterface listener; 

    public interface NestedFragmentInterface { 

     void actionMethodNested(); 

    } 


    @Override 
    public void onViewCreated(View view, Bundle savedInstanceState) { 

     if (getParentFragment() instanceof NestedFragmentInterface) { 
      listener = (NestedFragmentInterface) getParentFragment(); 
     } 

     // sending the event 
     if (listener != null) listener.actionMethodNested(); 
    } 

} 

2) nên (hoặc có thể) Tôi bỏ qua giao diện, và chỉ cần gọi

getParentFragment().publicParentMethod(); 

?

3) Tôi nên tạo các giao diện trong NestedFragment, nhưng để cho các hoạt động thực hiện nó, vì vậy mà hoạt động sẽ gọi TestFragment?

Câu hỏi C

Về ý tưởng của việc sử dụng Hoạt động như một cầu nối giữa các mảnh vỡ, tôi tin rằng nó được làm như vậy cho vòng đời xử lý thích hợp của tất cả các đối tượng này. Nó vẫn còn khả thi để làm một mảnh trực tiếp-to-fragment (sử dụng giao diện hoặc trực tiếp gọi phương thức công cộng) trong khi cố gắng để xử lý bằng tay ngoại lệ hệ thống có thể ném tôi?

+0

Xem điều này có giúp ích: https://corner.squareup.com/2014/10/advocating-against-android-fragments.html –

+0

Tôi đã đọc liên kết bạn đăng và trong khi đó thực sự là một bài viết thú vị rất nhiều thông tin, tôi sợ nó không trả lời câu hỏi của tôi. Cảm ơn bạn anyway – FrancescoC

Trả lời

4

Tôi sẽ cố gắng xóa tất cả một chút.

Trước hết, hãy xem xét cách tiếp cận của bạn trong việc thiết lập trình lắng nghe cho phân đoạn.Nó không phải là tốt để thiết lập người nghe trong phương pháp onViewCreated, bởi vì nó leeds để lắng nghe đặt lại dư thừa bất kỳ fragment được tạo ra. Nó là đủ để thiết lập nó vào phương pháp onAttach.

Tôi đã nói về các dòng mã. Hãy cho tôi để thông báo, nó là tốt để có BaseFragment thực hiện hành vi phổ biến trong ứng dụng của bạn như thiết lập FragmentListener tạo xem từ tài nguyên.

Và nhiều hơn thế để giảm các dòng mã và lấy lại một phần mã tái sử dụng, bạn có thể sử dụng chung trong BaseFragment. Vì vậy, nhìn vào đoạn mã tiếp theo:

public abstract BaseFragment<T extends BaseFragmentListener> extends Fragment { 

    T mListener; 

    public void onAttach(Activity activity) { 
    super.onAttach(activity); 
    if (Activity instanceof T) 
     mListener = (T) activity; 
    } 

    abstract int getLayoutResourceId(); 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View layout = inflater.inflate(getLayoutResourceId(), null); 
     // you can use some view injected tools here, mb ButterKnife 
     return layout; 
    } 
} 

trả lời A (Ví Câu hỏi A):

Nếu bạn có mảnh chỉ đúng một hoạt động bạn cần phải quyết định: "Bạn có thực sự cần phải sử dụng Fragment ở đây?" . Nhưng mb nó là tốt để có mảnh chính xác cho một hoạt động để trích xuất một số logic xem từ hoạt động và thanh toán bù trừ logic cơ bản. Nhưng để xóa logic kiến ​​trúc cơ sở cho ứng dụng của bạn, hãy sử dụng Trình nghe. Điều này sẽ giúp cuộc sống dễ dàng hơn cho các nhà phát triển khác

Trả lời B: Đối với các đoạn lồng nhau bạn cần giải quyết, những gì họ cần để sử dụng hoạt động chính xác hoặc chỉ mảnh và sử dụng nó làm cầu nối với hệ thống khác. Nếu bạn biết rằng đoạn lồng nhau sẽ được lồng nhau tất cả thời gian bạn, bạn cần phải khai báo đoạn cha như người nghe nếu không bạn phải sử dụng cách tiếp cận khác.

Lưu ý: Là cách tiếp cận cơ bản để giao tiếp giữa phần khác của Ứng dụng, bạn có thể sử dụng sự kiện, hãy thử xem bus sự kiện chẳng hạn. Nó cung cấp cho bạn phương pháp tiếp cận chung cho giao tiếp và bạn có thể trích xuất logic gọi các phương thức tùy chỉnh của người nghe và nhiều phương thức khác, tất cả logic sẽ được đặt vào các sự kiện xử lý và bạn sẽ có một hệ thống hòa giải để hợp tác.

Trả lời C: Tôi giải thích một phần cách tiếp cận để hợp tác giữa các đoạn. Sử dụng một trình điều phối sự kiện sẽ giúp bạn có nhiều người nghe cho tất cả các giao tiếp khác nhau. Một số lần nó là rất lợi nhuận. Hoặc tôi nghĩ có thể sử dụng Hoạt động hoặc các hoạt động lớp khác trong Hoạt động, cho một hòa giải viên cho sự hợp tác Fragments vì có nhiều tình huống Fragments thay đổi trong suốt vòng đời cả xử lý và hệ thống. Và nó tập trung tất cả logic này vào một nơi và làm cho mã của bạn rõ ràng hơn.

Hy vọng những cân nhắc của tôi sẽ giúp bạn.

+0

Cảm ơn bạn, đây là câu trả lời tuyệt vời, chi tiết về logic và hữu ích, đã cho tôi một số ý tưởng hay:) – FrancescoC

10

Ill làm hết sức mình để trả lời các bức tường của văn bản ở đây :)

Câu hỏi A:

Những mảnh vỡ được thiết kế để tái sử dụng các module có thể được cắm và chơi với bất kỳ hoạt động. Bởi vì điều này chỉ có cách chính xác để giao tiếp với hoạt động này là có hoạt động kế thừa từ một giao diện mà phân đoạn hiểu được.

public class MapFragment extends Fragment { 

    private MapFragmentInterface listener; 

    public interface MapFragmentInterface { 

     //All methods to interface with an activity 

    } 


    @Override 
    public void onViewCreated(View view, Bundle savedInstanceState) { 
     // sending the event 
     if (listener != null) listener.anyMethodInTheAboveInterface(); 
    } 

} 

Sau đó có các hoạt động thực hiện các giao diện

public class MainActivity extends Activity implement MapFragmentInterface{ 

//All methods need to be implemented here 
} 

này cho phép mảnh của bạn được sử dụng với bất kỳ hoạt động càng lâu càng hoạt động thực hiện giao diện này. Lý do tại sao bạn cần giao diện này là vì đoạn có thể được sử dụng với bất kỳ hoạt động nào. Gọi một phương thức như

((TestActivity) getActivity().myCustomMethod(); 

dựa vào thực tế là đoạn của bạn chỉ có thể hoạt động trong hoạt động thử nghiệm và do đó "phá vỡ" quy tắc của các đoạn.

Câu hỏi B và C:

Giả sử bạn đang làm theo hướng dẫn chính xác cho các đoạn và chúng là các mô-đun độc lập. Sau đó, bạn không bao giờ nên có một tình huống mà các mảnh cần phải biết về nhau. 99% thời gian mà mọi người nghĩ rằng họ cần mảnh vỡ để giao tiếp trực tiếp họ có thể tái yếu tố vấn đề của họ với tình hình tôi đã đưa ra ở trên bằng cách sử dụng một patten MVC hoặc một cái gì đó tương tự. Cho phép hoạt động giống như bộ điều khiển và cho biết các mảnh khi chúng cần cập nhật và sau đó tạo một kho lưu trữ dữ liệu riêng biệt.

+0

Sau đó, từ những gì bạn viết, tôi nhận được rằng những gì tôi đang làm là có thể nhưng không được đề xuất như việc sử dụng nằm ngoài phạm vi ban đầu. Nó không phải là cái gì đó là có hại, nhưng chỉ đơn giản là không được sử dụng như dự định ban đầu. Tôi sai bao nhiêu? :) – FrancescoC

+0

Chính xác 100% của bạn. Giống như với tất cả các chương trình có rất nhiều cách để làm việc. Rất nhiều thời gian tôi thậm chí sẽ làm điều đó chính xác như thế nào bạn mô tả bởi vì tôi biết mảnh của tôi sẽ chỉ được sử dụng trong hoạt động này. Tuy nhiên, nếu bạn đang cố gắng "đúng", bạn nên làm điều đó thông qua một giao diện để làm cho quảng cáo mã của bạn được tách riêng hết mức có thể. Nếu bạn có thời gian và tiền bạc, bạn nên luôn xây dựng ứng dụng của mình theo cách chính xác mặc dù :) – nbroeking

+0

Tiền thưởng được trao:) – FrancescoC

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