我有Activity
ViewPager
。我还有一个Dialog
,它将检索包含用户将选择的一些项目的列表。现在,如何更新项目应显示的Fragment
作为附加到此片段的新视图?
这是我的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);
}
}
答案 0 :(得分:117)
从ViewPager更新片段
您需要实施getItemPosition(Object obj)
方法。
调用
时会调用此方法notifyDataSetChanged()
在ViewPagerAdaper
上。隐式地,此方法返回POSITION_UNCHANGED
值,这意味着:
“碎片应该在哪里,所以不要改变任何东西。”
因此,如果您需要更新片段,可以使用以下方式进行更新:
POSITION_NONE
方法返回getItemPosition()
。它
表示:“必须始终重新创建片段” 第二种方法的示例:
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);
}
如果您选择第一种方法,它可能看起来像:
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
注意:值得考虑一下你会选择哪种方法。
答案 1 :(得分:28)
我有时会遇到问题,所以在这种情况下总是避免使用FragmentPagerAdapter并使用FragmentStatePagerAdapter。
它对我有用。我希望它也适合你。
答案 2 :(得分:13)
答案 3 :(得分:10)
在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) {
}
});
应该有用。
答案 4 :(得分:4)
非常简单地覆盖片段中的方法:
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser){
actionView();
}
else{
//no
}
}
答案 5 :(得分:4)
您可以通过两种不同的方式更新片段,
第一种方式
喜欢@Sajmon
您需要实施getItemPosition(Object obj)
方法。
调用
时会调用此方法notifyDataSetChanged()
您可以在Github中找到一个示例,并在此post中找到更多信息。
第二种方式
我在viewpager中更新片段的方法是对setTag()
方法中的任何实例化视图使用instantiateItem()
方法。因此,当您想要更改数据或使您需要的视图无效时,您可以调用ViewPager上的findViewWithTag()
方法来检索先前实例化的视图,并根据需要修改/使用它,而无需删除/创建每次要更新某个值时都有新视图。
@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;
}
答案 6 :(得分:3)
接受的答案是不明白的,这就是为什么添加简单的解决方案。经过长时间的斗争 找到工作解决方案。
只需通知您的适配器,它的效果令人惊叹,
参考代码
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
进行投射上下文。
此代码只能帮助找到解决方案的目的。
答案 7 :(得分:2)
更新您的片段视图的一种非常简单而有效的解决方案。使用{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:*LoginProfile",
"iam:*AccessKey*",
"iam:*SSHPublicKey*"
],
"Resource": "arn:aws:iam::account-id-without-hyphens:user/${aws:username}"
},
{
"Effect": "Allow",
"Action": [
"iam:ListAccount*",
"iam:GetAccountSummary",
"iam:GetAccountPasswordPolicy",
"iam:ListUsers"
],
"Resource": "*"
}
]
}
方法。当片段即将对用户可见时,将调用它。在那里,您可以更新我们的观点(setUserVisibleHint()
或setText()
等)
setVisibility()
它适用于我的情况。希望能帮助到你!
答案 8 :(得分:2)
如果您使用Kotlin,您可以执行以下操作:
<强> 1。首先,您应该创建Fragment
并在interface RefreshData {
fun refresh()
}
class YourFragment : Fragment(), RefreshData {
...
override fun refresh() {
//do what you want
}
}
OnPageChangeListener
<强> 2。下一步是将ViewPager
添加到您的viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) { }
override fun onPageSelected(position: Int) {
viewPagerAdapter.notifyDataSetChanged()
viewPager.currentItem = position
}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { }
})
getItemPosition
3。覆盖Adapter
override fun getItemPosition(obj: Any): Int {
if (obj is RefreshData) {
obj.refresh()
}
return super.getItemPosition(obj)
}
0,0
0,1
0,2
0,3
0,4
1,0
1,2
...
答案 9 :(得分:1)
也许您将项目添加到片段中的方法应该是 public (放置在所需的片段中),并且应该具有与selectedItems相同类型的参数。
这将使它从活动中可见,它将具有selectedItems数组和瞧..
P.S。更好地命名addItemsFromArray(typeOfSelectedItems[] pSelectedItems)
因为名称addItem()
非常不具备意图
编辑:stackoverflow刚刚提出类似主题:)检查here以获取详细的想法实现.. :)
答案 10 :(得分:0)
1)在要更新的片段中创建一个处理程序。
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)在Activity / Fragment / Dialog中,无论你想要触发更新调用,都要获取对该处理程序的引用并发送消息(告诉你的片段更新)
// 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();
}
答案 11 :(得分:0)
我在ViewPager中有4个片段,但是每次用户单击该片段时,我只想在viewPager的位置0处更新一个片段“ FavoriteFragment”。 但是上面的代码都没有帮助我重新加载我想要的一个片段。 所以我尝试了这个,对我有用:
在我的FavoriteFragment中,我重写了onResume()
@Override
public void onResume() {
super.onResume();
updateUI(); // code to update the UI in the fragment
}
在托管viewPager的活动中覆盖addOnPageChangeListener()
并添加此代码
mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
if(position == 0) { // 0 = the first fragment in the ViewPager, in this case, the fragment i want to refresh its UI
FavoritesFragment fragment = (FavoritesFragment) mViewPager.getAdapter().instantiateItem(mViewPager, position);
fragment.onResume(); // here i call the onResume of the fragment, where i have the method updateUI() to update its UI
mViewPager.getAdapter().notifyDataSetChanged();
}
}
});
它非常适合我,刷新/重新加载我想要的一个片段。
答案 12 :(得分:0)
因为上述答案都没有对我有用,所以这是我的解决方法:
我将POSITION_NONE
与加载在setUserVisibleHint(boolean isVisibleToUser)
上而不是onStart()
上组合
如此处所示:https://stackoverflow.com/a/25676323/497366
在Fragment
中:
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// load data here
}else{
// fragment is no longer visible
}
}
和FragmentStatePagerAdapter
中,如Simon Dorociak https://stackoverflow.com/a/18088509/497366的最高答案所示:
@Override
public int getItemPosition(@NonNull Object object) {
return POSITION_NONE;
}
现在,片段在每次显示给用户时都会重新加载到视图中。
答案 13 :(得分:0)
很多答案,但为我完成工作的快速而肮脏的解决方案是有一种方法可以在 MainActivity 中初始化 pagerAdapter:
public void initPagerAdapter(){
pagerAdapter = new MainPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
tabLayout.setupWithViewPager(viewPager);
}
在我想要刷新的片段中,我只获取 MainActivity 并调用该方法:
MainActivity activity = (MainActivity) getContext();
activity.initPagerAdapter();