2013-02-05 198 views
5

我想使用viewpager來顯示幾個片段。目前我只有一個片段,但它似乎永遠不會被實例化。我嘗試使用pager.setCurrentItem(0),但適配器中的getItem方法永遠不會被調用。有沒有人看到爲什麼我的片段不加載在下面的代碼?ViewPager +片段 - 片段未顯示

主要活動

public class MainActivity extends SherlockFragmentActivity { 

MyPagerAdapter adapter; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    // Create the FragmentPager Adapter and assign it to the viewpager 
    adapter = new MyPagerAdapter(getSupportFragmentManager(), this); 
    ViewPager pager = (ViewPager) findViewById(R.id.pager); 
    pager.setAdapter(adapter); 
    pager.setCurrentItem(0); 

    // Setup the tab page indicator 
    TabPageIndicator indicator = (TabPageIndicator) findViewById(R.id.indicator); 
    indicator.setViewPager(pager); 
} 

class MyPagerAdapter extends FragmentStatePagerAdapter { 
    private SparseArray<Fragment> fragmentPageMap; 

    public MyPagerAdapter(FragmentManager fm, Activity context) { 
     super(fm); 
     fragmentPageMap = new SparseArray<Fragment>(); 
    } 

    @Override 
    public Fragment getItem(int index) { 
     switch (index) { 
     case 0: 
      if (fragmentPageMap.get(index) != null) { 
       SherlockListFragment scheduleFragment = ScheduleListFragment.newInstance(); 
       fragmentPageMap.put(index, scheduleFragment); 
       return scheduleFragment; 
      } else { 
       return fragmentPageMap.get(index); 
      } 
     default: 
      return null; 
     } 
    } 

    /*@Override 
    public void destroyItem(View container, int index, Object object) { 
     super.destroyItem(container, index, object); 
     fragmentPageMap.remove(index); 
    }*/ 

    @Override 
    public CharSequence getPageTitle(int index) { 
     return ((ViewPagerPage) fragmentPageMap.get(index)).getTitle(); 
    } 

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

public interface ViewPagerPage { 
    String getTitle(); 
} 

MainActivity佈局

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:orientation="vertical" > 

<com.viewpagerindicator.TabPageIndicator 
    android:id="@+id/indicator" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:textStyle="bold" /> 

<android.support.v4.view.ViewPager 
    android:id="@+id/pager" 
    android:layout_width="fill_parent" 
    android:layout_height="0dp" 
    android:layout_weight="1" /> 

</LinearLayout> 

ScheduleListFragment

public class ScheduleListFragment extends SherlockListFragment implements ViewPagerPage { 

private ScheduleAdapter adapter; 
private final String TITLE = "Schedule"; 

public static ScheduleListFragment newInstance() { 
    ScheduleListFragment newFrag = new ScheduleListFragment(); 
    Bundle args = new Bundle(); 
    newFrag.setArguments(args); 
    return newFrag; 
} 

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    return inflater.inflate(R.layout.fragment_schedule_list, null); 
} 

@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
    inflater.inflate(R.menu.fragment_schedule_list, menu); 
} 

// Container Activity must implement this interface 
public interface OnAddItemClickedListener { 
    public void onAddItemClicked(); 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle item selection 
    switch (item.getItemId()) { 
    case R.id.add_item: 
     Intent myIntent = new Intent(getActivity(), AddScheduleItemActivity.class); 
     startActivityForResult(myIntent, 1); 

     return true; 
    default: 
     return super.onOptionsItemSelected(item); 
    } 
} 

public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
    setHasOptionsMenu(true); 

    adapter = new ScheduleAdapter(getActivity()); 

    setListAdapter(adapter); 
} 

private class SampleItem { 
    public String tag; 
    public int iconRes; 

    public SampleItem(String tag, int iconRes) { 
     this.tag = tag; 
     this.iconRes = iconRes; 
    } 
} 

public class ScheduleAdapter extends ArrayAdapter<SampleItem> { 

    public ScheduleAdapter(Context context) { 
     super(context, 0); 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 
     if (convertView == null) { 
      convertView = LayoutInflater.from(getContext()).inflate(R.layout.results_list_row, null); 
     } 
     ImageView icon = (ImageView) convertView.findViewById(R.id.row_icon); 
     icon.setImageResource(getItem(position).iconRes); 
     TextView title = (TextView) convertView.findViewById(R.id.row_title); 
     title.setText(getItem(position).tag); 

     return convertView; 
    } 

} 

@Override 
public String getTitle() { 
    return TITLE; 
} 

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (resultCode == android.app.Activity.RESULT_OK) { 
     String name = (String) data.getExtras().get("TEXT"); 
     Toast.makeText(getActivity(), name, Toast.LENGTH_LONG).show(); 
    } 
} 

片段佈局

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" > 

<ListView 
    android:id="@android:id/list" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" /> 

<TextView 
    android:id="@+id/textView1" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="TextView" /> 

</LinearLayout> 

謝謝, 彌敦道

目前的解決方案:

改變了適配器的構造函數初始化第一個片段,並將其添加到內部地圖。有沒有人看到這樣做有什麼問題,或者改善上述任何代碼的方法?謝謝!

public MyPagerAdapter(FragmentManager fm, Activity context) { 
     super(fm); 
     fragmentPageMap = new SparseArray<Fragment>(); 
     SherlockListFragment scheduleFragment = ScheduleListFragment.newInstance(); 
     fragmentPageMap.put(0, scheduleFragment); 
    } 

回答

4

getCount()MyPagerAdapter所以沒有片段將被創建返回0,它應該返回N如果你想N片段被實例化。

fragmentPageMap是在構造函數創建爲空時getCount()被調用,getCount()getItem(index)之前調用,這就是爲什麼getCount()返回0

在這種情況下,你不需要switch因爲你是實例相同每次碎片。但是如果你在實例化不同片段的時候你會需要它。

@Override 
public Fragment getItem(int index) { 
    switch (index) { 
    case 0: 
     return new Fragment1(); 
    case 1: 
     return new Fragment2(); 
    } 
    return null; 
} 
+0

*爲什麼*你認爲getCount()返回0?請詳細說明以作出更好的回答。 –

+0

因爲'fragmentPageMap'在構造函數中創建,並且在調用getCount()時爲空。 'getCount()'在'getItem(index)'之前被調用。你可以在調試器中查看。 – rubenlop

+0

謝謝!你是對的返回0.然而,我不認爲值應該硬編碼,我想能夠動態地添加/刪除片段。 switch語句在那裏,因爲不久將會添加更多的片段。 – Nath5