1

I am trying to create a gallery app with View Pager.All is working fine with image displaying correctly in View pager and swiping through images work fine.I have set a floating button to save image in my detail activity with a fragment.But when i click that button to save image then it saves the next image instead of current image.i.e if i click save button when i am on image 1 then it saves image 2.

Also when i swipe through images and click save button then sometimes it won't recognize my click event and sometime it replaces saved image.

Can someone guide me through what am i doing wrong?

DetaitActivity:

public class DetailActivity extends BaseActivity {

/**
 * The {@link android.support.v4.view.PagerAdapter} that will provide
 * fragments for each of the sections. We use a
 * {@link FragmentPagerAdapter} derivative, which will keep every
 * loaded fragment in memory. If this becomes too memory intensive, it
 * may be best to switch to a
 * {@link android.support.v4.app.FragmentStatePagerAdapter}.
 */
private SectionsPagerAdapter mSectionsPagerAdapter;

private String dirDownloadName = AppConstants.SDCARD_DIR_NAME;

public ArrayList<ImageModel> data = new ArrayList<>();
int pos;

public static GestureImageView downloadImage;
/**
 * The {@link ViewPager} that will host the section contents.
 */
private ViewPager mViewPager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_detail);

    data = getIntent().getParcelableArrayListExtra("data");
    pos = getIntent().getIntExtra("pos", 0);

    setTitle(data.get(pos).getName());
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    setupNavDrawerBackPress(); // for back icon press

    // Create the adapter that will return a fragment for each of the three
    // primary sections of the activity.
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(), data);
    // Set up the ViewPager with the sections adapter.
    mViewPager = (ViewPager) findViewById(R.id.container);
    mViewPager.setPageTransformer(true, new DepthPageTransformer());

    mViewPager.setAdapter(mSectionsPagerAdapter);
    mViewPager.setCurrentItem(pos);

    Log.v("Detail:","pos:" +pos);
    mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {

            //noinspection ConstantConditions
            setTitle(data.get(position).getName());

        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });
    File file = getFile(data.get(pos).getName(), false);
    final Context mContext;
    mContext = this;

    if (!file.exists()){
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.download_image);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Bitmap bitmap = ((GlideBitmapDrawable) downloadImage.getDrawable()).getBitmap();
                saveImageToSDCard(bitmap, data.get(pos).getName());
            }
        });
    }

}

@Override protected int getLayoutResource() {
    return R.layout.activity_detail;
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_detail, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}


/**
 * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
 * one of the sections/tabs/pages.
 */
public class SectionsPagerAdapter extends FragmentPagerAdapter {
    public ArrayList<ImageModel> data = new ArrayList<>();

    public SectionsPagerAdapter(FragmentManager fm, ArrayList<ImageModel> data) {
        super(fm);
        this.data = data;
    }

    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).
        return PlaceholderFragment.newInstance(position, data.get(position).getName(), data.get(position).getUrl());
    }

    @Override
    public int getCount() {
        // Show 3 total pages.
        return data.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return data.get(position).getName();
    }

    public GestureImageView getImageView(){
        return PlaceholderFragment.imageView;
    }
}

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {
    /**
     * The fragment argument representing the section number for this
     * fragment.
     */

    String name, url;
    int pos;
    private static final String ARG_SECTION_NUMBER = "section_number";
    private static final String ARG_IMG_TITLE = "image_title";
    private static final String ARG_IMG_URL = "image_url";
    public static GestureImageView imageView;

    @Override
    public void setArguments(Bundle args) {
        super.setArguments(args);
        this.pos = args.getInt(ARG_SECTION_NUMBER);
        this.name = args.getString(ARG_IMG_TITLE);
        this.url = args.getString(ARG_IMG_URL);
    }

    /**
     * Returns a new instance of this fragment for the given section
     * number.
     */
    public static PlaceholderFragment newInstance(int sectionNumber, String name, String url) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, sectionNumber);
        args.putString(ARG_IMG_TITLE, name);
        args.putString(ARG_IMG_URL, url);
        fragment.setArguments(args);
        return fragment;
    }

    public PlaceholderFragment() {
    }

    @Override
    public void onStart() {
        super.onStart();

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_detail, container, false);


        downloadImage = (GestureImageView) rootView.findViewById(R.id.detail_image);
        Glide.with(getActivity()).load(url).thumbnail(0.1f).into(imageView);
        Glide.with(getContext()).load(url)
                .into(downloadImage);

        return rootView;
    }


}

