ViewPager没有使用FragmentStatePagerAdapter进行更新

时间:2015-08-20 22:09:06

标签: android android-viewpager fragmentstatepageradapter

我有两个COERCIBLEfragmentsFragment AFragment B列出了所有产品,Fragment A显示了产品及其图片的详细信息。

Fragment B来电Fragment AFragment B从网络服务中提取数据,并使用Fragment B设置为ViewPager。最初它显示正确的图像,但此后它始终具有相同的图像。

如果我们从片段B中的任何点击事件中触发Adapter,那么它可以完美地工作但我们必须在片段B可见时立即显示

请查看代码。

adapter.notifyDataSetChanged()

片段B

 public class ImageAdapter extends FragmentStatePagerAdapter {

private List<String> pImageURL;

public ImageAdapter(FragmentManager fm, List<String> imageURL) {
    super(fm);
    // TODO Auto-generated constructor stub

    pImageURL = imageURL;
    Utility.showLog("PagerAdapter URL", pImageURL.toString());
}

@Override
public Fragment getItem(int position) {
    // TODO Auto-generated method stub

    String imageURL = pImageURL.get(position);

    PImageFragment imageFragment = (PImageFragment) PImageFragment.getInstance();
    imageFragment.setProductImage(imageURL);
    return imageFragment;
}

@Override
public int getItemPosition(Object object) {

    PImageFragment pFragment = (PImageFragment) object;
    String URL = pFragment.getProductImage();

    int position = pImageURL.indexOf(URL);

    if (position>=0)
        URL = pImageURL.get(position);

    if (position>=0)
        return position;
    else
        return POSITION_NONE;

}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return pImageURL.size();
   }
}

PImage Fragment

   // Image Loading Process

    String p_images = model.getProdutImageURL();

    imageUrl = new ArrayList<String>();


    if (p_images.contains(","))
        imageUrl.addAll(Arrays.asList(p_images.split(",")));
    else
        imageUrl.add(p_images);

    mAdapter = new ImageAdapter(getChildFragmentManager(), imageUrl);
    vPager.setPageTransformer(true, new DepthPageTransformer());
    vPager.setAdapter(mAdapter);

    mAdapter.notifyDataSetChanged();

更新

public class PImageFragment extends Fragment {

private static final String TAG = "Product_Images_Fragment";
private View rootView;

private ImageView ivProductImage;
private String imageURL;

@Override
@Nullable
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // TODO Auto-generated method stub

    rootView = inflater.inflate(R.layout.p_detail_images, container, false);

    bindComponents(rootView);
    loadImages(imageURL);
    return rootView;

}

public static Fragment getInstance() {

    Fragment fragment = new PImageFragment();
    return fragment;
}

public void setProductImage(String image_url) {

    imageURL = image_url;
    Utility.showLog(TAG + "Received URL : ", imageURL.toString());

}

public String getProductImage() {

    return imageURL;
}

private void bindComponents(View v) {
    // TODO Auto-generated method stub

    ivProductImage = (ImageView) v.findViewById(R.id.ivProductImage);
}

private void loadImages(String image_url) {


    Utility.showLog(TAG,
            "http://baryapp.com/kickzexchange/assets/products/" + image_url);

    final ProgressBar pBar = (ProgressBar) rootView
            .findViewById(R.id.pBarLoader);
    pBar.setVisibility(View.VISIBLE);

    ImageLoader imgLoader = VolleySingleton.getInstance().getImageLoader();

    imgLoader.get("http://baryapp.com/kickzexchange/assets/products/"
            + image_url, new ImageListener() {

        @Override
        public void onErrorResponse(VolleyError vError) {
            // TODO Auto-generated method stub

            Utility.showLog(TAG, vError.getLocalizedMessage() + "");
        }

        @Override
        public void onResponse(ImageContainer response, boolean result) {
            // TODO Auto-generated method stub

            if (response.getBitmap() != null) {

                ivProductImage.setImageBitmap(response.getBitmap());
                pBar.setVisibility(View.GONE);

            }
        }
    });
}


}

最新更新

    // This is how fragment A calls fragment B
   ProductDetail pDetail = new ProductDetail();

    Bundle bundle = new Bundle();
    bundle.putString("product_id", productList.get(position).getProductID());
    bundle.putString("product_title", productList.get(position).getProductTitle());

    pDetail.setArguments(bundle);

    ((MyTabActivity) mActivity).navigateFragment(Utility.BUY_TAB, pDetail,
            true);

非常感谢任何帮助/想法。

6 个答案:

答案 0 :(得分:1)

您可以为片段使用以下PagerFragment基类,并根据需要实现onVisible方法:

