在 viewpager 中处理片段 - android

Working with fragments inside viewpager - android

我在 viewpager 中的位置有问题。我有带有按钮的片段的容器布局。有些碎片有图片,有些则没有。如果片段包含图像,我想显示按钮。我知道容器发送到片段的位置有问题,但是如何处理容器中的位置,以及为什么第一个片段 0 和 1 作为容器发送到第一个片段的位置。

这是我的代码得到的示例: 例如,如果 16.fragment 包含图像,则按钮显示在 15.fragment 上,但我希望该按钮显示在同一片段(16.fragment)中。

这是我的片段代码 class

public class PitanjaFragment extends Fragment{

public static final String ARG_PAGE = "page";

private int broj;
private ImageView image;
public static String uri;
public static ListView listView;
public static boolean odgovoreno;

public static boolean tocno;
public static ArrayList<Odgovor> odgovorList;
private PitanjaAdapter adapter;
private DBTools db;

public static PitanjaFragment create(int pageNumber) {
    PitanjaFragment fragment = new PitanjaFragment();
    Bundle args = new Bundle();
    Log.i("broj u pageru je sljedeci", String.valueOf(pageNumber));
    args.putInt(ARG_PAGE, pageNumber);
    fragment.setArguments(args);
    return fragment;
}

public PitanjaFragment() {

}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    broj = getArguments().getInt(ARG_PAGE);
}

@Override
public View onCreateView(LayoutInflater inflater,
        @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_pitanja, container, false);
    image = (ImageView) view.findViewById(R.id.imageSlikaImageView);
    db = new DBTools(getActivity());
    listView = (ListView) view.findViewById(R.id.listView);
    updateDisplay();
    return view;
}

public void updateDisplay() {
    image.setImageBitmap(null);
    for (int j = 0; j < ContainerIspiti.getAllImages.size(); j++) {
        if (ContainerIspiti.getAllImages.get(j).getIdPitanja() == ContainerIspiti.getAllPitanja.get(broj)
                .getIdPitanja()
                && ContainerIspiti.getAllImages.get(j).getNazivSlike() != null) {
            image.setVisibility(View.VISIBLE);
            ContainerIspiti.povecalo.setEnabled(true);
            uri = PregledZnakova.PHOTOS_BASE_URL
                    + ContainerIspiti.getAllImages.get(j).getNazivSlike();
            int rounded_value = 40;    
            DisplayImageOptions options = new DisplayImageOptions.Builder().showImageForEmptyUri(R.drawable.placeholder).showStubImage(R.drawable.placeholder).cacheInMemory().cacheOnDisc().displayer(new RoundedBitmapDisplayer(rounded_value)).build();
            ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getActivity().getApplicationContext()).defaultDisplayImageOptions(options).build();               
            ImageLoader.getInstance().init(config); 
            ImageLoader.getInstance().displayImage(uri, image,options);

        } else {
            image.setVisibility(View.GONE);
            ContainerIspiti.povecalo.setEnabled(false);
        }
    }

    odgovorList = db.getAllOdgovore(Integer.toString(ContainerIspiti.getAllPitanja.get(broj)
            .getIdPitanja()));
    adapter = new PitanjaAdapter(getActivity(),
            R.layout.pitanja_entry, odgovorList);
    listView.setAdapter(adapter);

    for (int i=0;i<ContainerIspiti.getAllPitanja.size();i++){
        if (ContainerIspiti.getAllPitanja.get(i).isTocno()){
            Log.i("Ovo pitanje je tocno", ContainerIspiti.getAllPitanja.get(i).getTextPitanja());
        }
    }
}
}

这是容器的代码 class