private File getFile(String fname, Boolean makeDir){

    File myDir = new File(
            Environment
                    .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
            dirDownloadName);


    fname = fname+".jpeg";
    Log.v("Detail:","fname:" +fname);
    File file = new File(myDir, fname);

    return file;
}

public void saveImageToSDCard(Bitmap bitmap, String fname) {
    File file = getFile(fname, true);
    Log.v("Detail:","fname save:" +fname);
    if (file.exists()){
        file.delete();
    }

    try {
        file.createNewFile();
        FileOutputStream out = new FileOutputStream(file);

        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);

        out.flush();
        out.close();
        Toast.makeText(
                getApplicationContext(),getApplicationContext().getString(R.string.toast_saved)
                        .replace("#",
                                "\"" + dirDownloadName + "\""),
                Toast.LENGTH_SHORT).show();

    } catch (Exception e) {
        e.printStackTrace();
        Toast.makeText(getApplicationContext(),
                getApplicationContext().getString(R.string.toast_saved_failed),
                Toast.LENGTH_SHORT).show();
    }
}

}

Fragment deatil xml:

<com.alexvasilkov.gestures.views.GestureImageView

xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"

android:id="@+id/detail_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:padding="0dp"
tools:context="com.xxxx.stockwall.MainActivity" />

Activit detai xml:

<android.support.v4.view.ViewPager
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

<android.support.design.widget.FloatingActionButton
    android:id="@+id/download_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="@dimen/fab_margin"
    android:src="@android:drawable/ic_dialog_email" />

<android.support.design.widget.FloatingActionButton
    android:id="@+id/set_wallpaper_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="@dimen/fab_margin"
    android:visibility="invisible"
    android:src="@android:drawable/ic_dialog_info" />

Hi kareem.Thankx for the tips.I tried your solution and made few changes but it's still now working.It still saves next image instead of current image.Also when saving to sd card, it keeps replacing current one image. Here are my updated code

fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            PlaceholderFragment fragment = mSectionsPagerAdapter.getItem(mViewPager.getCurrentItem());

            Bitmap bitmap = ((GlideBitmapDrawable)  fragment.imageView.getDrawable()).getBitmap();
            saveImageToSDCard(bitmap, data.get(pos).getName());
        }
    });

On my SectionsPagerAdapter adapter:

@Override
public PlaceholderFragment getItem(int position) {
    // getItem is called to instantiate the fragment for the given page.
    // Return a PlaceholderFragment (defined as a static inner class below).
    return PlaceholderFragment.newInstance(position, data.get(position).getName(), data.get(position).getUrl());
}

I am starting to learn android(PHP developer now). So don't know much android right now. I am really sorry if i am missing something here.

  • what does Log.v("Detail:","pos:" +pos); displays? does it correctly prints the index of the correct view of a viewpager?? – AADProgramming Apr 29 '16 at 16:46
  • Log.v("Detail:","pos:" +pos); displays correct position only when i click image from gallery. But 'pos' remains unchanged when i swipe images from detail view. – Sujit Maharjan Apr 29 '16 at 16:52

2 Answers2

0

I think that you should not depend on the getView of the FragmentPagerAdapter to determine the current image, instead try getting the current position of the ViewPager and getting the fragment in that position and to retrieve the image from that fragment, you could have downloadImage attribute inside the PlaceholderFragment. on the View.OnClickListener() of fab you should get the fragment by

PlaceholderFragment fragment = SectionsPagerAdapter.getItem(mViewPager.getCurrentItem());
fragment.downloadImage

and continue your code

references How do I get the child View of a ViewPager at a given item

Community
  • 1
  • 1
kareem adel
  • 491
  • 3
  • 8
0

The easiest way I found was to load the image directly into the bitmap instead in an image view using the Picasso or Universal-Image Loader.

private void shareImage() {

    // Directly loading image into a bitmap and sharing the image

    Picasso.with(getActivity())
            .load(images.get(viewPager.getCurrentItem()))
            .into(new Target() {

                @Override
                public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {

                    // Download/Share your image here

                @Override
                public void onBitmapFailed(Drawable errorDrawable) {

                }

                @Override
                public void onPrepareLoad(Drawable placeHolderDrawable) {

                }
            });
Burhan Shakir
  • 237
  • 4
  • 11