【问题标题】:How to update fragment content from activity (viewpager)?如何从活动(viewpager)更新片段内容?
【发布时间】:2013-02-28 14:02:01
【问题描述】:

我有一个带有两个片段的简单 viewPager。每个片段都包含一个 TextView。我希望能够更新活动中显示的当前 textView 的文本。

活动:

public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        ArrayList<Fragment> fragments = new ArrayList<Fragment>();
        fragments.add(Fragment.instantiate(this, Live.class.getName()));
        fragments.add(Fragment.instantiate(this, Hit.class.getName()));

        this.pagerAdapter = new MyPagerAdapter(getSupportFragmentManager(),fragments);

        ViewPager pager = (ViewPager) findViewById(R.id.viewpager);
        pager.setAdapter(pagerAdapter);
    }
}

适配器:

public class MyPagerAdapter extends FragmentPagerAdapter {

    private final ArrayList<Fragment> fragments;

    public MyPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragments)
    {
        super(fm);
        this.fragments = fragments;
    }

    @Override
    public Fragment getItem(int position) {
        return this.fragments.get(position);
    }

    @Override
    public int getCount() {
        return this.fragments.size();
    }
}

片段:

public class Live extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        return inflater.inflate(R.layout.live, container,false);
    }
}

XML 片段:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent">
    <TextView android:layout_height="fill_parent"
              android:layout_width="fill_parent"
              android:text="First Fragment"
              android:id="@+id/status"/>
</LinearLayout>

每个片段都有一个 ID 为“status”的 TextView。 更新onCreateView 中的文本视图有效。但是我怎样才能从活动中的任何地方更新 textView 呢?

我试过这个没有成功:

片段:

public class Live extends Fragment {    
    public TextView tv;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.live, container,false);
        tv = (TextView) view.findViewById(R.id.status);

        return view;
    }
}

活动:

@Override
    protected void onResume() {
        super.onResume();
        Live frag = (Live) pagerAdapter.getItem(0);
        frag.tv.setText("Test 2");
    }

但它在 tv 上给了我一个 nullPointerException,可能是因为片段尚未膨胀。

我已经阅读了以下问题但没有成功:

【问题讨论】:

    标签: android android-fragments android-viewpager


    【解决方案1】:

    在您的MyPagerAdapter 类中,Android 仅在它想要创建新片段时才调用getItem(...)。所以在那里使用引用是有问题的,而不是你应该实例化片段。

    查看此答案support-fragmentpageradapter-holds-reference-to-old-fragments

    【讨论】:

    • 这是 100% 正确的。我已经和OP犯了同样的错误。不要保留自己的Fragments 数组。 FragmentPagerAdapter 中的 FragmentManager 包含所有 Fragments 并管理保存和恢复它们的状态。它们也可以被引用 - stackoverflow.com/questions/8785221/….
    • 好的,使用 : tamsler.blogspot.fr/2011/10/…tamsler.blogspot.fr/2011/11/… 的第二个解决方案。但是根据我的经验,在活动中创建或恢复时无法访问片段吗?
    • 当时可能无法使用/膨胀。为什么不使用 Fragments 自己的生命周期?
    • 只要创建/连接了ViewPagerFragmentPagerAdapter,就应该创建/恢复Fragments。我已经能够通过这两种方法访问它们,我总是在尝试对它做任何事情之前检查我的fragment.isResumed() 是否。老实说,我发布的链接中的答案更加优雅,因为您可以直接从FragmentManager 中获取您的Fragments,无需自己跟踪。
    【解决方案2】:

    我这样解决了这个问题,创建这样的适配器

    package com.yubraj.sample.adapter;
    
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentStatePagerAdapter;
    
    import com.yubaraj.sample.activities.RashiFragment;
    import java.util.List;
    
    
    public class PageSliderAdapter extends FragmentStatePagerAdapter {
        static String[] titleList = new String[] { "today",
                "this month", "this year" };
        List<String> rashi;
        // private static String TAG = "pagerscreenslider";
    
        public PageSliderAdapter(FragmentManager fm, List<String> rashiList) {
            super(fm);
            this.rashi = rashiList;
        }
        public void updateData(List<String> rashisList){
            rashi.clear();
            this.rashi = rashisList;
            notifyDataSetChanged();
        }
        @Override
        public int getItemPosition(Object object) {
            // TODO Auto-generated method stub
            return POSITION_NONE;
        }
    
        @Override
        public Fragment getItem(int position) {
            Fragment fragment = new RashiFragment();
            Bundle bundle = new Bundle();
            bundle.putString("RASHI", rashi.get(position));
            bundle.putInt("RASHI_TYPE", position);
            fragment.setArguments(bundle);
            return fragment;
        }
    
        @Override
        public int getCount() {
            return titleList.length;
        }
    
        @Override
        public String getPageTitle(int position) {
            return titleList[position];
        }
    
    
    }
    

    然后从你的活动中

    List<String> rashiCollection = getJSONFromDb(Dates);
    adapter.updateData(rashiCollection);
    

    【讨论】:

    • 我已经尝试了很长一段时间,但是每当我调用 notifydatasetchanged 时,它都会依次调用 addOnTabSelectedListener 导致无限循环
    【解决方案3】:
    @Override
        public int getItemPosition(Object object) {
        XXXFragment fragment = (XXXFragment) object;
            if(…condition){
        fragment.refresh(…);
        }
            return super.getItemPosition(object);
        }
    

    覆盖上述内容。当您调用 notifyDataSetChanged() 时,会触发上述方法。尽可能刷新。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-26
      • 1970-01-01
      相关资源
      最近更新 更多