2012-12-12 38 views
13

Tôi đã xem một số câu hỏi về SO về Fragments và tôi vẫn không thể tìm ra nếu tôi muốn làm gì, và hơn thế nữa nếu thiết kế của tôi mô hình chỉ là thiếu sót và tôi cần phải làm lại toàn bộ quá trình. Về cơ bản, giống như hầu hết các câu hỏi đã được hỏi, tôi có một ActionBar với NavigationTabs (sử dụng ActionBarSherlock), sau đó trong mỗi Tab có một FragementActivity và sau đó FragmentActivities đẩy Fragments mới khi một hàng được chọn (tôi đang cố gắng tạo lại một dự án iOS trong Android và nó chỉ là một ứng dụng dựa trên Điều hướng cơ bản với một số tab có thể đi sâu vào thông tin cụ thể). Khi tôi nhấp vào nút quay lại trên điện thoại, Fragment trước đó được tải nhưng Fragment sẽ tự tạo lại (vì vậy các dịch vụ Web được gọi lại cho mỗi chế độ xem) và điều này không cần thiết vì thông tin sẽ không thay đổi trong chế độ xem trước đó đi ngược lại. Vì vậy, về cơ bản những gì tôi muốn tìm ra là làm thế nào để tôi thiết lập Fragments của tôi để khi tôi nhấn nút quay lại trên điện thoại, Fragment trước đó chỉ được kéo lên với các mục trước đó đã được tạo ra. Dưới đây là mã hiện tại của tôi:Android Fragment, quay lại mà không cần tạo lại/tải lại Fragment

//This is from my FragmentActivity Class that contains the ActionBar and Tab Selection Control 
    @Override 
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) { 
    // TODO Auto-generated method stub 
    int selectedTab = tab.getPosition(); 

    if (selectedTab == 0) { 
     SalesMainScreen salesScreen = new SalesMainScreen(); 
     ft.replace(R.id.content, salesScreen); 
    } 
    else if (selectedTab == 1) { 
     ClientMainScreen clientScreen = new ClientMainScreen(); 
     ft.replace(R.id.content, clientScreen); 
    }..... 

    //This is within the ClientMainScreen Fragment Class, which handles moving to the Detail Fragment 
    row.setOnClickListener(new View.OnClickListener() { 
         @Override 
         public void onClick(View view) { 
          //Do something if Row is clicked 
          try{ 
           String selectedClientName = clientObject.getString("ClientName"); 
           String selectedClientID = clientObject.getString("ClientID"); 
           String selectedValue = clientObject.getString("ClientValue"); 
           transaction = getFragmentManager().beginTransaction(); 
           ClientDetailScreen detailScreen = new ClientDetailScreen(); 
           detailScreen.clientID = selectedClientID; 
           detailScreen.clientName = selectedClientName; 
           detailScreen.clientValue = selectedValue; 
           int currentID = ((ViewGroup)getView().getParent()).getId(); 
           transaction.replace(currentID,detailScreen); 
           transaction.addToBackStack(null); 
           transaction.commit(); 

          } 
          catch (Exception e) { 
           e.printStackTrace(); 
          } 
         } 
        });.... 

    //And then this is the Client Detail Fragment, with the method being called to Call the Web Service and create thew (since what is displayed on this screen is dependent on what is found in the Web Service 
      @Override 
public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved) { 
    return inflater.inflate(R.layout.clientdetailscreen, group, false); 
} 

@Override 
public void onActivityCreated (Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 

    //Setup Preferences File Link 
    this.preferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); 

    //initialize the table object 
    mainTable = (TableLayout)getActivity().findViewById(R.id.mainTable); 

    //setup the detail table 
    setupRelatedClientSection(); 

} 

Các Screen Khách hàng chi tiết sau đó có thể đi sâu thêm một lần nữa, bằng cách sử dụng phương pháp tương tự như Client Màn hình chính nhưng khi tôi quay trở lại từ đó màn hình mới với chi tiết màn hình seuptRelatedClientSection () được gọi lại và do đó toàn bộ Fragment được xây dựng lại khi thực sự tôi chỉ muốn kéo lên một phiên bản đã lưu của màn hình đó. Điều này có thể xảy ra với thiết lập hiện tại của tôi hay tôi đã tiếp cận sai cách này?

