从ViewPager更新片段
我有一个ViewPager
Activity
。 我也有一个Dialog
,将检索用户将select的一些项目列表。 现在,我怎么能更新项目应该显示为附加到这个片段的新视图的片段?
这是我的ViewPager
的适配器:
public static class MyAdapter extends FragmentPagerAdapter { public MyAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { return 1; } @Override public android.support.v4.app.Fragment getItem(int position) { switch (position) { case 0: return new Fragment1(); default: return null; } } }
现在,这里是Fragment
:
public class Fragment1 extends Fragment{ @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); } @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); } @Override public ViewGroup onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub ViewGroup view = (ViewGroup)inflater.inflate(R.layout.screen1, container, false); } return view; } }
这是我想用来添加项目到我的Fragment
private void addItem() { // Instantiate a new "row" view. final ViewGroup[] newViews = new ViewGroup[selectedItems.length]; for(int i = 0; i < selectedItems.length; i++){ newViews[i] = (ViewGroup) LayoutInflater.from(this).inflate( R.layout.animated_layout_item, mContainerView, false); // Set the text in each new row. ((TextView) newViews[i].findViewById(android.R.id.text1)).setText(selectedItems[i]); // Because mContainerView has android:animateLayoutChanges set to true, // adding this view is automatically animated. mContainerView.addView(newViews[i], 0); // Set a click listener for the "X" button in the row that will remove the row. OnClickListener listener = new MyAddItemListener(newViews[i], mContainerView, this); newViews[i].findViewById(R.id.delete_button).setOnClickListener(listener); } }
从ViewPager更新片段
你需要实现getItemPosition(Object obj)
方法。
这个方法在你打电话时被调用
notifyDataSetChanged()
在你的ViewPagerAdaper
。 隐含地说,这个方法返回POSITION_UNCHANGED
值,这意味着像这样: “片段是它应该是这样的,所以不要改变任何东西。
所以如果你需要更新Fragment,你可以这样做:
- 始终从
getItemPosition()
方法返回POSITION_NONE
。 这意味着: “片段必须重新创build” - 你可以创build一些update()方法来更新你的Fragment(片段将自己处理更新)
第二种方法的例子:
public interface Updateable { public void update(); } public class MyFragment extends Fragment implements Updateable { ... public void update() { // do your stuff } }
而在FragmentPagerAdapter中,你会做这样的事情:
@Override public int getItemPosition(Object object) { MyFragment f = (MyFragment ) object; if (f != null) { f.update(); } return super.getItemPosition(object); }
如果你select第一种方法,它可以看起来像:
@Override public int getItemPosition(Object object) { return POSITION_NONE; }
注意:有必要考虑一下你会select哪种方法。
我遇到了一些问题,所以在这种情况下总是避免使用FragmentPagerAdapter并使用FragmentStatePagerAdapter。
它为我工作。 我希望它也能为你工作。
我按照Sajmon的回答执行了一个应用程序演示。 只是为了search这个问题的其他人。
您可以访问GitHub上的源代码
在你的PagerAdapter覆盖getItemPosition
@Override public int getItemPosition(Object object) { // POSITION_NONE makes it possible to reload the PagerAdapter return POSITION_NONE; }
之后添加viewPager.getAdapter()。notifyDataSetChanged(); 这个代码如下所示
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { viewPager.getAdapter().notifyDataSetChanged(); } @Override public void onPageScrollStateChanged(int state) { } });
应该工作。
接受的答案是不明白的,这就是为什么添加简单的解决scheme。 经过漫长的奋斗寻找工作解
只要通知你的适配器 ,它的工作令人惊叹,
参考代码
void setAdapter(int position) { PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(pagerAdapter); // when notify then set manually current position. viewPager.setCurrentItem(position); pagerAdapter.notifyDataSetChanged(); }
当您设置适配器并且想要刷新UI时调用此代码。
在您的片段中添加此代码进行刷新
((YourActivityName) getContext()).setAdapter(selectedTabPosition);
使用instanceof
投射上下文。
这个代码共享只是帮助寻找解决scheme的目的。
您可以用两种不同的方式更新片段,
第一种方式
像@Sajmon
你需要实现getItemPosition(Object obj)
方法。
这个方法在你打电话时被调用
notifyDataSetChanged()
你可以在Github中find一个例子,在这篇文章中有更多的信息。
第二种方式
我在viewpager中更新片段的方法是对instantiateItem setTag()
方法中的任何实例化视图使用setTag()
instantiateItem()
方法。 因此,当您想要更改数据或使需要的视图无效时,可以调用ViewPager上的findViewWithTag()
方法来检索先前实例化的视图,并根据需要修改/使用它,而无需删除/创build新视图每次你想更新一些值。
@Override public Object instantiateItem(ViewGroup container, int position) { Object object = super.instantiateItem(container, position); if (object instanceof Fragment) { Fragment fragment = (Fragment) object; String tag = fragment.getTag(); mFragmentTags.put(position, tag); } return object; } public Fragment getFragment(int position) { Fragment fragment = null; String tag = mFragmentTags.get(position); if (tag != null) { fragment = mFragmentManager.findFragmentByTag(tag); } return fragment; }
你可以在Github中find一个例子,或者在这篇文章中find更多的信息:
更新您的片段视图的一个非常简单而有效的解决scheme。 使用setUserVisibleHint()
方法。 当片段即将被用户看见时,它将被调用。 在那里你可以更新我们的视图( setText()
或setVisibility()
等)
@Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if(isVisibleToUser){ //Write your code to be executed when it is visible to user } }
它在我的情况下工作。 希望它有帮助!
也许你的方法添加项目到片段应公开 (放置在所需的片段),并应具有相同的types作为selectedItems参数..
这将使其可见的活动,这将有selectedItems数组和瞧…
更好地命名为addItemsFromArray(typeOfSelectedItems[] pSelectedItems)
原因名称addItem()
是相当不addItemsFromArray(typeOfSelectedItems[] pSelectedItems)
编辑:stackoverflow只是build议类似的话题:) 在这里查看详细的想法实现.. 🙂
很简单,覆盖片段中的方法:
@Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if(isVisibleToUser){ actionView(); } else{ //no } }
1)在你想要更新的片段中创build一个处理程序。
public static Handler sUpdateHandler; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... sUpdateHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); // call you update method here. } }; }
2)在活动/片段/对话框中,无论您想要触发更新调用,请获取对该处理程序的引用,并发送消息(告诉您的片段更新)
// Check if the fragment is visible by checking if the handler is null or not. Handler handler = TaskTabCompletedFragment.sUpdateHandler; if (handler != null) { handler.obtainMessage().sendToTarget(); }