当按钮被点击时刷新片段视图

3
我有一个片段活动,使用ViewPager来显示一组片段。在片段活动中,我有一个按钮,当点击它时,会向当前片段发送一条消息以刷新其内容。除了无法刷新片段视图之外,一切都正常(活动/当前片段通信)。通过getView()访问当前视图并不能成功,因为该函数返回null;似乎在创建片段后(调用ViewCreated),getView()就被销毁了。我错过了什么吗?如何使片段以编程方式重新绘制其内容?似乎唯一可行的方法是从父活动创建片段。我必须再次删除和添加片段才能达到这个效果吗?
以下是代码:
主要活动:
public class MainActivity extends FragmentActivity {

    private MyAdapter mAdapter;
    private static ViewPager mPager;

        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                setupViewPager();
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
                getMenuInflater().inflate(R.menu.activity_main, menu);
                return true;
        }

        @Override
        public boolean onPrepareOptionsMenu(Menu menu) {
                return super.onPrepareOptionsMenu(menu);
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
                switch (item.getItemId()) {

                case R.id.menu_test:
                        updateFragment();
                        return true;

                default: return true;
                }
        }

        private void updateFragment() {
                for (int i=0; i< mAdapter.getCount(); i++) {
                        SampleFragment fragment = (SampleFragment) mAdapter.getItem(i);
                        fragment.update();
                }
        }

        private void setupViewPager() {
                try {
                        mAdapter = new MyAdapter(getSupportFragmentManager());

                        mPager = (ViewPager) findViewById(R.id.pager);
                        mPager.setAdapter(this.mAdapter);

                } catch (Exception e) {
                        e.printStackTrace();
                }
        }

        public class MyAdapter extends FragmentPagerAdapter {

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

                @Override
                public Fragment getItem(int position) {
                        SampleFragment fragment = new SampleFragment(position); 
                        return fragment;
                }

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

以及片段类:

public class SampleFragment extends Fragment{

        private int myPosition = -1;

        public SampleFragment(int position) {
                this.myPosition = position;
        }

        @Override
        public void onAttach(Activity activity) {
                super.onAttach(activity);
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                View view = inflater.inflate(R.layout.fragment, container, false);
                update(view, "Updated from onCreateView");
                return view;
        }

        @Override
        public void onActivityCreated(Bundle bundle) {
                super.onActivityCreated(bundle);
        }

        @Override
        public void onViewCreated(View view, Bundle savedInstanceState) {
                super.onViewCreated(view, savedInstanceState);

                view.findViewById(R.id.textTitle).setOnClickListener(myClickListener);
        }

        private OnClickListener myClickListener = new OnClickListener() {
                @Override
                public void onClick(View v) {
                        switch (v.getId()) {

                        case R.id.textTitle:
                                break;

                        }
                }
        };

        public void update() {
                update(getView(), "Updated from main");
        }

        private void update(View view, String subtitleText) {
                TextView title = (TextView) view.findViewById(R.id.textTitle);
                TextView subtitle = (TextView) view.findViewById(R.id.textSubtitle);

                title.setText("Fragment " + myPosition);
                subtitle.setText(subtitleText);
        }
}

在主活动中的菜单项调用时,view.FindViewById发生错误(视图为空)。


你能否在Fragment中捕获/存储你想要修改的布局视图?例如:TextView mTitle = (TextView)findById(R.id.title); 然后稍后只需编辑该视图的文本即可。 - Steve Pomeroy
我已经尝试过了,但当我需要更新布局时,它们也变成了null。 - a.p.
你能否贴一些代码来帮助解释正在发生的事情? - Steve Pomeroy
我已经发布了片段活动和片段的代码。问题是由片段内部对getView()的调用引起的,该调用由活动中的fragment.update()触发。 - a.p.
UgglyNoodle的回答很好。看起来问题的很大一部分在于你更新片段的位置。在Android中,Adapter负责更新它们发出的View的内容(通过填充数据来“适应”视图)。对于Fragment也应该是如此。 - Steve Pomeroy
1个回答

4
您可以查看本文,了解如何在ViewPager中保留片段的引用。
该页面描述了两种方法。第一种方法涉及在使用FragmentManager添加片段时设置标记。然后,您可以使用findFragmentByTag()检索片段。但是,我没有看到如何在使用FragmentPagerAdapter或FragmentStatePagerAdapter时使其工作,因为这些实现会为您添加片段。如果您使用自己的自定义PagerAdapter,则可能适用于您。
另一种方法适用于FragmentPagerAdapter或FragmentStatePagerAdapter,并涉及保留所有片段的映射,在您的getItem()destroyItem()实现中进行更新。这种方法对我有效。
一旦您有当前片段的引用,您只需调用片段中的方法即可刷新其视图。

第二种方法肯定更好。谢谢! - Philipp E.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接