public abstract class PagerFragment extends Fragment {

private boolean mCalled = false;
private boolean mWasVisible = false;
private boolean mIsResumed = false;
private boolean mIsPaused = false;

protected void onVisible() {
    mCalled = true;
}

protected void onHide() {
    mCalled = true;
}

/**
 * {@inheritDoc}
 * 
 * @see android.app.Fragment#onAttach(android.app.Activity)
 */
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
}

/**
 * {@inheritDoc}
 * 
 * @see android.app.Fragment#onDetach()
 */
@Override
public void onDetach() {
    super.onDetach();
}

/**
 * {@inheritDoc}
 * 
 * @see android.app.Fragment#onResume()
 */
@Override
public void onResume() {
    super.onResume();
    mIsPaused = false;
    mIsResumed = true;
    setUserVisibleHint(getUserVisibleHint());
}

/**
 * {@inheritDoc}
 * 
 * @see android.app.Fragment#onPause()
 */
@Override
public void onPause() {
    mIsPaused = true;
    mIsResumed = false;
    setUserVisibleHint(getUserVisibleHint());
    super.onPause();
}

/**
 * {@inheritDoc}
 * 
 * @see android.app.Fragment#setUserVisibleHint(boolean)
 */
@Override
public void setUserVisibleHint(boolean visible) {
    super.setUserVisibleHint(visible);

    mCalled = false;
    if (mIsResumed) {
        if (visible) {
            performVisible();
            mWasVisible = visible;
        } else {
            performHide();
            mWasVisible = visible;
        }
    } else if (mIsPaused && mWasVisible) {
        performHide();
        mWasVisible = visible;
    }

}

private void performVisible() {
    onVisible();
    if (!mCalled) {
        throw new SuperNotCalledException("PagerFragment " + this + " did not call through to super.onVisible()");
    }
}

private void performHide() {
    onHide();
    if (!mCalled) {
        throw new SuperNotCalledException("PagerFragment " + this + " did not call through to super.onHide()");
    }
}

}

或者您只需在Fragment A上预加载数据,并在加载数据时通知适配器,然后更改页面。始终可以从ViewPager动态添加和删除片段。因此,您也可以尝试使用旧数据删除片段,然后再创建一个新片段。

答案 1 :(得分:1)

您尚未展示关键部分,即MyTabActivity.navigateFragment()

我相信您正在尝试重用现有的Fragment B实例,并通过Fragment.setArguments()传递新数据

创建片段后,setArguments没有用处

  1. 每次创建片段B的新实例并替换现有的实例,或
  2. 使用片段
  3. 中的自定义函数传递新数据

    我建议使用方法1,因为通过这样做,即使活动重新创建,您的数据也会保留,例如屏幕旋转。对于方法2,您需要额外的工作来处理活动重新创建。

答案 2 :(得分:1)

如果我理解正确,您可以尝试使用onPageSelected并根据位置更新您选择的页面上的片段。

        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {

        //use this to run when your fragment is visible

        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });

答案 3 :(得分:1)

您可能知道在后台进程中加载​​图像。即使用排球库

即使在流程完成之前,您的adapter.notifyDataSetChanged()也会被调用。 但正如你所说的,当你在按钮上调用它时单击它可以工作,然后解决方案很简单。

  

在后台调用adapter.notifyDataSetChanged()后   过程完成。

即里面: -

  @Override
      public void onResponse(ImageContainer response, boolean result) {
        // TODO Auto-generated method stub

        if (response.getBitmap() != null) {

            ivProductImage.setImageBitmap(response.getBitmap());
            pBar.setVisibility(View.GONE);
            adapter.notifyDataSetChanged();
        }
    }
});

答案 4 :(得分:0)

当你使用FragmentStatePagerAdapter时,getItem()只被调用一次,所以最初你有正确的图像,但它保持不变。

您应该使用回调界面重新加载数据。因此,当选择片段A中的一个项目时,您将在片段B中重新加载数据。为此,您需要添加

public void reloadData() {
//relaod your data here
}

然后在片段A中创建一个像这样的回调接口

public interface itemSelectedListener {
    void onItemSelected(View view, int position)
}

在包含两个片段的活动中实现此接口

in

onItemSelected() {
    MyFragmentB myFragmentB = ...//get your fragment
    myFragmentB.reloadData();
}

答案 5 :(得分:0)

最后我已经解决了答案。 Fragment B已保存在navigateFragment中,已被以下行阻止,并且有效。

    if (mCurrentFragment != null) {
        if (mCurrentFragment instanceof GetProducts)
            saveFragmentState(mCurrentFragment.getClass().getName(), mCurrentFragment);
    }