8

Tôi không quen với FragmentPagerAdapter, vì vậy đây sẽ là một trong những câu hỏi mà chúng tôi (bạn) đọc mô tả một cách nghiêm túc.FragmentPagerAdapter với ViewPager và hai Mảnh vỡ. Chuyển đến phần đầu tiên từ phần thứ hai và cập nhật văn bản đầu tiên

Cấu trúc: Tôi có FragmentPagerAdapter (mã bên dưới), sẽ giữ hai đoạn một lúc. Các trích đoạn sách hiển thị đầu tiên, và danh sách thứ hai của danh sách sách.

Mục tiêu: Tôi muốn đạt được nội dung được mô tả trong tiêu đề: người dùng có thể điều hướng đến đoạn thứ hai trong máy nhắn tin, nhấp vào tiêu đề và sau đó tôi muốn chuyển người dùng trở lại đoạn đầu tiên và nói đoạn đầu tiên để cập nhật văn bản. Đoạn đầu tiên có phương pháp triggerRefresh cho điều đó.

Mã số: Tôi tin rằng sự cố của tôi xảy ra do cách FragmentPagerAdapter reuses/tạo Phân đoạn (mà tôi không hiểu). Đây là lớp học của tôi:

static class MyFragmentPagerAdapter extends FragmentPagerAdapter { 

    public MyFragmentPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public int getCount() { 
     return NUM_ITEMS; 
    } 

    @Override 
    public Fragment getItem(int position) { 
     switch(position) { 
     case 0: 
      return new ExcerptsFragment(); 
     case 1: 
      return new BookListFragment(); 
     default: 
      throw new IllegalArgumentException("not this many fragments: " + position); 
     } 
    } 
} 

Đây là cách tôi tạo ra các thành viên có liên quan:

ViewPager mViewPager = (ViewPager) findViewById(R.id.pager); 
MyFragmentPagerAdapter mFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager()); 
mViewPager.setAdapter(mFragmentPagerAdapter); 

Và đây là những gì tôi đã cố gắng ở những nơi khác trong Hoạt động của tôi, khi tôi nhận được gọi lại từ đầu sách Fragment với tiêu đề được chọn:

mViewPager.setCurrentItem(0); // back to excerpts screen page. It's OK. 
// Here's the problem! How to identify the fragment 0 
// to ExcerptsFragment and call its triggerRefresh()?!? 

loạt các vấn đề:

Gọi bộ chuyển đổi getView() sẽ không hoạt động vì nó sẽ trả về phiên bản ExcerptsFragment mới, không phải là phiên bản hiện đang được đính kèm (như dự kiến, ném ngoại lệ).

Tôi đã thấy nhiều người ở đây (example) chỉ lưu trữ các đoạn trong getView(). Có đúng không? Bởi vì bằng cách nhìn vào các ví dụ chính thức, có vẻ như một mô hình chống lại tôi (đánh bại tham chiếu tự động bằng cách giữ các mục). Và đó cũng là ý kiến ​​herehere (và có vẻ phù hợp với tôi).

Mọi đề xuất? Tôi sẽ không ngạc nhiên nếu tôi không hiểu tất cả những điều này một chút ...

Trả lời

7

Tuyên bố từ chối trách nhiệm: Mặc dù điều này đã làm việc hoàn hảo cho tôi trước đây, bạn nên biết về những cạm bẫy cổ điển tùy thuộc vào nội bộ , hành vi riêng tư. Trong khi tôi đã viết các bài kiểm tra mà cuối cùng sẽ cảnh báo tôi nếu việc thực hiện nội bộ thay đổi, tôi đã chuyển sang greener pastures. Và bạn cũng nên làm thế. Như vậy, giá trị của câu hỏi này và câu trả lời của nó chỉ là lịch sử, theo ý kiến ​​của tôi.


Xin lỗi về câu hỏi đó, tôi nghĩ đó là giờ.

Để giải quyết vấn đề đó, tôi đã triển khai this solution. Dường như làm việc tốt. Vì vậy, tôi tin rằng nó chỉ là một vấn đề của việc tìm kiếm (hiện đang đính kèm) mảnh dụ bằng cách tìm ra cách Id của nó được đặt tên. Liên kết ở trên giải thích cách nó được tạo.

