2012-04-10 31 views
17

Tôi đã cố gắng hết sức để có được các khối + các tab + hành động.Actionbarsherlock + tabs + nhiều phân đoạn?

Tôi chỉ có thể làm cho bộ này hoạt động như tĩnh, tôi muốn tạo ứng dụng này như ứng dụng thị trường Android (chuyển động vuốt).

Tôi gặp khó khăn khi bạn cần thổi phồng bố cục với nhiều phân đoạn bên trong.

Trong Support4demos, tôi đã nhận FragmentsTabsPager làm ví dụ để làm theo.

+0

Bạn cần đăng mã bạn đang gặp sự cố và LogCat của bạn nếu có bất kỳ ngoại lệ nào bị ném. Nếu bạn muốn vuốt giữa 'Fragments', bạn cần sử dụng' ViewPager'. – adneal

+0

https://github.com/JakeWharton/ActionBarSherlock/blob/master/samples/fragments/src/com/actionbarsherlock/sample/fragments/FragmentTabsPager.java –

Trả lời

10

Bạn cần thư viện phù hợp để triển khai những gì bạn muốn.

Về cơ bản, thư viện ViewPager là những gì còn thiếu trong bạn. gợi ý của tôi:

1. ActionBarSherlock

Thật dead-dễ dàng để làm việc với rằng tôi sẽ không giải thích nó.

2. ViewPagerExtensions

Bạn có thể tìm thấy nó here. Tải xuống các tệp ZIP và tạo một dự án mới từ đó.

Tôi chỉ có thể làm cho bộ này hoạt động như tĩnh, tôi muốn tạo ứng dụng này như ứng dụng thị trường Android (chuyển động swype).

Triển khai com.astuetz.viewpager.extensions.SwipeyTabsView từ dự án này. Có những ví dụ dễ làm theo. nó thực hiện chính xác những gì bạn muốn. Thậm chí còn có các kiểu tab khác để chọn (bao gồm tab Mọi người mới đi kèm với ICS). Bên cạnh đó, nó rất dễ dàng để tạo kiểu cho phù hợp với danh tính ứng dụng của bạn.

3. FragmentPagerAdapter

Cuối cùng, đó là lớp từ thư viện hỗ trợ (v4).

Chúc may mắn và được tự do hỏi tôi xem bạn có cần thêm trợ giúp không.


Bạn không cần ghi đè instantiateItem trong FragmentPagerAdapter nếu bạn đang sử dụng những gì tôi đề xuất. Bạn chỉ cần

  1. Cung cấp một hàm tạo với FragmentManager và gọi thực hiện siêu;
  2. Override getCount để trả lại số mảnh vỡ trong máy nhắn tin của bạn, và
  3. getItem, đó là những gì bạn sẽ sử dụng để quay trở lại mảnh vỡ của bạn để tạo.

Đây là ví dụ từ mã tôi có ở đây (ví dụ sản xuất, làm việc đầy đủ). Đây là lớp bên trong cho hoạt động triển khai máy nhắn tin:

static class MyFragmentPagerAdapter extends FragmentPagerAdapter { 

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

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

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

Như bạn có thể thấy, máy nhắn tin này xử lý hai 'trang', bên trái hiển thị dữ liệu bán hàng.Quyền phù hợp cho phép người dùng chọn bộ phận nào. Chúng được trả về theo phương thức getItem. Các mảnh thích hợp (bạn có thể sử dụng bất kỳ mảnh vỡ bạn đã có, không cần sửa đổi).

Như mong đợi, bạn kết hợp tất cả điều này với nhau bằng 1) tạo đối tượng khởi tạo MyFragmentPagerAdapter và 2) đặt bộ điều hợp cho đối tượng ViewPager của bạn để trở thành lớp mà bạn vừa khởi tạo. Như bạn có thể thấy, phương thức getItem của nó sẽ "cung cấp" cho máy nhắn tin tất cả các mảnh bạn cần. Ví dụ:

mFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager()); 
mViewPager.setAdapter(mFragmentPagerAdapter); 

Tất nhiên, có những thứ khác để làm, như tạo các nút tab bản thân và tham gia tất cả điều này để xuyên giao tiếp. Tôi khuyên bạn nên xem các ví dụ được cung cấp trong tệp ZIP ViewPagerExtensions mà bạn tải xuống từ GitHub. Đây chỉ là câu trả lời cho câu hỏi trong bình luận của bạn. Như bạn có thể thấy, nó không phải là nhiều mã sử dụng thư viện này.

+0