public class ContainerIspiti extends FragmentActivity{

private ImageView next, previous, odgovori, informacije;
public static ImageView povecalo;
private TextView textPitanja, brojPitanja;
private ViewPager pager;
private PagerAdapter mPagerAdapter;
public static ArrayList<Pitanja> getAllPitanja;
public static ArrayList<Pitanje_has_Slika> getAllImages;
private Intent intent;
private DBTools db = new DBTools(this);
private ProgressDialog pDialog;
private int broj = 0;
private Typeface custom_font;
private HashMap<Integer, List<Integer>> odgBrojPitanja;
private static RelativeLayout relative;
private List<Integer> kliknuti;
private static ImageView expandedImageView;
private static ImageLoaderConfiguration config;
private static DisplayImageOptions options;

@Override
protected void onCreate(Bundle arg0) {
    super.onCreate(arg0);
    Bundle bundle = new Bundle();
    intent = getIntent();
    custom_font = Typeface.createFromAsset(getAssets(), "fonts/Aller.ttf");
    odgBrojPitanja = new HashMap<Integer, List<Integer>>();
    setContentView(R.layout.activity_container_pitanja);
    Dohvati d = new Dohvati();
    d.execute();
    relative = (RelativeLayout) findViewById(R.id.RelativeLayoutContainerPitanjeExpandedImageView);
    povecalo = (ImageView) findViewById(R.id.povecaloButtonPitanja);
    povecalo.setImageResource(R.drawable.gumb_povecalo);
    textPitanja = (TextView) findViewById(R.id.kategorijaTextViewPitanjeActivity);
    brojPitanja = (TextView) findViewById(R.id.brojPitanjaTextViewPitanjeActivity);
    pager = (ViewPager) findViewById(R.id.pagerPitanja);
    options = new DisplayImageOptions.Builder().cacheInMemory().cacheOnDisc().build();
    config = new ImageLoaderConfiguration.Builder(this.getApplicationContext()).defaultDisplayImageOptions(options).build();
}

private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {

    public ScreenSlidePagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return PitanjaFragment.create(position);
    }

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

}

private class Dohvati extends AsyncTask<String, String, String>{

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(ContainerIspiti.this);
        pDialog.show();
    }

    @Override
    protected String doInBackground(String... params) {
        getAllPitanja = db
                .getAllPitanja(intent.getStringExtra("id_kategorije"));
        getAllImages = db.getAllPitanjaImages();
        return null;
    }
    @Override
    protected void onPostExecute(String result) {
        pDialog.dismiss();
        mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
        pager.setAdapter(mPagerAdapter);
        pager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
            @Override
            public void onPageSelected(int position) {

                invalidateOptionsMenu();
                broj = position;
                brojPitanja.setText(String.valueOf(broj+1) + "/" + String.valueOf(getAllPitanja.size()));
                for (int j = 0; j < getAllImages.size(); j++){
                    if (getAllPitanja.get(broj).getIdPitanja() == getAllImages.get(j).getIdPitanja()){
                        //Log.i("getAllImages koja sadrzi je sljedeca", getAllImages.get(j).getNazivSlike());
                        povecalo.setVisibility(View.VISIBLE);
                    } else {
                        povecalo.setVisibility(View.INVISIBLE);
                    }
                }
            }
        });
        textPitanja.setText(intent.getStringExtra("NAZIV_KATEGORIJE"));
        brojPitanja.setText(String.valueOf(broj+1) + "/" + getAllPitanja.size());
    }

}

public static void zoomImage(String uri){

    ImageLoader.getInstance().init(config); 
    ImageLoader.getInstance().displayImage(uri, expandedImageView,options);
    relative.bringToFront();
    relative.setVisibility(View.VISIBLE);
    expandedImageView.setScaleType(ScaleType.CENTER_INSIDE);
    expandedImageView.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View v) {

            relative.setVisibility(View.GONE);

        }

    });

}

}

希望有人帮忙

您的 ContainerIspitiPitanjaFragment 中有一个相同的 for 循环 运行 来确定是否显示图像,我认为问题可能出现了那里。相反,如果每个 PitanjaFragment 实例都标识它是否有图像,则可以检查 ViewPager 中选择的 PitanjaFragment 来确定是否显示该按钮。