Tôi đã chọn trả lời câu hỏi của riêng mình thay vì xóa nó vì tôi tin những người mới như tôi trên những máy nhắn tin này sẽ được hưởng lợi từ "trường hợp thực tế". Hầu hết các câu trả lời tôi đã nhìn thấy hầu hết về lý thuyết, đó là đúng cách BTW ... nhưng không có một ví dụ thực tế để làm việc trên đôi khi những người như tôi bị lạc.

Dù sao, đây là mảnh cuối cùng của mã mà tôi cần (phần nhận xét ở trên):

int n = 0; 
mViewPager.setCurrentItem(n); // in the question I had stopped here. 

ExcerptsFragment f = (ExcerptsFragment) ContainerActivity.this 
     .getSupportFragmentManager().findFragmentByTag(getFragmentTag(n)); 
f.triggerRefresh(); 

// ... below the helper method: used the solution from the link. 

private String getFragmentTag(int pos){ 
    return "android:switcher:"+R.id.pager+":"+pos; 
} 

Vì vậy, tôi đang gặp một cảm giác rằng đây là một giải pháp mạnh mẽ, bởi vì tôi không giữ bất kỳ tham chiếu đến các mảnh (do đó rủi ro các tài liệu tham khảo là lỗi thời). Tôi giữ mã của riêng mình ở mức tối thiểu, do đó giảm thiểu cơ hội tôi làm điều gì đó ngu ngốc.

Tất nhiên, nếu bạn có điều gì đó cần thêm, để cho chúng tôi biết, để biết điều gì sai khi thực hiện hoặc những gì có thể cải thiện, tôi rất vui khi được nghe từ bạn.

+0

bạn không nên dựa vào khả năng tương thích với cơ chế phân bổ thẻ nội bộ. Xem câu trả lời của tôi cho câu hỏi tương tự như thế nào để làm điều này đúng: http://stackoverflow.com/questions/14035090/how-to-get-existing-fragments-when-using-fragmentpageradapter/41345283#41345283 – morgwai

+0

@morgwai Cảm ơn bạn đã cảnh báo tôi. Tôi đã bao gồm tuyên bố từ chối trách nhiệm để cảnh báo độc giả tiềm năng. – davidcesarino

+0

bạn được chào đón :) Tôi nghĩ tuy nhiên sẽ tốt hơn nếu cung cấp liên kết trực tiếp đến câu trả lời của tôi (không chỉ cho câu hỏi đó) vì câu trả lời của tôi rất mới và do đó vẫn ghi điểm thấp để người đọc có thể bị mắc kẹt với một trong 2 câu trả lời được ghi, cả hai đều có vấn đề. (Tôi đã thêm một số giải thích cho câu trả lời của tôi tại sao giải pháp ghi đè 'instantiateItem' có thể không đủ) – morgwai

2

Tôi đã tìm kiếm giải pháp cho vấn đề này một lúc. Cách tiếp cận của bạn về nguyên tắc hoạt động, nhưng nó sẽ phá vỡ mã của bạn nếu bao giờ mã của việc tạo thẻ phân mảnh trong các thay đổi thực hiện lớp cơ sở Android. Đây là một phụ thuộc khá khó chịu!

Cách tiếp cận trang nhã hơn sẽ là giải quyết vấn đề xung quanh và duy trì hoạt động cơ sở của bạn trong đoạn của bạn. Thực hiện một setter cho thẻ trong hoạt động của bạn và gọi bên trong mảnh khi tạo - thẻ có sẵn chỉ với getTag().

Triển khai ví dụ có thể được tìm thấy here.

+0

Giải pháp tốt nhất cho vấn đề này rất ngẫu nhiên cho đến nay. Tuy nhiên, có hai thứ: bạn có thể tham chiếu đến "activity cha" với getActivity(). Và bạn cần lưu ý rằng bạn cần giữ tên thẻ thông qua các thay đổi cấu hình, bởi vì mặc dù bộ điều hợp có thể được tạo lại, các đoạn có thể không (và do đó các thẻ sẽ không được đặt lại) – jpm

0

Tôi đã giải quyết vấn đề này bằng cách sử dụng WeakReferences cho các phân đoạn khi tạo. Xem: https://stackoverflow.com/a/23843743/734151

Nếu bạn tìm thấy bất kỳ điều gì sai với phương pháp này, vui lòng nhận xét.