1

我試圖創建我的第一個Android應用程序,其外觀如下所示:存在具有由FragmentPagerAdapter初始化的多個片段的主要活動。還有另一個活動(SettingsActivity),我想列出所有片段名稱並允許隱藏其中一些片段名稱。要隱藏它們,我想使用以下內容:當使用FragmentPagerAdapter創建片段時,在運行時更改片段可見性

FragmentManager fm=getFragmentManager(); 
Fragment myFragment=fm.findFragmentByTag("tag"); 
fm.beginTransaction().hide(myFragment).commit(); 

問題是我不知道片段ID或標記,不知道它們是否存在。我如何得到它們?我是否應該切換到XML定義以使其成爲可能?

適配器:

public class TabsPagerAdapter extends FragmentPagerAdapter { 

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

@Override 
public Fragment getItem(int index) { 
    switch (index){ 
    case 0: 
     return new CoverFragment(); 
    case 1: 
     return new NumbersConverterFragment(); 
    case 2: 
     return new TempConverterFragment(); 
    case 3: 
     return new LengthConverterFragment(); 
    case 4: 
     return new AreaConverterFragment(); 
    case 5: 
     return new VolumeConverterFragment(); 
    case 6: 
     return new WeightConverterFragment(); 
    case 7: 
     return new SpeedConverterFragment(); 
    } 
    return null; 
} 

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

主要活動:

public class MainActivity extends FragmentActivity implements ActionBar.TabListener { 

private ViewPager viewPager; 
private TabsPagerAdapter tabsPagerAdapter; 
private ActionBar actionBar; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 

    String[] tabs={getString(R.string.title_section0), getString(R.string.title_section1),getString(R.string.title_section2)}; 

    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    viewPager=(ViewPager) findViewById(R.id.pager); 
    actionBar=getActionBar(); 
    tabsPagerAdapter=new TabsPagerAdapter(getSupportFragmentManager()); 

    viewPager.setAdapter(tabsPagerAdapter); 
    actionBar.setHomeButtonEnabled(false); 
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 

    for(String tab : tabs){ 
    actionBar.addTab(actionBar.newTab().setText(tab).setTabListener(this)); 
    } 


    viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { 

     @Override 
     public void onPageSelected(int position) { 
      // on changing the page 
      // make respected tab selected 
      actionBar.setSelectedNavigationItem(position); 
     } 
    ... 
    }); 

} 

片段佈局:

<?xml version="1.0" encoding="utf-8"?> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="#fbfdfb" 
    > 


    <TextView android:text="@string/celsius_" android:id="@+id/textView1" 
     android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView> 
    <EditText android:text="" android:id="@+id/txtCelsius" android:layout_width="match_parent" 
     android:layout_height="wrap_content"></EditText> 

    <TextView android:text="@string/fahrenheit_" android:id="@+id/textView1" 
     android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView> 
    <EditText android:text="" android:id="@+id/txtFahrenheit" android:layout_width="match_parent" 
     android:layout_height="wrap_content"></EditText> 

    <TextView android:text="@string/kelvin_" android:id="@+id/textView1" 
     android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView> 
    <EditText android:text="" android:id="@+id/txtKelvin" android:layout_width="match_parent" 
     android:layout_height="wrap_content"></EditText>  

</LinearLayout> 

片段類:

public class TempConverterFragment extends Fragment { 

EditText txtCelsius, txtFahrenheit, txtKelvin; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

    View rootView = inflater.inflate(R.layout.temp_converter_fragment, container, false); 

    txtCelsius = (EditText) rootView.findViewById(R.id.txtCelsius); 
    txtFahrenheit = (EditText) rootView.findViewById(R.id.txtFahrenheit); 
    txtKelvin = (EditText) rootView.findViewById(R.id.txtKelvin); 
     ... 
    } 
    ... 
} 

提前致謝。

回答

1

如果SettingsActivity不是持有FragmentPagerAdapter的Activity,那麼您將不得不重新創建所有片段。片段的性質與其活動密切相關。

如果SettingsActivity是持有FragmentPagerAdapter的Activity,那麼我記得,FragmentPagerAdapter會盡快初始化所有8個片段,以便在滑動時使它們準備就緒,這與FragmentStatePagerAdapter不同。這意味着您應該(我認爲)能夠在構造函數TabsPagerAdapter中創建每個片段並保留對它們的引用,您可以使用TabsPagerAdapter上的getter方法訪問它們。

這裏是如何讓你的pageradapter片段方便地訪問一個例子:

public class DisplayPagerAdapter extends FragmentStatePagerAdapter { 

    private static final String TAG = "DisplayPagerAdapter"; 

    SparseArray<DisplayFragment> registeredFragments = new SparseArray<DisplayFragment>(); 

    @Inject DisplayCoreModule display; 

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

    @Override 
    public int getCount() { 
     return (display != null && display.getPagesCount() > 0) ? display.getPagesCount() : 1; 
    } 

    @Override 
    public int getItemPosition(Object object) { 
     return POSITION_NONE; 
    } 


    @Override 
    public Fragment getItem(int position) { 
     Log.d(TAG, "getItem " + position); 
     return DisplayFragment.newInstance(position); 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     if (display != null && display.getPagesCount() > 0) { 
      return "Side " + (position+1); 
     } else { 
      return super.getPageTitle(position); 
     } 
    } 

    @Override 
    public Object instantiateItem(ViewGroup container, int position) { 
     Log.d(TAG, "instantiateItem " + position); 
     DisplayFragment fragment = (DisplayFragment) super.instantiateItem(container, position); 
     registeredFragments.put(position, fragment); 
     return fragment; 
    } 

    @Override 
    public void destroyItem(ViewGroup container, int position, Object object) { 
     Log.d(TAG, "destroyItem " + position); 
     registeredFragments.remove(position); 
     super.destroyItem(container, position, object); 
    } 

    public Fragment getRegisteredFragment(int position) { 
     return registeredFragments.get(position); 
    } 

    public SparseArray<DisplayFragment> getRegisteredFragments() { 
     return registeredFragments; 
    } 


} 

現在,如果你實現registeredFragments的這種用法,你可以調用tabsPagerAdapter.getRegisteredFragment(2)讓你TempConverterFragment。

SparseArray<DisplayFragment>SparseArray<Fragment>你的情況

現在,這並不解決您的SettingsActivity問題。但是,如果我理解正確,那麼直接在SettingsActivity的佈局XML中添加您想要的片段將是合理的。然後,它會很容易暫時隱藏任何使用或片段:

FragmentManager fm=getFragmentManager(); 
Fragment myFragment=fm.findFragmentById(R.id.frag_tempconverter) 
fm.beginTransaction().hide(myFragment).commit(); 

注意使用findFragmentById。標籤通常用於動態添加的片段(至少在我看來)。 findFragmentById肯定會返回一個片段,如果它是在XML佈局中定義的,但要清楚,它將是片段的新實例。

爲了解決你的問題:

如果我移動片段主要活動XML是什麼?將不是讓事情變得更簡單

不這麼認爲,更新的回答顯示瞭如何方便地訪問片段(從您的主要活動範圍內)。

雖然不知道我可以在SettingsActivity使用FragmentManager

當然可以。您可以添加新片段,訪問可用片段(使用findById從預定義的XML或使用findByTag動態添加)。但是,您不能訪問您的主要活動保留的片段的相同實例。

要共享片段和兩個活動之間的信息,您需要以某種方式保持片段的狀態(這是一個不同的主題)。

總而言之,我認爲你是在正確的道路上,你只需要結合正確的拼圖塊:)

+0

謝謝!我錯過了這些片段與活動相關聯。 SettingsActivity不包含適配器。在說「必須重新創建碎片」時,你是什麼意思?如果我將片段移動到主要活動XML中怎麼辦?它不會讓事情變得更簡單 - 我可以通過首先訪問活動來訪問它們的id - findViewById(R.id. user3155208

+0

沒問題:)用一些有用的東西更新了我的答案 – cYrixmorten

+0

非常感謝你的例子。我意識到我做錯了什麼。我會在一兩天內繼續。 – user3155208

相關問題