2013-04-26 34 views
1

我有一個ViewPager託管在一個片段中,該片段承載兩個ListFragments,這些片段由從SQLite查詢返回的Cursor填充。我最近在我的Action Bar中添加了一個微調器,允許用戶對ViewPager中的列表進行排序。但是,每次選擇微調控制器時,即使當前顯示第一個列表時,也只對第二個列表進行排序。看起來ViewPager似乎沒有跟蹤當前顯示的ListFragmentViewPager FragmentPagerAdapter只更新導航導航選項上的最後一個片段

我試過覆蓋getItemPosition在我的適配器和使用n otifyDataSetChanged,但這並沒有幫助。我試圖緩存當前活動片段的位置onAttach()也無濟於事。我也嘗試使用由我的適配器實現的OnSortChanged接口來嘗試重新創建ListFragments。我在這裏真的很茫然。這裏是我當前的代碼:

我的主要片段:

public class BeerMenuFragment extends SherlockFragment { 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.beer_menu_fragment, container, 
      false); 
    ViewPager pager = (ViewPager) view.findViewById(R.id.beer_pager); 

    pager.setAdapter(buildAdapter()); 
    return view; 
} 

private PagerAdapter buildAdapter() { 
    return (new BeerMenuAdapter(getChildFragmentManager())); 
} 
} 

FragmentPagerAdapter

public class BeerMenuAdapter extends FragmentPagerAdapter { 
private final int NUM_ITEMS = 2; 

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

/* 
* (non-Javadoc) 
* 
* @see android.support.v4.view.PagerAdapter#getPageTitle(int) 
*/ 
@Override 
public CharSequence getPageTitle(int position) { 
    return BeerListFragment.getTitle(position); 
} 

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

@Override 
public Fragment getItem(int position) { 
    return BeerListFragment.newInstance(position); 
} 
} 

最後,ListFragment:提前

public class BeerListFragment extends SherlockListFragment implements 
    OnNavigationListener { 
private static final String KEY_POSITION = "position"; 
private static final String KEY_SPINNER = "ab_spinner"; 
private IconicAdapter adapter; 
private static final String[] LABELS = { "Newest First", "Oldest First", 
     "Alphabetical" }; 
private Context ctxt; 
private int mShowItems; 
private Cursor data; 
private boolean synthetic = true; 

static BeerListFragment newInstance(int position) { 
    BeerListFragment frag = new BeerListFragment(); 
    Bundle args = new Bundle(); 

    args.putInt(KEY_POSITION, position); 
    frag.setArguments(args); 
    return (frag); 
} 

static String getTitle(int position) { 
    String header = "Draft"; 
    switch (position) { 
    case 0: 
     header = "Draft"; 
     break; 
    case 1: 
     header = "Bottle"; 
     break; 
    } 
    return (header); 
} 

/* 
* (non-Javadoc) 
* 
* @see 
* android.support.v4.app.ListFragment#onCreateView(android.view.LayoutInflater 
* , android.view.ViewGroup, android.os.Bundle) 
*/ 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    View result = inflater.inflate(R.layout.menu_list_fragment, container, 
      false); 

    ctxt = getActivity().getApplicationContext(); 
    SQLiteDatabase db = DatabaseHelper.getInstance(ctxt) 
      .getReadableDatabase(); 

    SherlockFragmentActivity activity = getSherlockActivity(); 
    ArrayAdapter<String> show = null; 
    ActionBar bar = activity.getSupportActionBar(); 

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 
     show = new ArrayAdapter<String>(bar.getThemedContext(), 
       android.R.layout.simple_spinner_item, LABELS); 
    } else { 
     show = new ArrayAdapter<String>(activity, 
       android.R.layout.simple_spinner_item, LABELS); 
    } 

    show.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
    bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); 
    bar.setListNavigationCallbacks(show, this); 

    if (savedInstanceState != null) { 
     bar.setSelectedNavigationItem(savedInstanceState 
       .getInt(KEY_SPINNER)); 
    } 

    data = getBeerMenuDbData(db, mShowItems); 

    // set up list adapter 
    adapter = new IconicAdapter(ctxt, data); 

    setListAdapter(adapter); 
    return (result); 
} 

private Cursor getBeerMenuDbData(SQLiteDatabase db, int showItems) { 
    String order; 
    String WHERE; 
    switch (showItems) { 
    case 1: // Oldest First 
     order = DbContract.BeerEntry.COLUMN_MODIFIED + " ASC"; 
     break; 
    case 2: // Alphabetical 
     order = DbContract.BeerEntry.COLUMN_TITLE + " ASC"; 
     break; 
    default: // Newest first 
     order = DbContract.BeerEntry.COLUMN_MODIFIED + " DESC"; 
     break; 
    } 
    String[] COLUMNS = { DbContract.BeerEntry._ID, 
      DbContract.BeerEntry.COLUMN_TITLE, 
      DbContract.BeerEntry.COLUMN_MODIFIED }; 
    WHERE = "serving='" + getTitle(getArguments().getInt(KEY_POSITION, -1)) 
      + "'"; 
    return db.query(DbContract.BeerEntry.TABLE_NAME, COLUMNS, WHERE, null, 
      null, null, order); 
} 

