简体   繁体   中英

Working with fragments inside viewpager - android

I have problem with position in my viewpager. I have container layout for my fragments that has button. Some fragments have picture, but some of them don't. I want to show button if fragment contains image. I know there is problem with my position that Container sends to fragment, but how to handle position in container, and why there is in first fragment 0 and 1 as position that container sends to first fragment.

Here is an example what I get as a result of my code: For example if 16. fragment contains image, button is shown on 15. fragment, but I want that button to show up in the same fragment (16. fragment).

Here is my code for 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());
        }
    }
}
}

and here is code for container 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);

        }

    });

}

}

I hope someone will help.

You have an identical for loop running in both your ContainerIspiti and PitanjaFragment to determine whether to display an image, and I think the issue is likely arising there. Instead, if each PitanjaFragment instance identifies whether it has an image, you can check the selected PitanjaFragment in the ViewPager to determine whether to display the button.

I haven't tested the following code, but it this should be enough to point you in the right direction.

First, add a private boolean field to the PitanjaFragment to indicate whether this instance is displaying an image:

PitanjaFragment.java

public class PitanjaFragment extends Fragment{
    private boolean isDisplayingImage;

Then, update this field when you've determined whether it's displaying an image:

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;
            }
        }

        // ...
    }

Then, add a getter so that other code can access this value:

PitanjaFragment.java

    public boolean hasImage() {
        return isDisplayingImage;
    }

Next, we'll move on to ContainerIspiti.java , where we will access the selected PitanjaFragment to find whether it has an image, then set the state of povecalo accordingly.

First, change povecalo back to a private, non-static field, since we are no longer trying to access it from PitanjaFragment (more info at the end of this answer):

ContainerIspiti.java

public class ContainerIspiti extends FragmentActivity{

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

Then, since FragmentStatePagerAdapter doesn't provide a way to retrieve a specific Fragment by position, you need to first add this functionality to your ScreenSlidePagerAdapter (see android - Retrieve a Fragment from a ViewPager for more info on this solution):

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);
        }
    }

Finally, you need to get the hasImage() value from the selected fragment, and set the state of povecalo accordingly:

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);
                        }
                    }
                }
            });

            // ...
        }
    }

Again, I haven't tested this code, so please do comment if you have any issues.

One other thing I'd like to point out is that using static fields to store instance data is not a good solution, even if you're sure that there will be only one instance of the object.

In this case, we cleaned up povecalo , but you're still using other static fields ( getAllPitanja and getAllImages ) in your Activity , ContainerIspiti , to store data that's generated by an instance of ContainerIspiti . PitanjaFragment then accesses these static fields directly from the class.

Instead, you should consider at least making them private non-static fields, and using getter methods to access them from the instance rather than from the class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM