【问题标题】:Pager inside a fragment片段内的寻呼机
【发布时间】:2014-07-08 20:23:00
【问题描述】:

正如我的previous question 中所述,在ViewPager 内的Fragments 之一打开另一个Fragment 后,在ViewPager 内显示Fragments 时遇到了一些问题。

我设法通过在FragmentTransaction 中使用add() 解决了这个问题。不幸的是,这又产生了另一个问题:

我在我的应用程序中使用ActionBar。当我两次选择相同的菜单项时,我遇到了与以前相同的问题,它没有在ViewPager 中显示任何Fragments

主页活动代码(点击事件上的操作栏被调用)

public class HomePageActivity extends SherlockFragmentActivity implements ICallback {

    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private SherlockActionBarDrawerToggle mDrawerToggle;

    private CharSequence mDrawerTitle;
    private CharSequence mTitle;
    private String[] mChampionsMenuItems;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setTheme(R.style.Theme_Sherlock);
        setContentView(R.layout.activity_home_page);

        mTitle = mDrawerTitle = getTitle();
        mChampionsMenuItems = getResources().getStringArray(R.array.champions_array);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);

        mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
        mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, mChampionsMenuItems));
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);    
        getSupportActionBar().setBackgroundDrawable(getResources().getDrawable(R.color.navy_blue));
        getSupportActionBar().setDisplayShowTitleEnabled(false);

        mDrawerToggle = new SherlockActionBarDrawerToggle(this, mDrawerLayout, R.drawable.menu_icon, R.string.drawer_open, R.string.drawer_close) {

            public void onDrawerClosed(View view) {
                getSupportActionBar().setTitle(mTitle);
                supportInvalidateOptionsMenu();
            }

            public void onDrawerOpened(View drawerView) {
                getSupportActionBar().setTitle(mDrawerTitle);
                supportInvalidateOptionsMenu();
            }
        };
        mDrawerLayout.setDrawerListener(mDrawerToggle);

        if (savedInstanceState == null) {
            onFragmentChange(new HomeActivityFragment(), true);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }

        switch (item.getItemId()) {
            default: return super.onOptionsItemSelected(item);
        }
    }

    private class DrawerItemClickListener implements ListView.OnItemClickListener {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectItem(position);
        }
    }

    private void selectItem(int position) {    
        switch (position) {

            case 0:
                onFragmentChange(new Fragment1(), false);
                break;

            case 1:
                onFragmentChange(new Fragment2(), false);
                break;

            case 2:
                onFragmentChange(new MyPointFragment3(), false);
                break;

            case 3:
                // onFragmentChange(new HomeActivityFragment(), true);
                break;

            case 4:
                onFragmentChange(new QueriesFragment(), false);
                break;

            case 5:
                onFragmentChange(new GalleryFragment(), false);
                break;

            default:
                break;
        }

        mDrawerList.setItemChecked(position, true);
        mDrawerLayout.closeDrawer(mDrawerList);

    }

    @Override
    public void setTitle(CharSequence title) {
        mTitle = title;
        getSupportActionBar().setTitle(mTitle);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    public void onFragmentChange(Fragment fragment, boolean flag) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.content_frame, fragment, fragment.getClass().getName());
        transaction.commit();
    }    
}

这是包含ViewPagerFragment

public class Fragment1 extends Fragment implements OnClickListener {

        ICallback callback;
        private LinearLayout headerContainer;
        private ImageView headerLogo;
        private TextView headerName;
        private Button menuBarButton;

        MyAdapter adapter;
        ViewPager pager;
        ActionBar actionBar;

        private Button progOverview, progStr, bonusPoint;

        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            if (activity instanceof ICallback) {
                this.callback = (ICallback) activity;
            }
            actionBar = activity.getActionBar();
            actionBar.show();
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View rootView = setUpView(inflater, container);        
            return rootView;
        }

        private View setUpView(LayoutInflater inflater, ViewGroup container) {

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

            headerContainer = (LinearLayout) rootView.findViewById(R.id.second_top_header);
            headerContainer.setBackgroundColor(getResources().getColor(R.color.prog_str_blue));
            headerLogo = (ImageView) rootView.findViewById(R.id.header_logo);
            headerLogo.setBackgroundResource(R.drawable.about_champions_ticon);
            headerName = (TextView) rootView.findViewById(R.id.header_name);
            headerName.setText(R.string.about_champ_title);

            adapter = new MyAdapter(getFragmentManager());
            pager = (ViewPager) rootView.findViewById(R.id.pager);
            pager.setAdapter(adapter);

            return rootView;
        }


        @Override
        public void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
        }

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            if (savedInstanceState != null) {
                // Restore last state for checked position.
            }
        }
        }  
    }

