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

相关问题