Tôi khuyên bạn nên sử dụng thư viện ViewPagerExtensions vì tôi thích mã được tạo và cũng vì nó cung cấp một vài loại tab khác nhau mà bạn có thể lựa chọn, bên cạnh việc tạo kiểu rất dễ dàng. Nếu bạn thấy phương pháp tiếp cận Rymnel bị giới hạn trong những gì bạn có thể làm, hãy chắc chắn thử nó. – davidcesarino

+0

cảm ơn, nó thực sự hữu ích. Bây giờ tôi cần phải tìm hiểu làm thế nào để thổi phồng hai bố trí cho mỗi vị trí bên trong: Object instantiateItem (Xem container, vị trí int), có bạn bất kỳ hướng dẫn? thx – Marckaraujo

+0

Cập nhật câu trả lời để hiển thị một ví dụ về cách bạn sử dụng 'FragmentpagerAdapter' để trả về các mảnh bạn cần. Nếu bạn cần bất kỳ sự trợ giúp nào khác, hãy tự do hỏi. – davidcesarino

38

Tôi thực sự đã quản lý để làm việc này mà không cần gì hơn thư viện ABS và thư viện hỗ trợ. Đây là mã của tôi:

public class ActionBarTabs extends SherlockFragmentActivity { 
CustomViewPager mViewPager; 
TabsAdapter mTabsAdapter; 
TextView tabCenter; 
TextView tabText; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
      WindowManager.LayoutParams.FLAG_FULLSCREEN); 

    mViewPager = new CustomViewPager(this); 
    mViewPager.setId(R.id.pager); 

    setContentView(mViewPager); 
    ActionBar bar = getSupportActionBar(); 
    bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
    bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE); 

    mTabsAdapter = new TabsAdapter(this, mViewPager); 

    mTabsAdapter.addTab(bar.newTab().setText("Home"), 
      ToolKitFragment.class, null); 
    mTabsAdapter.addTab(bar.newTab().setText("FujiSan"), 
      FujiFragment.class, null); 
} 

public static class TabsAdapter extends FragmentPagerAdapter implements 
     ActionBar.TabListener, ViewPager.OnPageChangeListener { 
    private final Context mContext; 
    private final ActionBar mActionBar; 
    private final ViewPager mViewPager; 
    private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); 

    static final class TabInfo { 
     private final Class<?> clss; 
     private final Bundle args; 

     TabInfo(Class<?> _class, Bundle _args) { 
      clss = _class; 
      args = _args; 
     } 
    } 

    public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) { 
     super(activity.getSupportFragmentManager()); 
     mContext = activity; 
     mActionBar = activity.getSupportActionBar(); 
     mViewPager = pager; 
     mViewPager.setAdapter(this); 
     mViewPager.setOnPageChangeListener(this); 
    } 

    public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) { 
     TabInfo info = new TabInfo(clss, args); 
     tab.setTag(info); 
     tab.setTabListener(this); 
     mTabs.add(info); 
     mActionBar.addTab(tab); 
     notifyDataSetChanged(); 
    } 

    @Override 
    public int getCount() { 
     return mTabs.size(); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     TabInfo info = mTabs.get(position); 
     return Fragment.instantiate(mContext, info.clss.getName(), 
       info.args); 
    } 

    @Override 
    public void onPageScrolled(int position, float positionOffset, 
      int positionOffsetPixels) { 
    } 

    @Override 
    public void onPageSelected(int position) { 
     mActionBar.setSelectedNavigationItem(position); 
    } 

    @Override 
    public void onPageScrollStateChanged(int state) { 
    } 

    @Override 
    public void onTabSelected(Tab tab, FragmentTransaction ft) { 
     Object tag = tab.getTag(); 
     for (int i = 0; i < mTabs.size(); i++) { 
      if (mTabs.get(i) == tag) { 
       mViewPager.setCurrentItem(i); 
      } 
     } 
    } 

    @Override 
    public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
    } 

    @Override 
    public void onTabReselected(Tab tab, FragmentTransaction ft) { 
    } 
} 
} 

Bạn tải nội dung tab của mình dựa trên những điều sau đây.

mTabsAdapter.addTab(bar.newTab().setText("Home"), 
      YOURFRAGMENTHERE.class, null); 

Điều này sẽ cung cấp cho bạn hiệu ứng "tab swipey" đáng yêu, như bạn tham khảo, với ABS, thư viện hỗ trợ và các đoạn. ABS thực sự làm cho điều này gần giống như làm việc với các thư viện bản địa. Tôi thực sự đã sao chép mã này trực tiếp từ ví dụ về tab phân trang của Google và sửa đổi nó một chút cho ABS.

Hy vọng điều này sẽ hữu ích!

+1

