【问题标题】:Issue/Bug when saving image from View Pager从 View Pager 保存图像时的问题/错误
【发布时间】:2017-05-16 02:58:32
【问题描述】:

我正在尝试使用 View Pager 创建一个图库应用程序。所有工作正常,图像在 View pager 中正确显示,并且在图像中滑动工作正常。我设置了一个浮动按钮以使用片段将图像保存在我的详细活动中。但是,当我单击该按钮保存图像时,它会保存下一个图像而不是当前图像。即,如果我在图像 1 上单击保存按钮,则它会保存图像 2。

此外,当我浏览图像并单击保存按钮时,有时它无法识别我的单击事件,有时它会替换保存的图像。

有人可以指导我解决我做错了什么吗?

详细活动:

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

}

片段细节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" />

活动详情 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" />

嗨,kareem。感谢您的提示。我尝试了您的解决方案并进行了一些更改,但它现在仍然有效。它仍然保存下一张图像而不是当前图像。此外,当保存到 sd 卡时,它会不断替换当前的一张图像。这是我更新的代码

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

在我的 SectionsPagerAdapter 适配器上:

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

我开始学习 android(现在是 PHP 开发人员)。所以现在不太了解android。如果我在这里遗漏了什么,我真的很抱歉。

【问题讨论】:

  • Log.v("Detail:","pos:" +pos);显示?它是否正确打印 viewpager 的正确视图的索引??
  • Log.v("Detail:","pos:" +pos);仅当我单击图库中的图像时才显示正确的位置。但是当我从详细视图中滑动图像时,'pos' 保持不变。

标签: android android-fragments android-viewpager


【解决方案1】:

我认为您不应该依赖 FragmentPagerAdapter 的 getView 来确定当前图像,而是尝试获取 ViewPager 的当前位置并获取该位置的片段并从该片段中检索图像,您可以PlaceholderFragment 中的 downloadImage 属性。 在 fab 的 View.OnClickListener() 上,您应该通过

获取片段
PlaceholderFragment fragment = SectionsPagerAdapter.getItem(mViewPager.getCurrentItem());
fragment.downloadImage

继续你的代码

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

【讨论】:

    【解决方案2】:

    我发现最简单的方法是将图像直接加载到位图中,而不是使用 Picasso 或 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) {
    
                    }
                });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-04
      • 2018-02-11
      • 1970-01-01
      • 2013-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多