这是ViewPager 中的Fragments 之一:

public class ProgramOverViewFragment extends Fragment {

    ICallback callback;

    @Override
    public void onAttach(Activity activity) {           
        super.onAttach(activity);
        if (activity instanceof ICallback) {
            this.callback = (ICallback) activity;
        }    
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_program_overview, container, false);

        TextView termsAndCond = (TextView) rootView.findViewById(R.id.terms_and_condition_button);
        termsAndCond.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                FragmentManager fragmentManager = getSupportFragmentManager();
                FragmentTransaction transaction = fragmentManager.beginTransaction();
                transaction.replace(R.id.content_frame, fragment);
                fragment.setRetainInstance(true);
                transaction.addToBackStack(null);
                transaction.commit();    
            }
        });

        return rootView;
    }
}

我的FragmentStatePagerAdapter

public class MyAdapter extends FragmentStatePagerAdapter {    

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

    @Override
    public android.support.v4.app.Fragment getItem(int index) {
        switch (index) {
            case 0: return new ProgramOverViewFragment();
            case 1: return new ProgramStructureFragment();
            case 2: return new BonusPointFragment();
        }
        return null;
    }

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

感谢您的帮助!

【问题讨论】:

  • 如果您不向我们展示一些相关代码或错误消息,没有人可以帮助您。请在您的问题中编辑它们。
  • @XaverKapeller - 请检查我用代码更新了我的问题。
  • 不要在你的 onCreate() 中调用 onFragmentChange() 尝试使用 .add 方法,然后在你的 onFragmentChange() 方法中使用 .replace() 而不是 .add()
  • @Tinashe- 是的,我们可以这样做,但在我的情况下,它会产生一些其他问题。 :)

标签: android android-fragments android-viewpager


【解决方案1】:

你到底想做什么?您是否尝试替换 ViewPager 中的片段?或者您是否尝试在 ViewPager 中的 Fragment 中替换 Fragment?或者你想尝试做一些完全不同的事情?如果您详细解释您要做什么,我只能给您一个准确的解决方案。无论如何,这是我猜测可能是错误的:


我认为你的问题是你使用了错误的FragmentManager。有多种不同的FragmentManagers,但基本上有两种情况:

  1. 您想从Activity 添加/替换/删除Fragment
  2. 您想从另一个Fragment 添加/替换/删除Fragment

只要我没有看到您的布局文件,我就无法确定这两个选项中的哪一个适合您的情况。


如果你想在另一个 Fragment 中替换一个 Fragment 的解决方案

如果您想在另一个Fragment 内的Fragment 上执行FragmentTransaction,那么您需要使用子FragmentManager!您可以像这样在Fragment 中使用子FragmentManager

FragmentManager fragmentManager = getChildFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.content_frame, fragment);
fragment.setRetainInstance(true);
transaction.addToBackStack(null);
transaction.commit();

如您所见,您只需要使用getChildFragmentManager() 而不是getSupportFragmentManager()


正如我已经说过的,如果没有关于您的情况的任何进一步信息,我无法给您更准确的答案。所以请尽量向我解释你想做什么,我相信我们可以解决这个问题。

【讨论】:

  • 感谢您的回复,我要做的是:我在片段中有一个视图寻呼机,其中包含三个视图(片段)。所有这 3 个视图都包含一个将打开另一个片段的按钮。 ** 关于使用 replace() 方法:当我打开片段时(通过在任何视图中单击该按钮),片段会显示,但是当我单击后退按钮时,视图 Pager 中的一个视图变为空白。关于使用 add() 方法:上述问题已解决,但在我的操作栏中,当我两次单击同一选项卡(即具有视图寻呼机的同一片段)时,我的视图寻呼机视图为空白。
【解决方案2】:

最后我发现我在代码中做错了什么:

我正在使用下面的代码为片段内的视图寻呼机设置适配器:

  adapter = new MyAdapter(getFragmentManager());
            pager = (ViewPager) rootView.findViewById(R.id.pager);
            pager.setAdapter(adapter);

通过将getFragmentManager() 替换为getChildFragmentManager(),我们解决了这个问题。根据我的理解,我在片段中使用视图寻呼机,这就是为什么我必须使用 getChildFragment 管理器来存储我的 viewPager 的转换。 这可能对某人有帮助吗?这个问题仍然有待更好的解决方案。

【讨论】:

    猜你喜欢
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多