首页 > 解决方案 > 如何在特定位置替换 ViewPager 中的图像

问题描述

我正在制作一个简单的图像编辑应用程序,用户可以从图库中选择最多 3 张图像,然后所有 3 张图像将显示在 viewPager 中,下一个用户将按下图像上的铅笔图标,然后该特定图像将在 EditActivity 中打开并且用户将添加一些文本并按完成以保存文本,最后 n 用户将按保存按钮将该图像保存在移动存储中,并且该编辑图像的路径将传递回 MainActivity 中的 viewPager 以显示更新的图像,唯一的问题是我面临的是在 viewPager 中显示编辑后的图像。从图库中获取的图像存储在ArrayList<Image> images变量中。我尽力找到解决方案提前谢谢!

库选择多个图像 - > https://github.com/darsh2/MultipleImageSelect

库来编辑图像 - > https://github.com/burhanrashid52/PhotoEditor

在 MainActivity 中的以下方法中,我从画廊接收 3 张图像并存储在 ArrayList 变量中,然后将其传递给 viewPager 适配器,我能够在 viewPager 中成功显示这些图像。

MainActivity.java

 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == Constants.REQUEST_CODE && resultCode == RESULT_OK && data != null) {
            images = data.getParcelableArrayListExtra(Constants.INTENT_EXTRA_IMAGES);

            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0, l = images.size(); i < l; i++) {
                stringBuilder.append(images.get(i).path).append("\n");
            }

            viewPagerAdapter viewPagerAdapter = new viewPagerAdapter(this, images);
            viewPager.setAdapter(viewPagerAdapter);

        }
    }

之后,当我单击 viewPager(MainActivity) 中图像上的编辑图标时,特定图像和图像位置将通过意图传递给 EditActivity,编辑后图像将保存在手机存储中,路径将传回 MainActivity

编辑活动.java

Intent i = new Intent(EditActivity.this,MainActivity.class);
            i.putExtra("ImagePath",filePath);
            i.putExtra("EditPosition",position);
            startActivity(i);

(这里面临问题)再次在 MainActivity 中,我正在从意图中检索数据并尝试替换 ArrayList 中的该图像并将路径传递回 viewPagerAdapter 以显示已编辑的图像,但它不起作用,活动只是重新加载并且没有任何反应。

MainActivity.java - onCreate 方法

  //getting path and position of edited Image back from EditActivity
     String imagePath = getIntent().getStringExtra("ImagePath");
     imagePosition = getIntent().getIntExtra("EditPosition",0);

if (imagePath != null) {

            Image image = new Image(0,"",imagePath,false);

            images.remove(imagePosition);
            images.set(imagePosition,image);
            viewPagerAdapter viewPagerAdapter = new viewPagerAdapter(this, images);
            viewPagerAdapter.notifyDataSetChanged();

            Toast.makeText(this, "image " + image.path,Toast.LENGTH_LONG).show();
        }

MultiImageSelect 库的模型类

image.java
package com.darsh.multipleimageselect.models;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Created by Darshan on 4/18/2015.
 */
public class Image implements Parcelable {
    public long id;
    public String name;
    public String path;
    public boolean isSelected;

    public Image(long id, String name, String path, boolean isSelected) {
        this.id = id;
        this.name = name;
        this.path = path;
        this.isSelected = isSelected;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(id);
        dest.writeString(name);
        dest.writeString(path);
    }

    public static final Parcelable.Creator<Image> CREATOR = new Parcelable.Creator<Image>() {
        @Override
        public Image createFromParcel(Parcel source) {
            return new Image(source);
        }

        @Override
        public Image[] newArray(int size) {
            return new Image[size];
        }
    };

    private Image(Parcel in) {
        id = in.readLong();
        name = in.readString();
        path = in.readString();
    }
}

保存按钮代码

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.edit_save){
            //saving edited image on Mobile storage
            takeSS(editImage);

            //passing edited image path and position to MainActivity back
            Intent i = new Intent();
            i.putExtra("ImagePath",filePath);
            i.putExtra("EditPosition",position);
            setResult(Activity.RESULT_OK,i);
            startActivity(i);
            finish();
        }
        return super.onOptionsItemSelected(item);
    }