我尚未测试以下代码,但这应该足以为您指明正确的方向。

首先,向 PitanjaFragment 添加一个私有布尔字段以指示此实例是否正在显示图像:

PitanjaFragment.java

public class PitanjaFragment extends Fragment{
    private boolean isDisplayingImage;

然后,当您确定它是否显示图像时更新此字段:

PitanjaFragment.java

    public void updateDisplay() {
        image.setImageBitmap(null);
        for (int j = 0; j < ContainerIspiti.getAllImages.size(); j++) {
            if (ContainerIspiti.getAllImages.get(j).getIdPitanja() == 
                    ContainerIspiti.getAllPitanja.get(broj).getIdPitanja()
                    && ContainerIspiti.getAllImages.get(j).getNazivSlike() != null) {
                image.setVisibility(View.VISIBLE);

                // the Views on an Activity instance should not be accessed statically
                //ContainerIspiti.povecalo.setEnabled(true);

                // Instead, update the new boolean field
                isDisplayingImage = true;

                // ...

            } else {
                image.setVisibility(View.GONE);

                // the Views on an Activity instance should not be accessed statically
                //ContainerIspiti.povecalo.setEnabled(false);

                // Instead, update the new boolean field
                isDisplayingImage = false;
            }
        }

        // ...
    }

然后,添加一个getter以便其他代码可以访问这个值:

PitanjaFragment.java

    public boolean hasImage() {
        return isDisplayingImage;
    }

接下来,我们将继续ContainerIspiti.java,在这里我们将访问所选的PitanjaFragment以查找它是否有图像,然后相应地设置povecalo的状态。

首先,将 povecalo 改回私有的非静态字段,因为我们不再尝试从 PitanjaFragment 访问它(本答案末尾有更多信息):

ContainerIspiti.java

public class ContainerIspiti extends FragmentActivity{

private ImageView next, previous, odgovori, informacije, povecalo;
//public static ImageView povecalo;

然后,由于 FragmentStatePagerAdapter 不提供按位置检索特定 Fragment 的方法,您需要先将此功能添加到 ScreenSlidePagerAdapter(请参阅 android - Retrieve a Fragment from a ViewPager 了解有关此解决方案的更多信息):

ContainerIspiti.java

    private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
        SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();

        // ...

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            Fragment fragment = (Fragment) super.instantiateItem(container, position);
            registeredFragments.put(position, fragment);
            return fragment;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            registeredFragments.remove(position);
            super.destroyItem(container, position, object);
        }

        public Fragment getRegisteredFragment(int position) {
            return registeredFragments.get(position);
        }
    }

最后需要从选中的片段中获取hasImage()值,并相应设置povecalo的状态:

ContainerIspiti.java

    private class Dohvati extends AsyncTask<String, String, String>{
        // ...

       pager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
            @Override
            protected void onPostExecute(String result) {
                // ...

                pager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
                    @Override
                    public void onPageSelected(int position) {
                        // ...

                        // Replace the for() loop with this
                        if (((PitanjaFragment) mPagerAdapter.getRegisteredFragment(position)).hasImage()) {
                            povecalo.setEnabled(true);
                            povecalo.setVisibility(View.VISIBLE);
                        }
                        else {
                            povecalo.setEnabled(false);
                            povecalo.setVisibility(View.INVISIBLE);
                        }
                    }
                }
            });

            // ...
        }
    }

同样,我还没有测试过这段代码,所以如果您有任何问题,请发表评论。

我想指出的另一件事是,使用静态字段来存储实例数据并不是一个好的解决方案,即使您确定只有一个对象实例也是如此。

在这种情况下,我们清理了 povecalo,但您仍在 ActivityContainerIspiti,用于存储由 ContainerIspiti 的实例生成的数据。 PitanjaFragment 然后直接从 class 访问这些静态字段。

相反,您至少应该考虑将它们设为私有非静态字段,并使用 getter 方法从实例而不是从 class.

访问它们