单击按钮时刷新片段视图

Posted

技术标签:

【中文标题】单击按钮时刷新片段视图【英文标题】:Refresh fragment view when button is clicked 【发布时间】:2012-09-26 17:03:03 【问题描述】:

我有一个片段活动,它使用 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(视图为空)发生错误。

【问题讨论】:

您能否从您的布局中捕获/存储您希望在片段中修改的视图?例如。 TextView mTitle = (TextView)findById(R.id.title);然后再编辑视图的文本? 我已经尝试过了,但是当我需要更新布局时它们也变成了空值。 你能发布一些代码来帮助解释发生了什么吗? 我已经发布了片段活动和片段的代码。问题是由在活动中由 fragment.update() 调用的片段内部调用 getView() 造成的。 UgglyNoodle 的回答很好。在您更新片段的地方看起来有很多问题。在 android 中,Adapters 负责更新它们发出的Views 的内容(它们通过填充视图将数据“调整”到视图)。 Fragments 也应该如此。 【参考方案1】:

您可以查看this article,它解释了如何在 ViewPager 中保留对片段的引用。

页面上描述了两种方法。第一个涉及在使用 FragmentManager 添加片段时设置标签。然后您可以使用findFragmentByTag() 检索片段。但是,我没有看到如何使用 FragmentPagerAdapter 或 FragmentStatePagerAdapter 来完成这项工作,因为这些实现会为您添加片段。如果您使用自己的自定义 PagerAdapter,这可能对您有用。

另一种适用于 FragmentPagerAdapter 或 FragmentStatePagerAdapter 的方法涉及保留所有片段的映射,并在 getItem()destroyItem() 实现中进行更新。这种方法对我有用。

一旦你有了对当前片段的引用,你就可以在你的片段中调用一个方法来刷新它的视图。

【讨论】:

第二种方法肯定更好。谢谢!

以上是关于单击按钮时刷新片段视图的主要内容,如果未能解决你的问题,请参考以下文章

如何刷新片段上的列表视图

单击按钮刷新时如何刷新小部件列表视图?

单击XIB按钮时刷新当前视图控制器数据请求

如何覆盖搜索视图中的向上按钮行为

我想从片段中隐藏片段容器视图(在 MainActivity 布局内),但是当我单击任务按钮然后重新打开应用程序时它不起作用

刷新 UINavigationController 堆栈中的视图