簡體   English   中英

使用FragmentPagerAdapter創建片段時,在運行時更改片段可見性

[英]Change fragment visibility in runtime when the fragment was created using 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,那么我記得,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 該標記通常用於動態添加的片段(在我看來是最少的)。 如果在XML布局中定義了findFragmentById則肯定會返回一個片段,但為了清楚findFragmentById ,它將是該片段的新實例。

要解決您的問題:

如果將片段移動到主要活動XML怎么辦? 不會簡化事情嗎

別這么認為,更新后的答案顯示了如何輕松訪問片段(從您的主要活動中)。

雖然不確定我可以在SettingsActivity中使用FragmentManager

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

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

總而言之,我認為您走在正確的道路上,您只需要結合正確的難題即可:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM