5

Vì TabActivity không được dùng nữa nên tôi cần tìm cách để thực hiện nó với Fragments. Tôi đã làm việc với Fragments trước khi tôi biết cách nó hoạt động nhưng tôi cần một hướng dẫn để tạo ra máy chủ tab của tôi với FragmentActivities. Tôi đã tìm thấy một vài ví dụ trên internet, và tất cả chúng đều đưa các mảnh vỡ vào một thùng chứa cho các tab.Thay thế TabActivity bằng FragmentActivity and Fragments

Điều tôi muốn là đặt FragmentActivities cho mỗi tab. Bởi vì trong ứng dụng của tôi, tôi sẽ sử dụng 4 tab và mỗi tab có nội dung thực sự phức tạp trong đó. Kết quả là, tôi cần có một FragmentActivity cho mỗi tab để quản lý Fragments mà tôi sẽ đặt dưới mỗi tab trong một thùng chứa riêng biệt.

SOLUTION:

Sau câu trả lời và tìm kiếm trên internet tôi đã kết thúc với một giải pháp. Theo các giải pháp tôi đã tìm thấy, tôi theo dõi các mảnh vỡ trong ngăn xếp ngăn cách cho mỗi tab dưới máy chủ tab. Here là kho lưu trữ GitHub của tôi, tôi đã tạo một ứng dụng mẫu nhỏ cho vấn đề này.

Trả lời

9

Vì TabActivity không được dùng nữa Tôi cần tìm cách để thực hiện việc này với Phân đoạn.

Nếu bạn không muốn sử dụng TabActivity - quên đặt FragmentActivities vào nội dung của tab.

Tôi nhắc bạn có thể sử dụng TabWidget mà không cần TabActivity. Vì vậy, bạn có thể thử giải pháp này:

  1. Chỉ tạo một FragmentActivity.
  2. Đặt TabWidget vào bố cục FragmentActivity. Đặt chiều cao của nội dung là TabWidget = 0.
  3. Dưới dạng khai báo XML trong XML kê khai Fragment s (FrameLayout ví dụ).
  4. Trong FragmentActivity chỉ cần xử lý tab nào được chọn (TabHost.OnTabChangeListener) và đặt cần thiết Fragment vào vùng chứa.
  5. Đặt nhật ký chương trình (trước đó trong các hoạt động khác nhau) vào các Phân đoạn khác nhau.

Hoặc bạn có thể tạo FragmentActivity với TabWidget, và thay vì chuyển đổi Fragment s bạn có thể trực tiếp đặt Fragment s vào nội dung của mỗi tab.

Ví dụ: nếu bạn có 3 tab và 3 đoạn, hãy thử những gì tôi làm. Hãy gọi showFragmentX khi bạn cần thay đổi một đoạn khác.

public class Test extends FragmentActivity { 

private Fragment1 fragment1=new Fragment1(); 
private Fragment2 fragment2=new Fragment2(); 
private Fragment3 fragment3=new Fragment3(); 

private void showFragment1(){ 
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
    ft.replace(R.id.fragments_container, fragment1); 
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
    ft.commit(); 
} 

private void showFragment2(){ 
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
    ft.replace(R.id.fragments_container, fragment2); 
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
    ft.commit(); 
} 

private void showFragment3(){ 
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
    ft.replace(R.id.fragments_container, fragment3); 
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
    ft.commit(); 
} 

@Override 
protected void onCreate(Bundle arg0) { 
    // TODO Auto-generated method stub 
    super.onCreate(arg0); 
    setContentView(R.layout.fragmentactivity_layout); 
} 
} 

Nếu bạn làm như vậy fragmentX biến của bạn sẽ không bị xóa mỗi khi bạn đặt chúng trong fragment_container.Họ sẽ sống trong khi bạn sống FragmentActivity. Hãy xem fragments lifecycle. Chỉ OnCreateViewonDestroyView các phương pháp phân đoạn sẽ gọi lại một lần nữa trong khi bạn replace một đoạn này sang phân đoạn khác.

Ngoài ra Fragments có phương thức onSaveInstanceState nơi bạn có thể lưu trạng thái phân đoạn của mình. Ví dụ: người dùng đã nhập tên của mình trong editText của fragment1. Nếu bạn muốn giữ lại dữ liệu này (string name) trong khi người dùng khám phá những mảnh còn lại bạn nên

1.save tên chuỗi trong phương pháp fragment1 của onSaveInstanceState
2. Vào onCreateView phương pháp bó séc savedInstanceState fragment1, nếu nó không phải null - điền EditText với chuỗi mà bạn nhận được từ gói.