class IconicAdapter extends CursorAdapter { 
    LayoutInflater inflater; 

    IconicAdapter(Context context, Cursor data) { 
     super(context, data, 0); 
     inflater = LayoutInflater.from(context); 
    } 

    @Override 
    public void bindView(View view, Context context, Cursor cursor) { 
     String dateString = cursor.getString(2); 
     String[] dateArray = new String[3]; 
     TextView beerName = (TextView) view.findViewById(R.id.beerName); 
     TextView date = (TextView) view.findViewById(R.id.drinkDate); 
     RatingBar rb = (RatingBar) view.findViewById(R.id.ratingBar1); 

     beerName.setText(cursor.getString(1)); 
     if (!dateString.isEmpty()) { 
      dateArray = dateString.split("-"); 
      date.setText(dateArray[1] + "/" + dateArray[2] + "/" 
        + dateArray[0]); 
     } else { 
      date.setText(dateString); 
     } 
     rb.setRating((float) Math.random() * 5.0f); 
    } 

    @Override 
    public View newView(Context context, Cursor cursor, ViewGroup parent) { 
     return inflater 
       .inflate(R.layout.beer_club_list_item, parent, false); 
    } 
} 

/* 
* (non-Javadoc) 
* 
* @see android.support.v4.app.Fragment#onDestroy() 
*/ 
@Override 
public void onDestroy() { 
    super.onDestroy(); 
    ((CursorAdapter) getListAdapter()).getCursor().close(); 
} 

@Override 
public boolean onNavigationItemSelected(int itemPosition, long itemId) { 
    if (synthetic) { 
     synthetic = false; 
     return true; 
    } 

    mShowItems = itemPosition; 
    SQLiteDatabase db = DatabaseHelper.getInstance(ctxt) 
      .getReadableDatabase(); 
    Cursor newData = getBeerMenuDbData(db, mShowItems); 
    adapter.changeCursor(newData); 
    return true; 
} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    outState.putInt(KEY_SPINNER, getSherlockActivity() 
      .getSupportActionBar().getSelectedNavigationIndex()); 
} 
} 

感謝您的幫助!

+0

出於好奇,將調用記錄到'onNavigationItemSelected',並查看它是否被調用了兩個「BeerListFragment」的實例,或者只是一個實例。我的直覺是,當你爲第二個'BeerListFragment'調用'setListNavigationCallbacks'時,它會覆蓋第一個的回調,所以第一個沒有得到回調來對它的數據進行排序,而第二個總是這樣做。 – 2013-04-26 15:14:54

+0

@steven,我按照你的建議進行了登錄,並且我只收到一個對'onNavigationItemSelected'的調用,並且僅對第二個'BeerListFragment'進行調用,即使在顯示第一個片段時也是如此。 – 2013-04-26 16:02:55

回答

1

所以,你的問題是,你打電話bar.setListNavigationCallbacks(show, this)在你的BeerListFragment s內。在ViewPager中創建第一個BeerListFragment時,它將自己設置爲導航選擇的回調。然後,在創建第二個BeerListFragmentViewPager s恢復當前可見頁面左側和右側的頁面)時,它將自己設置爲導航選擇的回調,並且將覆蓋第一個BeerListFragment,該第一個BeerListFragment現在不會再獲取onNavigationItemSelected回調。

這一切的結果與您所看到的行爲,最後BeerListFragment調用bar.setListNavigationCallbacks將是一個接收onNavigationItemSelected回調。這就是爲什麼只有第二個BeerListFragment正在排序。

爲了解決這個問題,我建議你做幾件事情:

  1. 管理設置在BeerMenuFragment導航選擇回調,並將結果傳遞給孩子Fragment S中的在「活着」 (在onResume)。您需要使用answers here中的一個才能這樣做。
  2. 存儲應用的最新排序選項,並檢查每個BeerListFragmentonResume以查看它的排序是否匹配,如果不匹配,則應用排序。

這樣可以保證所有排序都適用於ViewPager中的所有頁面,無論它們是在應用排序時顯示還是不顯示。

+1

是的!謝謝@Steven的幫助。我使用了你在「回答這裏」鏈接中提到的'getRegisteredFragment'方法,然後設置一個'OnSortOrderChangedListener'接口來告訴子分片何時改變了排序順序! – 2013-04-26 19:26:39