如何在另一个 Fragment 中更新 ListView?

Posted

技术标签:

【中文标题】如何在另一个 Fragment 中更新 ListView?【英文标题】:How do I update ListView in another Fragment? 【发布时间】:2014-04-06 11:21:10 【问题描述】:

我有一个 Activity,其中包含一个带有 2 个片段的 ViewPager。一个片段用于向ListView 添加项目,另一个片段保存ListView

我已经尝试了将近 3 天,但没有任何积极的结果。如何从第一个片段更新另一个片段的ListView

我正在尝试从包含 ViewPager 的 Activity 中调用更新 ListView 的方法,但它不起作用。

ViewPageractivity调用方法:

@Override
    public void onPageSelected(int position) 
    library.populateListView(getApplicationContext());
    aBar.setSelectedNavigationItem(position);

这是populateListView 方法:

public void populateListView(Context context)      
    CustomListViewAdapter customAdapter = new CustomListViewAdapter(getDatabaseArrayList(context), getActivity());

        if (lView != null)
        
            lView.setAdapter(customAdapter);
        
        customAdapter.notifyDataSetChanged();

但这不起作用,因为 lView 变量 (ListView) 为 null,因为在调用它时片段未显示。

【问题讨论】:

将数组传递给另一个片段,然后在显示时更新该片段。 【参考方案1】:

我假设函数populateListView() 是包含ListView 的片段的函数。每次拨打onPageSelected 时,您都会拨打populateListView()。如果您不检查正在选择的位置是什么。无论如何,populateListView() 方法应该是包含ListView 的 Fragment 的公共方法。您可以从 Activity 中的Viewpager 适配器实例化片段,然后调用此方法。这样listView 不应为空。

@Override
public void onPageSelected(int position) 
ListViewFragment frag=(ListViewFragment)adapter.instantiateItem(viewPager, 1);
//here adapter is the ViewPager Adapter and you must supply the viewpager that    contains 
//the fragments and also the position of the fragment to instantiate. 
//For example 0 or 1 etc.
frag.populateListView(getApplicationContext());
aBar.setSelectedNavigationItem(position);

【讨论】:

是的!我不敢相信解决方案一直这么简单。谢谢! onPageSelected 用于 ListFragment。扩展片段呢?有替代方法吗?【参考方案2】:

了解片段

请看这个link。我已经非常详细地解释了片段的概念。

特别注意rootview的定义:

public void onActivityCreared(Bundle savedInstanceState)
        super.onActivityCreated(savedInstanceState);
            // Do stuff on creation. This is usually where you add the bulk of your code. Like clickListners
        // You can define this object as any element in any of your xml's 
        View rootview = inflater.inflate(R.layout.xml_the_fragment_uses container,false);
        rootview.findViewById(R.id.your_id).setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            //Do something 
        
    );
 

在上面的例子中,我为点击监听器定义了一个按钮,但是您可以很容易地定义一个 ListView 及其相应的方法。

替代解决方案

第二种方法是使用getView 或getActivity(查看与活动通信部分)。

例如:

ListView listView = (ListView) getView().findViewById(R.id.your_listView_id);

OR    (more likely solution for your problem)

View listView = getActivity().findViewById(R.id.list);

请阅读this 帖子了解更多信息。

祝你好运。

【讨论】:

【参考方案3】:

要安全地执行此操作,您必须将listview 数据保存在更高级别的Parent-Activity 中,而不是fragments。通过创建构造函数private 来创建MainActivityclass singleton 类,并创建一个返回唯一初始化的`MainActivity 实例的getInstance 方法。

这将使您能够确保数据实例不会被重新初始化或丢失。然后,在您的片段的onResume 中将数据(从MainActivity 获取)重新设置为您的listview adapter 并从notifyDataSetChanged() 实例调用notifyDataSetChanged() 方法。

这样就可以了。

【讨论】:

抱歉回复晚了。问题是片段 onResume 没有执行。即使我在片段之间滑动,onResume 只执行一次,然后再也不执行。这是为什么呢? 因为它缓存在您的pager 中。 pager 总是创建当前片段,也许是左右一个片段以允许快速导航。 您可以通过pager.setOffScreenPageLimit(1);控制预加载片段的数量,这将创建唯一的当前片段 这似乎不起作用,我确实设置了pager.setOffScreenPageLimit(1),但在打开应用程序时它仍然会加载两个片段 @WhizW,您是否尝试过使用 FragmentStatePagerAdapter?见developer.android.com/reference/android/support/v4/app/…

以上是关于如何在另一个 Fragment 中更新 ListView?的主要内容,如果未能解决你的问题,请参考以下文章

如何从另一个 Fragment 更新一个 Fragment 的 ListView?

如何在另一个片段内膨胀另一个布局

SwiftUI:如何在另一个视图中更新传递的数组项

如何在另一个类中更新变量

如何在另一个小部件更新qt中的相同内容后更新小部件内容

如何编写一个触发器,根据在另一个表中采取的操作来更新一个表?