MainActivity.java

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

        viewPager = findViewById(R.id.viewPager);
        start = findViewById(R.id.btnStart);
        preview = findViewById(R.id.btnPreview);
        audio = findViewById(R.id.btn_audio);
        showAudio = findViewById(R.id.txt_audio);

        ImageView photoView = findViewById(R.id.imgLauncher);
        testimage = findViewById(R.id.testImage);


        //getting path and position of edited Image back from EditActivity
        //imagePath = getIntent().getStringExtra("ImagePath");
        //imagePosition = getIntent().getIntExtra("EditPosition",0);


        //Library default method to select image from gallery
        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, AlbumSelectActivity.class);
                intent.putExtra(Constants.INTENT_EXTRA_LIMIT, 3);
                startActivityForResult(intent, Constants.REQUEST_CODE);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == Constants.REQUEST_CODE && resultCode == RESULT_OK && data != null) {
            images = data.getParcelableArrayListExtra(Constants.INTENT_EXTRA_IMAGES);
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0, l = images.size(); i < l; i++) {
                stringBuilder.append(images.get(i).path).append("\n");
            }

            //textView.setText(stringBuffer.toString());
            viewPagerAdapter viewPagerAdapter = new viewPagerAdapter(this, images);
            viewPager.setAdapter(viewPagerAdapter);

        } else if (requestCode == com.starmoonsolutions.image2video.Constants.REQUEST_CODE_EDIT_IMAGE && resultCode == RESULT_OK && data != null) {
            Toast.makeText(MainActivity.this, "yessss", Toast.LENGTH_LONG).show();

            String imagePath = data.getStringExtra("ImagePath");
            int editPosition = data.getIntExtra("EditPosition", 0);


            Image image = new Image(0, "", imagePath, false);
            images.remove(editPosition);
            images.add(editPosition, image);
            viewPagerAdapter.notifyDataSetChanged();

        }


    }

viewPagerAdapter 中的编辑按钮代码

//passing ImagePath & position to EditActivity for editing
        editButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String name = imagesArray.get(position).name;
                String path1 = imagesArray.get(position).path;
                Toast.makeText(context,name,Toast.LENGTH_LONG).show();
                Intent i = new Intent(context,EditActivity.class);
                i.putExtra("Path",path1);
                i.putExtra("position",position);
                context.startActivity(i);
            }
        });

当我选择多个图像时

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.abc.image2video, PID: 25326
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=10101, result=-1, data=Intent { (has extras) }} to activity {com.abc.image2video/com.abc.image2video.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.abc.image2video.viewPagerAdapter.notifyDataSetChanged()' on a null object reference
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4284)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4327)
        at android.app.ActivityThread.-wrap22(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1624)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:156)
        at android.app.ActivityThread.main(ActivityThread.java:6517)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.abc.image2video.viewPagerAdapter.notifyDataSetChanged()' on a null object reference
        at com.abc.image2video.MainActivity.onActivityResult(MainActivity.java:238)
        at android.app.Activity.dispatchActivityResult(Activity.java:7193)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4280)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4327) 
        at android.app.ActivityThread.-wrap22(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1624) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:156) 
        at android.app.ActivityThread.main(ActivityThread.java:6517) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)

当我选择单个图像时

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.abc.image2video, PID: 25665
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=10101, result=-1, data=Intent { (has extras) }} to activity {com.abc.image2video/com.abc.image2video.MainActivity}: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4284)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4327)
        at android.app.ActivityThread.-wrap22(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1624)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:156)
        at android.app.ActivityThread.main(ActivityThread.java:6517)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)
     Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
        at java.util.ArrayList.set(ArrayList.java:427)
        at com.abc.image2video.MainActivity.onActivityResult(MainActivity.java:237)
        at android.app.Activity.dispatchActivityResult(Activity.java:7193)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4280)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4327) 
        at android.app.ActivityThread.-wrap22(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1624) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:156) 
        at android.app.ActivityThread.main(ActivityThread.java:6517) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)

标签: androidandroid-viewpager

解决方案


你在这里做错了

viewPagerAdapter viewPagerAdapter = new viewPagerAdapter(this, images); viewPagerAdapter.notifyDataSetChanged();

您正在创建一个新的适配器,但不会设置为ViewPager

正确的做法是,如果你EditActivty要从MainActivity,而不是save button's onClickListener你为什么再次打开MainActivity

就这样save button's onClickListenerEditActivity

编辑

编辑活动.java

Intent i = new Intent(EditActivity.this,MainActivity.class);
i.putExtra("ImagePath",filePath);
i.putExtra("EditPosition",position);
startActivity(i);

从上面的行中删除EditActivity

并粘贴这些行

Intent i = new Intent();
i.putExtra("ImagePath",filePath);
i.putExtra("EditPosition",position);
setResult(Activity.RESULT_OK, i);
finish()

并在 MainActivity 中处理结果,onActivityResult()只需更改列表images并通知适配器,

将此代码添加onActivityResultMainActivity

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == Constants.REQUEST_CODE && resultCode == RESULT_OK && data != null) {
            images = data.getParcelableArrayListExtra(Constants.INTENT_EXTRA_IMAGES);

            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0, l = images.size(); i < l; i++) {
                stringBuilder.append(images.get(i).path).append("\n");
            }

            viewPagerAdapter viewPagerAdapter = new viewPagerAdapter(this, images);
            viewPager.setAdapter(viewPagerAdapter);

        } else if (requestCode == Constants.REQUEST_CODE_EDIT_IMAGE && resultCode == RESULT_OK && data != null) {
            String imagePath = data.getStringExtra("ImagePath","");
            int imagePosition = data.getIntExtra("EditPosition",0);

            Image image = new Image(0,"",imagePath,false);
            images.remove(imagePosition);
            images.set(imagePosition,image);
            viewPagerAdapter.notifyDatSetChnaged();
       }
    }

Constants.java添加这一行

public static int REQUEST_CODE_EDIT_IMAGE = 10101;

推荐阅读