2012-10-17 29 views
6

Android 4.1 ActionBar cung cấp chế độ điều hướng hữu ích dưới dạng danh sách hoặc tab. Tôi đang sử dụng SpinnerAdapter để chọn từ ba đoạn được hiển thị trong chế độ xem android.R.id.content. Trình nghe theo số onNavigationItemSelected() sau đó thổi từng đoạn vào chế độ xem và thêm nó vào ngăn xếp sau bằng cách sử dụng FragmentTransaction.addToBackStack(null).Làm cách nào để làm mới mục điều hướng ActionBar khi di chuyển ngăn xếp Phân đoạn trở lại?

Tất cả đều hoạt động như được quảng cáo, nhưng tôi không biết cách cập nhật ActionBar để phản ánh ngăn xếp hiện tại. Sử dụng công cụ ActionBar.setSelectedNavigationItem(position) hoạt động nhưng cũng kích hoạt OnNavigationListener() mới cũng tạo ra một FragmentTransaction khác (không phải tác dụng tôi muốn). Mã được hiển thị bên dưới để làm rõ. Bất kỳ trợ giúp nào với giải pháp đều được đánh giá cao.


public class CalcActivity extends Activity { 
private String[] mTag = {"calc", "timer", "usage"}; 
private ActionBar actionBar; 

/** An array of strings to populate dropdown list */ 
String[] actions = new String[] { 
    "Calculator", 
    "Timer", 
    "Usage" 
}; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    this.actionBar = getActionBar(); 

    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); 
    // may not have room for Title in actionbar 
    actionBar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE); 

    actionBar.setListNavigationCallbacks(
    // Specify a SpinnerAdapter to populate the dropdown list. 
    new ArrayAdapter<String>(
     actionBar.getThemedContext(), 
     android.R.layout.simple_list_item_1, 
     android.R.id.text1, 
     actions), 
    // Provide a listener to be called when an item is selected. 
    new NavigationListener() 
    );  
} 

public class NavigationListener implements ActionBar.OnNavigationListener { 
    private Fragment mFragment; 
    private int firstTime = 0; 

    public boolean onNavigationItemSelected(int itemPos, long itemId) { 
     mFragment = getFragmentManager().findFragmentByTag(mTag[itemPos]); 

     if (mFragment == null) { 
      switch (itemPos) { 
      case 0: 
       mFragment = new CalcFragment(); 
       break; 
      case 1: 
       mFragment = new TimerFragment(); 
       break; 
      case 2: 
       mFragment = new UsageFragment(); 
       break; 
      default: 
       return false; 
      }    
      mFragment.setRetainInstance(true); 
     } 

     FragmentTransaction ft = getFragmentManager().beginTransaction(); 
     if (firstTime == 0) { 
      firstTime++; 
      ft.add(android.R.id.content, mFragment, mTag[itemPos]); 
     } else { 
      ft.replace(android.R.id.content, mFragment, mTag[itemPos]); 
      ft.addToBackStack(null); 
     } 
     ft.commit(); 

     Toast.makeText(getBaseContext(), "You selected : " + 
       actions[itemPos], Toast.LENGTH_SHORT).show(); 

     return true; 
    }  
} 

public static class CalcFragment extends Fragment {    
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
    View v = inflater.inflate(R.layout.fragment_calc, container, false); 
    return v; 
    } 
} 

public static class TimerFragment extends Fragment { 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
    View v = inflater.inflate(R.layout.fragment_timer, container, false); 
    return v; 
    } 
} 

public static class UsageFragment extends Fragment { 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
    View v = inflater.inflate(R.layout.fragment_usage, container, false); 
    return v; 
    } 
} 

Trả lời

4

Bạn có thể làm một cái gì đó như thế này:

  1. Tạo một boolean để theo dõi khi bạn đang chọn một mục chuyển hướng dựa trên các nút quay lại:

    private boolean mListIsNavigatingBack = false; 
    
  2. Ghi đè onBackPressed, trong ghi đè, kiểm tra xem backstack có các mục, nếu bạn tự xử lý, nếu không gọi superclass :

    public void onBackPressed() { 
        if(getFragmentManager().getBackStackEntryCount() > 0){ 
         mListIsNavigatingBack = true; 
    
         //You need to get the previous index in the backstack through some means 
         //possibly by storing it in a stack 
         int previousNavigationItem = ???; 
    
         getActionBar().setSelectedNavigationItem(previousNavigationItem); 
        } 
        else{ 
         super.onBackPressed(); 
        } 
    } 
    
  3. Bên NavigationListener, xử lý tình trạng mListIsNavigatingBack, tay bật stack trở lại và unset nhà nước:

    if(mListIsNavigatingBack){ 
        if(fm.getBackStackEntryCount() > 0){ 
         fm.popBackStack(); 
        } 
        mListIsNavigatingBack = false; 
    } 
    
+0

Cảm ơn bạn đã gợi ý của bạn mà tôi thực hiện với một chồng. Với độ phức tạp thêm và UX độc đáo, tôi có những suy nghĩ thứ hai về mẫu thiết kế này. Có tốt hơn khi không bao giờ addToBackStack() khi sử dụng điều hướng ActionBar không? – GregM

+0

Điều hướng danh sách không làm cho nó phức tạp. Thông thường, ngăn xếp lưng được sử dụng nhiều hơn để hoán đổi các đoạn trong chế độ xem hiện tại của bạn, vì vậy có lẽ trường hợp sử dụng của bạn có thể được đơn giản hóa bằng cách chỉ đính kèm lại đoạn đó trong nền. –

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