public class Fragment1 extends Fragment { 

EditText nameEditText; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    super.onCreateView(inflater, container, savedInstanceState); 

    View fragment1View=inflater.inflate(R.layout.fragment1_layout, container, false); 
    nameEditText=(EditText) fragment1View.findViewById(R.id.edittext_name); 

    //check for saved data. if it is not null - fill your edittext with saved string 
    if(savedInstanceState!=null){ 
     String nameString=(String) savedInstanceState.get("nameString"); 
     nameEditText.setText(nameString); 
    } 
    return fragment1View; 
} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    //save data that user have entered 
    outState.putString("nameString", nameEditText.getText().toString()); 
} 

}

Bạn có thể kiểm tra dữ liệu trước khi lưu. Tôi hy vọng quan điểm của tôi đã rõ ràng.

Ngoài ra, nếu bạn gọi setRetainInstance(true) trong phương thức onCreateView() của fragment - hệ thống sẽ cố gắng lưu trạng thái phân đoạn (với tất cả dữ liệu đầu vào). link to description

+0

Thx cho câu trả lời, nhưng có một vấn đề khác nếu tôi đặt các mảnh thay vì hoạt động vào các tab. Ví dụ: trong tab đầu tiên, tôi muốn thay thế vùng chứa bằng một đoạn khác trong trường hợp người dùng nhấp vào một nút và sau đó Nếu tôi thay đổi tab, hãy chuyển đến tab thứ hai để thay thế các đoạn trước đó. Vì vậy, trong trường hợp tôi đi đến tab đầu tiên một lần nữa nó sẽ tạo ra các mảnh một lần nữa và tôi sẽ không thể nhìn thấy trang trước đó. Bạn có bất kỳ ý tưởng làm thế nào để thoát khỏi nó? – osayilgan

+0

Tôi đã chỉnh sửa câu trả lời của mình. Hãy nhìn vào đó. Và cũng có những ví dụ mảnh trong các mẫu ("ApiDemos"). Kiểm tra chúng ra. –

+0

Vâng tôi đã hiểu, nhưng đây không phải là điều tôi đang hỏi. Tôi đã làm việc với những mảnh vỡ và tôi biết nó hoạt động như thế nào. Điều mà tôi không biết là: Giả sử rằng chúng ta đang ở trong tab đầu tiên và tôi đã gọi một đoạn khác trong trường hợp người dùng nhấp vào nút, bước thứ hai tôi đã thay đổi tab sang tab thứ hai, vì vậy tại đây sẽ thay thế dữ liệu trong đó với phần của các tab thứ hai phải không? Nhưng tôi cũng muốn giữ cho điều đã được thay đổi trong tab đầu tiên. Vì vậy, theo cách này, nếu tôi chỉ thay thế các mảnh trênTabChange, điều này sẽ không giữ nội dung đã thay đổi trước đó trong tab trước đó. Bất kỳ ý tưởng ? – osayilgan

1

Cách tiếp cận đặt nội dung tab vào các Hoạt động riêng biệt không được chấp nhận, vì bây giờ chúng tôi có khung phân đoạn. Bạn nên đặt nội dung phức tạp của các tab vào Fragments và trao đổi các Fragments đó khi người dùng chọn các tab.

Giải pháp được khuyến nghị cho việc này là sử dụng ActionBar bằng điều hướng Tab thay vì sử dụng tiện ích TabHost.

+0

Cảm ơn câu trả lời, tôi có một số lo ngại về việc sử dụng nó. Ví dụ: Nếu tôi đặt một đoạn cho tab đầu tiên, tôi sẽ cần điều hướng trong cùng một tab và theo tôi biết chúng tôi chỉ sử dụng một vùng chứa cho toàn bộ tab và các đoạn trong đó, sau khi thêm một vài đoạn vào container chính trong tab đầu tiên, tôi sẽ thay đổi nó thành tab thứ hai, vì vậy khi tôi làm điều này, điều này sẽ loại bỏ tất cả các mảnh mà tôi đã tạo và đặt trong vùng chứa trong tab đầu tiên và nó sẽ đặt đoạn thứ hai vào chính vùng chứa, – osayilgan

+0

có nghĩa là tất cả dữ liệu tôi đã tạo trong tab đầu tiên sẽ bị xóa và được thay thế bằng đoạn thứ hai? Nếu tôi trở lại tab đầu tiên thì sao? Tôi sẽ tạo lại nó? – osayilgan

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