2012-11-28 34 views
7

Đây là những gì tôi muốn ứng dụng của mình thực hiện trên máy tính bảng. Fragment (0) có một số menu sẽ hiển thị mảnh (1) ... (n) như thế này:di chuyển đoạn Android sang một vùng chứa khác Không thể thay đổi ID vùng chứa của đoạn

----------------- 
| | | | | 
| | | | | 
|(0)| X | X | X | 
| | | | | 
| | | | | 
----------------- 
becomes 
----------------- 
| | | | | 
| | | | | 
|(0)|(1)| X | X | 
| | | | | 
| | | | | 
----------------- 
and then 
----------------- 
| | | | | 
| | | | | 
|(0)|(2)|(1)| X | 
| | | | | 
| | | | | 
----------------- 
etc... 

Fragment0 bao giờ di chuyển, những người khác được chuyển sang bên phải. Các mảnh vỡ đi ra khỏi cạnh bên phải sẽ bị phá hủy.

Vì vậy, tôi thiết lập layout XML của tôi với một LinearLayout ngang và chứa 4 FrameLayout với các ID thích hợp (fragment0 ... fragment3)

tôi có thể nhanh chóng và hiển thị fragment0 và sau đó fragment1, nhưng tôi không thể chuyển nó ở bên phải sau đó, tôi nhận được:

ERROR/AndroidRuntime(343): FATAL EXCEPTION: main 
java.lang.IllegalStateException: Can't change container ID of fragment ... 

những câu hỏi chỉ liên quan tôi đã tìm thấy là this onethat one, thử tất cả các giải pháp khác nhau được cung cấp không có may mắn.

Cố gắng FragmentTransaction.remove() Tiếp theo .add(), cố gắng .replace(), thử chúng trong đơn đặt hàng khác nhau và cam kết một nửa chiều qua (thậm chí cố gắng để thực hiện hai lần như ai đó gợi ý), cố gắng gọi addToBackStack() ... vẫn không có may mắn.

Câu hỏi là liệu có thể di chuyển các đoạn như thế này bằng FragmentTransaction hay không. Nếu có, tôi đang làm gì sai (và tiền thưởng, là nó có thể animate đó?). Nếu không, đâu là cách thích hợp để thực hiện điều này?

Lưu ý rằng tôi không muốn khởi tạo lại các đoạn mỗi lần (mỗi truy vấn trên một số trang web có thể mất chút thời gian). Có thể trích xuất tất cả dữ liệu trở lại hoạt động để tạo lại, nhưng tôi không muốn làm điều đó nếu có thể ...

Trả lời

3

Tôi không biết đây có phải là điều bạn muốn nhưng tôi đã làm một mẫu nhỏ về vấn đề của bạn. Về cơ bản, bạn sẽ thực hiện chuyển dịch đúng bằng cách sử dụng tệp sơ đồ bố trí, có vùng chứa bao bọc cho từng phần chuyển đổi đó. Các mẫu mã là một chút to lớn cho một câu trả lời vì vậy tôi đã đăng nó vào a gist that you can find here. Trong mẫu đó, hãy nhấn từng mục trong số các mục của ListFragment (Đoạn 1 -> Đoạn 2 -> đoạn 3) để xem hành vi.

+0

Nó không làm những gì tôi đang tìm kiếm, nhưng tôi đang cố gắng thay đổi mã của bạn để làm điều đó ... Tôi sẽ đăng nó nếu tôi có thể ... – Matthieu

+0

Đã có thể làm những gì tôi cần .. Không thể tìm ra cách để đẩy các thay đổi của tôi vào ý chính bạn đã tạo, vì vậy tôi đặt nó ở đó: https://gist.github.com/4166640 – Matthieu

+0

Xin lỗi. Đó có phải là một lỗi đánh máy, rằng nó phải là 'LinearLayout' thay vì' RelativeLayout' trong 'frag_fragaccordion.xml'? – midnite

20

Có thể thay đổi vùng chứa của đoạn bằng chức năng remove().

Sự cố ở đây là commit(). Nó là một cuộc gọi không đồng bộ, và sẽ lên lịch cho nó được trên chủ đề chính. Vì vậy, để buộc FragmentManager thực hiện việc này ngay lập tức trước khi thêm nó vào vùng chứa khác.

Đối với điều này, chúng tôi sẽ phải sử dụng chức năng executePendingTransactions(). Sau khi gọi điều này, hãy thử thêm phân đoạn vào vùng chứa mới.

Documents: executePendingTransactions()

Mã mẫu:

FragmentManager fManager = getSupportFragmentManager(); 
FragGroups fragGroups = (FragGroups) fManager.findFragmentByTag("groups"); 
if (fragGroups != null) { 
    fManager.beginTransaction().remove(fragGroups).commit(); 
    fManager.executePendingTransactions(); 
} else { 
    fragGroups = new FragGroups(); 
} 
if (mTwoPane) { 
    fManager.beginTransaction().replace(R.id.fragment_container_groups, fragGroups, "groups").commit(); 
} else { 
    fManager.beginTransaction().replace(R.id.fragment_container, fragGroups, "groups").commit(); 
} 

Thưởng thức.Feed-lưng được hoan nghênh

Sửa

Tôi muốn một thêm một điểm ở đây. Như tôi đã có cùng một vấn đề, đã đi qua chủ đề này và áp dụng các thay đổi được đề xuất. Vấn đề vẫn còn tồn tại. Sau đó, tôi đã xem xét lời giải thích cuối cùng về chủ đề này đã giải quyết được vấn đề của tôi: xóa phương thức addToBackStack() trong khi thực hiện giao dịch hoặc nếu bạn cố ý sử dụng nó, hãy xóa phân đoạn khỏi ngăn xếp trước khi thêm nó vào vùng chứa khác. Hy vọng nó sẽ giúp người đọc trong tương lai.

+1

Câu trả lời xuất sắc! Có thể không chính xác những gì câu hỏi ban đầu đã được tìm kiếm nhưng tôi thấy nó cực kỳ hữu ích. –

+2

Pavan ..... Tôi thậm chí không biết bạn .... bạn thậm chí không biết tôi .... nhưng tôi có một số tình yêu nghiêm trọng cho bạn, bạn của tôi. – dell116

+0

@TomR Tôi rất vui vì bạn thấy nó hữu ích :) –

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