android - 如何在特定位置替换 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)
解决方案
你在这里做错了
viewPagerAdapter viewPagerAdapter = new viewPagerAdapter(this, images); viewPagerAdapter.notifyDataSetChanged();
您正在创建一个新的适配器,但不会设置为ViewPager
正确的做法是,如果你EditActivty
要从MainActivity
,而不是save button's onClickListener
你为什么再次打开MainActivity
就这样save button's onClickListener
做EditActivity
编辑
编辑活动.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
并通知适配器,
将此代码添加onActivityResult
到MainActivity
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;
推荐阅读
- python-3.x - Python 值错误:重复的级别名称:“变量”,分配给级别 1,已用于级别 0
- .net-core - 如何通过 MsBuild 将一个 .Net Core 项目的构建输出复制到多个其他目录?
- python - 为什么我的多步 SARIMA 预测会返回如此好的结果?
- sql - SQL/Postgres 如何使用 knex 库连接两个不同的表
- javascript - 尝试将两个值绑定到 React Virtualized Table 中的复选框的单个 isSelected 值,复选框停止工作
- c# - 如何从 Web API 向类库依赖项提供配置
- python - 根据每组平均分排名
- python - Keras ImageDataGenerator 比预测集预测更多
- python - 如果函数位于单独的 .py 文件中,如何将函数传递给 tkinter 类?
- sql - 如果在 case 语句中同时满足两个条件,则显示行两次