使用FragmentPagerAdapter创建片段时,更改运行时的片段可见性



我正在尝试创建我的第一个Android应用程序,如下所示:有一个由FragmentPagerAdapter初始化的带有多个片段的主活动。还有另一个活动(SettingsActivity),我想列出所有的片段名称,并允许隐藏其中的一些。为了隐藏它们,我想使用以下方法:

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);
...
}
...
}

提前谢谢。

如果SettingsActivity不是持有FragmentPagerAdapter的Activity,则必须重新创建所有片段。碎片的性质与其活动密切相关。

如果SettingsActivity是持有FragmentPagerAdapter的Activity,那么我记得,FragmentPagedAdapter会尽快初始化所有8个片段,以便在您滑动时将其准备好,这与FragmentStatePagerAdaper不同。这意味着您应该(我认为)能够在构造函数TabsPagerAdapter中创建每个片段,并保留对它们的引用,您可以使用TabsPagetAdapter上的getter方法访问这些引用。

以下是一个如何轻松访问您的寻呼机片段的示例:

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的布局XML中是有意义的。然后可以很容易地暂时隐藏碎片或使用的任何东西

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

注意findFragmentById的使用。标签通常用于动态添加的片段(至少在我看来是这样)。如果findFragmentById是在XML布局中定义的,那么它肯定会返回一个片段,但需要明确的是,它将是该片段的一个新实例。

要解决您的问题:

如果我将片段移动到主活动XML,该怎么办?不会让事情变得更简单吗

不要这么认为,更新后的答案显示了如何轻松访问片段(从您的主要活动中)。

虽然不确定我是否可以在设置活动中使用FragmentManager

当然可以。您可以添加新的片段,访问可用的片段(使用findById从预定义的XML或使用findByTag动态添加)。但是,您不能访问由您的主活动保存的片段的同一实例。

为了在片段和两个活动之间共享信息,您需要以某种方式保持片段的状态(这是一个不同的主题)。

总而言之,我认为你走在了正确的道路上,你只需要把正确的拼图组合起来:)

相关内容

最新更新