Vâng, tôi có thể hiểu điều đó, nhưng vấn đề của tôi là lớp phân mảnh, nó luôn luôn sụp đổ, bạn có thể vui lòng chia sẻ hoặc cho tôi một cách để tạo ra lớp mảnh này với 2 hoặc nhiều mảnh bên trong? thx – Marckaraujo

+0

Tuyệt vời. Cảm ơn bạn. Tốt hơn nhiều so với các ví dụ đi kèm với ABS vì điều này cung cấp cho các mảnh với các tab ICS mới, đáng yêu thay vì ví dụ ABS có vẻ hoàn nguyên về các tab cũ khi sử dụng các đoạn mã –

+2

Cảm ơn mã mẫu, đây chính xác là những gì tôi đã tìm kiếm! Có một điều mặc dù tôi dường như không hiểu, những gì là "CustomViewPager" tốt cho? Dường như nó hoạt động tốt với ViewPager mặc định. – Glenn85

3

Rất nhiều ví dụ thường ném một ngoại lệ (IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first) khi chuyển về tab đã chọn trước đó.

Tôi thích điều chỉnh ví dụ của Google bằng một số FragmentStatePageAdapter thay vì một đồng bằng FragmentPageAdapter, sẽ thay thế các đoạn cho bạn và giải quyết lỗi này. Thông thường điều này sẽ phá hủy các mảnh mà nó cho là có thể được loại bỏ để tiết kiệm không gian; ghi đè destroyItem(ViewGroup, int, Object) với một khối trống nếu bạn muốn luôn giữ các mảnh của mình.

Dưới đây là một ví dụ:

public class ActionBarTabs extends SherlockFragmentActivity { 
    CustomViewPager mViewPager; 
    TabsAdapter mTabsAdapter; 
    TextView tabCenter; 
    TextView tabText; 
    ActionBar mActionBar; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
      WindowManager.LayoutParams.FLAG_FULLSCREEN); 

     mViewPager = new CustomViewPager(this); 
     mViewPager.setId(R.id.pager); 

     setContentView(mViewPager); 
     mActionBar = getSupportActionBar(); 
     mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
     mActionBar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE); 

     mTabsAdapter = new TabsAdapter(this, mViewPager); 

     mTabsAdapter.addTab(mActionBar.newTab().setText("Page 1"), 
      YOURFRAGMENT_A.class, null); 
     mTabsAdapter.addTab(mActionBar.newTab().setText("Page 2"), 
      YOURFRAGMENT_B.class, null); 
     mTabsAdapter.addTab(mActionBar.newTab().setText("Page 3"), 
      YOURFRAGMENT_C.class, null); 
    } 

    public static class TabsAdapter extends FragmentPagerAdapter 
      implements ActionBar.TabListener, ViewPager.OnPageChangeListener { 
     private final Context mContext; 
     private final ActionBar mActionBar; 
     private final ViewPager mViewPager; 
     private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); 

     static final class TabInfo { 
      private final Class<?> clss; 
      private final Bundle args; 

      TabInfo(Class<?> _class, Bundle _args) { 
       clss = _class; 
       args = _args; 
      } 
     } 

     public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) { 
      super(activity.getSupportFragmentManager()); 
      mContext = activity; 
      mActionBar = activity.getSupportActionBar(); 
      mViewPager = pager; 
      mViewPager.setAdapter(this); 
      mViewPager.setOnPageChangeListener(this); 
     } 

     public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) { 
      TabInfo info = new TabInfo(clss, args); 
      tab.setTag(info); 
      tab.setTabListener(this); 
      mTabs.add(info); 
      mActionBar.addTab(tab); 
      notifyDataSetChanged(); 
     } 

     @Override 
     public int getCount() { 
      return mTabs.size(); 
     } 

     @Override 
     public Fragment getItem(int position) { 
      TabInfo info = mTabs.get(position); 
      return Fragment.instantiate(mContext, 
       info.clss.getName(), info.args); 
     } 

     @Override 
     public void onPageScrolled(int position, float positionOffset, 
      int positionOffsetPixels) { 
     } 

     @Override 
     public void onPageSelected(int position) { 
      mActionBar.setSelectedNavigationItem(position); 
     } 

     @Override 
     public void onPageScrollStateChanged(int state) { 
     } 

     @Override 
     public void onTabSelected(Tab tab, FragmentTransaction ft) { 
      Object tag = tab.getTag(); 
      for (int i = 0; i < mTabs.size(); i++) { 
       if (mTabs.get(i) == tag) { 
        mViewPager.setCurrentItem(i); 
       } 
      } 
     } 

     @Override 
     public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
     } 

     @Override 
     public void onTabReselected(Tab tab, FragmentTransaction ft) { 
     } 
    } 
} 

Hoạt động tốt với ABS và tương đối đơn giản để thực hiện.