Trả lời

7

Tôi tin rằng bạn đang tìm kiếm show()hide().

Tôi nghĩ bạn vẫn có thể thêm chúng vào hậu trường.

transaction.hide(currentFragment); 
transaction.show(detailScreen); 
transaction.addToBackStack(null); 
transaction.commit(); 

Tôi không có mã để xem nhưng tôi tin rằng đây là cách nó sẽ đi ... Hãy thử trừ khi ai đó có cách tốt hơn. Tôi đã không thử backstack với show() hide() nhưng tôi tin rằng nó có những thay đổi được thực hiện trước khi giao dịch cam kết và sẽ hoàn tác chúng nếu nút quay lại được nhấn. Vui lòng liên hệ lại với tôi vì lý do này mà tôi muốn biết.

Bạn cũng phải đảm bảo rằng đoạn chi tiết được tạo trước khi bạn gọi nó. Vì nó được dựa trên các nhấp chuột của someitem sau đó bạn nên có lẽ tạo ra các mảnh chi tiết mỗi khi bạn nhấp vào để đảm bảo rằng các chi tiết chính xác fragment được tạo ra.

+4

tôi đã sử dụng .add() thay vì .show(). Từ đoạn thứ hai, khi tôi nhấn nút quay lại, nó đã đi đến mảnh đầu tiên và không làm mới. – Sri

0

Bạn nói đúng, đã có một số câu hỏi trước/tài liệu về chủ đề này;)

Các tài liệu trên mảnh vỡ, đặc biệt là phần về giao dịch và tiết kiệm nước, sẽ hướng dẫn các bạn câu trả lời.

http://developer.android.com/guide/components/fragments.html#Transactions

http://developer.android.com/guide/components/activities.html#SavingActivityState

Android - Fragment onActivityResult avoid reloading

Những mảnh vỡ có thể có hỗ trợ cho onSaveInstanceState nhưng không onRestoreInstanceState, vì vậy nếu bạn muốn tiết kiệm một tham chiếu đến các quan điểm bảng, lưu chúng vào Bundle và bạn có thể truy cập chế độ xem đã lưu theo phương thức onActivityCreated của bạn. Bạn cũng có thể sử dụng ngăn xếp Phân mảnh.

This guide/tutorial có hướng dẫn/ví dụ rất chi tiết về ngăn xếp và giữ lại trạng thái phân đoạn.

Chúc may mắn

7

Hãy thử sử dụng fragementTransaction.add thay vì thay thế

3

tôi đăng câu trả lời này cho những người có thể tham khảo câu hỏi này trong tương lai.

Mã sau sẽ minh họa cách mở FragmentB từ FragmentA và quay lại FragmentA từ FragmentB (không cần làm mới FragmentA) bằng cách nhấn nút quay lại.

public class FragmentA extends Fragment{ 

    ... 

    void openFragmentB(){ 

     FragmentManager fragmentManager = 
      getActivity().getSupportFragmentManager(); 
     FragmentB fragmentB = FragmentB.newInstance(); 

     if (fragmentB.isAdded()) { 

      return; 
     } else { 

      fragmentManager. 
       beginTransaction(). 
       add(R.id.mainContainer,fragmentB). 
       addToBackStack(FragmentB.TAG). 
       commit(); 
     } 
    } 
} 

public class FragmentB extends Fragment{ 

    public static final String TAG = 
     FragmentB.class.getSimpleName(); 

    ... 

    public static FragmentB newInstance(){ 

     FragmentB fragmentB = new FragmentB(); 
     return fragmentB; 
    } 

    @Override 
    public void onResume() { 

     super.onResume(); 
     // add this piece of code in onResume method 
     this.getView().setFocusableInTouchMode(true); 
     this.getView().requestFocus(); 
    } 
} 

Trong override MainActivity bạn onBackPressed()

class MainActivity extends Activity{ 
    ... 

    @Override 
    public void onBackPressed() { 

     if (getFragmentManager().getBackStackEntryCount() > 0) { 

      getFragmentManager().popBackStack(); 
     } else { 

      super.onBackPressed(); 
     } 
    } 
} 
Các vấn đề liên quan