如何使用 Image Id 意图将图像传递给不同的 activity?
How to pass image using Image Id in intent to different activity?
我正在尝试学习创建模因生成器应用程序。首先,当我点击网格视图中的图像时,我的应用程序崩溃了,因为图像太大了。我被建议使用图像 ID 将图像传递给第二个 activity。我(认为,我)相应地更改了代码。现在,当单击图像时,我可以看到下一个 activity 带有输入顶部和底部文本选项,但没有显示静止图像。我知道问题是我传递图像 ID 的方式但不知道是什么。我希望你能给我具体的代码,因为我对编程很陌生。
我知道使用 uri 也是一种选择,但作为初学者我不确定我将如何在这里执行它。如果您认为它更好(在应用程序的速度和内存使用方面/更易于学习和执行),您也会非常友好地帮助我编写代码,将不胜感激。
提前致谢!
这是我的代码:
主要Activity.java
package com.javatechig.gridviewexample;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import java.util.ArrayList;
public class MainActivity extends ActionBarActivity {
private GridView gridView;
private GridViewAdapter gridAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView = (GridView) findViewById(R.id.gridView);
gridAdapter = new GridViewAdapter(this, R.layout.grid_item_layout, getData());
gridView.setAdapter(gridAdapter);
gridView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
ImageItem item = (ImageItem) parent.getItemAtPosition(position);
//Create intent
Intent intent = new Intent(MainActivity.this, DetailsActivity.class);
intent.putExtra("id", item.getId());
//Start details activity
startActivity(intent);
}
});
}
/**
* Prepare some dummy data for gridview
*/
private ArrayList<ImageItem> getData() {
final ArrayList<ImageItem> imageItems = new ArrayList<>();
TypedArray imgs = getResources().obtainTypedArray(R.array.image_ids);
for (int i = 0; i < imgs.length(); i++) {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgs.getResourceId(i, -1));
imageItems.add(new ImageItem(bitmap, R.array.image_ids));
}
return imageItems;
}
}
详情Activity.java
package com.javatechig.gridviewexample;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ImageView;
public class DetailsActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.details_activity);
//imageUri = Uri.parse(extras.getString("imageUri"));
Bitmap bitmap = getIntent().getParcelableExtra("id");
ImageView imageView = (ImageView) findViewById(R.id.image);
imageView.setImageBitmap(bitmap);
}
}
ImageItem.java
package com.javatechig.gridviewexample;
import android.graphics.Bitmap;
public class ImageItem {
private Bitmap image;
private int id;
public ImageItem(Bitmap image, int id) {
super();
this.image = image;
this.id = id;
}
public Bitmap getImage() {
return image;
}
public void setImage(Bitmap image) {
this.image = image;
}
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
}
GridViewAdapter.java
package com.javatechig.gridviewexample;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import java.util.ArrayList;
public class GridViewAdapter extends ArrayAdapter<ImageItem> {
private Context context;
private int layoutResourceId;
private ArrayList<ImageItem> data = new ArrayList<ImageItem>();
public GridViewAdapter(Context context, int layoutResourceId, ArrayList<ImageItem> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new ViewHolder();
holder.image = (ImageView) row.findViewById(R.id.image);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
ImageItem item = data.get(position);
holder.image.setImageBitmap(item.getImage());
return row;
}
static class ViewHolder {
ImageView image;
}
}
item.getId()是内存中的唯一ID,不是图片的资源ID,应该使用资源ID。
简单的方法,您可以在 setgetData() 中将资源 ID 设置为 imageItems ID。
您的代码存在一些问题。首先,您从资源中获取图像,但是当您创建一个新的 ImageItem 并将其添加到 ArrayList 时,您并没有传入单独的资源 ID。这是您的 getData() 方法的相关部分:
TypedArray imgs = getResources().obtainTypedArray(R.array.image_ids);
for (int i = 0; i < imgs.length(); i++) {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgs.getResourceId(i, -1));
//Here you are putting in the generic R.array.image_ids
//Instead you should put in the images specific id: imgs.getResourceId(i, -1));
imageItems.add(new ImageItem(bitmap, R.array.image_ids));
}
接下来,您在活动之间错误地传递和检索数据。这是您的相关代码:
Intent intent = new Intent(MainActivity.this, DetailsActivity.class);
intent.putExtra("id", item.getId()); //You are putting in an int extra
...
//You are attempting to retrieve a Parcelable extra even though you only
//passed in an int
Bitmap bitmap = getIntent().getParcelableExtra("id");
最后,我想明确指出,您没有将这些 ImageItem 存储在任何地方,因此,您将无法使用 ID 检索正确的 ImageItem 以获取图像。
那么,解决办法是什么?
您可能知道位图可能非常大,在活动之间传递它们并不是最好的方法,因为这样做可能会出现很多问题。解决这个问题的一种方法是将它们存储在一个文件中,然后在另一个 Activity 中检索相同的文件。幸运的是,您需要的所有位图都已存储在您的资源中,因此您可以从那里获取它们。
首先,修复您的 getData() 方法:
private ArrayList<ImageItem> getData() {
final ArrayList<ImageItem> imageItems = new ArrayList<>();
TypedArray imgs = getResources().obtainTypedArray(R.array.image_ids);
try{
for (int i = 0; i < imgs.length(); i++) {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgs.getResourceId(i, -1));
imageItems.add(new ImageItem(bitmap, imgs.getResourceId(i, -1)));
}
}finally{
imgs.recycle(); //When done recycle your TypedArray
}
return imageItems;
}
然后,详细信息中的 onCreate() 方法Activity:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.details_activity);
Intent intent = getIntent();
int id = intent.getIntExtra("id", -1);
if(id != -1){
//We have the resource ID so we can retreive the item
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), id);
ImageView imageView = (ImageView) findViewById(R.id.image);
imageView.setImageBitmap(bitmap);
}else{
//We don't have the resource ID so show default View or perform task
}
}
我正在尝试学习创建模因生成器应用程序。首先,当我点击网格视图中的图像时,我的应用程序崩溃了,因为图像太大了。我被建议使用图像 ID 将图像传递给第二个 activity。我(认为,我)相应地更改了代码。现在,当单击图像时,我可以看到下一个 activity 带有输入顶部和底部文本选项,但没有显示静止图像。我知道问题是我传递图像 ID 的方式但不知道是什么。我希望你能给我具体的代码,因为我对编程很陌生。
我知道使用 uri 也是一种选择,但作为初学者我不确定我将如何在这里执行它。如果您认为它更好(在应用程序的速度和内存使用方面/更易于学习和执行),您也会非常友好地帮助我编写代码,将不胜感激。
提前致谢!
这是我的代码:
主要Activity.java
package com.javatechig.gridviewexample;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import java.util.ArrayList;
public class MainActivity extends ActionBarActivity {
private GridView gridView;
private GridViewAdapter gridAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView = (GridView) findViewById(R.id.gridView);
gridAdapter = new GridViewAdapter(this, R.layout.grid_item_layout, getData());
gridView.setAdapter(gridAdapter);
gridView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
ImageItem item = (ImageItem) parent.getItemAtPosition(position);
//Create intent
Intent intent = new Intent(MainActivity.this, DetailsActivity.class);
intent.putExtra("id", item.getId());
//Start details activity
startActivity(intent);
}
});
}
/**
* Prepare some dummy data for gridview
*/
private ArrayList<ImageItem> getData() {
final ArrayList<ImageItem> imageItems = new ArrayList<>();
TypedArray imgs = getResources().obtainTypedArray(R.array.image_ids);
for (int i = 0; i < imgs.length(); i++) {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgs.getResourceId(i, -1));
imageItems.add(new ImageItem(bitmap, R.array.image_ids));
}
return imageItems;
}
}
详情Activity.java
package com.javatechig.gridviewexample;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ImageView;
public class DetailsActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.details_activity);
//imageUri = Uri.parse(extras.getString("imageUri"));
Bitmap bitmap = getIntent().getParcelableExtra("id");
ImageView imageView = (ImageView) findViewById(R.id.image);
imageView.setImageBitmap(bitmap);
}
}
ImageItem.java
package com.javatechig.gridviewexample;
import android.graphics.Bitmap;
public class ImageItem {
private Bitmap image;
private int id;
public ImageItem(Bitmap image, int id) {
super();
this.image = image;
this.id = id;
}
public Bitmap getImage() {
return image;
}
public void setImage(Bitmap image) {
this.image = image;
}
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
}
GridViewAdapter.java
package com.javatechig.gridviewexample;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import java.util.ArrayList;
public class GridViewAdapter extends ArrayAdapter<ImageItem> {
private Context context;
private int layoutResourceId;
private ArrayList<ImageItem> data = new ArrayList<ImageItem>();
public GridViewAdapter(Context context, int layoutResourceId, ArrayList<ImageItem> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new ViewHolder();
holder.image = (ImageView) row.findViewById(R.id.image);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
ImageItem item = data.get(position);
holder.image.setImageBitmap(item.getImage());
return row;
}
static class ViewHolder {
ImageView image;
}
}
item.getId()是内存中的唯一ID,不是图片的资源ID,应该使用资源ID。 简单的方法,您可以在 setgetData() 中将资源 ID 设置为 imageItems ID。
您的代码存在一些问题。首先,您从资源中获取图像,但是当您创建一个新的 ImageItem 并将其添加到 ArrayList 时,您并没有传入单独的资源 ID。这是您的 getData() 方法的相关部分:
TypedArray imgs = getResources().obtainTypedArray(R.array.image_ids);
for (int i = 0; i < imgs.length(); i++) {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgs.getResourceId(i, -1));
//Here you are putting in the generic R.array.image_ids
//Instead you should put in the images specific id: imgs.getResourceId(i, -1));
imageItems.add(new ImageItem(bitmap, R.array.image_ids));
}
接下来,您在活动之间错误地传递和检索数据。这是您的相关代码:
Intent intent = new Intent(MainActivity.this, DetailsActivity.class);
intent.putExtra("id", item.getId()); //You are putting in an int extra
...
//You are attempting to retrieve a Parcelable extra even though you only
//passed in an int
Bitmap bitmap = getIntent().getParcelableExtra("id");
最后,我想明确指出,您没有将这些 ImageItem 存储在任何地方,因此,您将无法使用 ID 检索正确的 ImageItem 以获取图像。
那么,解决办法是什么?
您可能知道位图可能非常大,在活动之间传递它们并不是最好的方法,因为这样做可能会出现很多问题。解决这个问题的一种方法是将它们存储在一个文件中,然后在另一个 Activity 中检索相同的文件。幸运的是,您需要的所有位图都已存储在您的资源中,因此您可以从那里获取它们。
首先,修复您的 getData() 方法:
private ArrayList<ImageItem> getData() {
final ArrayList<ImageItem> imageItems = new ArrayList<>();
TypedArray imgs = getResources().obtainTypedArray(R.array.image_ids);
try{
for (int i = 0; i < imgs.length(); i++) {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgs.getResourceId(i, -1));
imageItems.add(new ImageItem(bitmap, imgs.getResourceId(i, -1)));
}
}finally{
imgs.recycle(); //When done recycle your TypedArray
}
return imageItems;
}
然后,详细信息中的 onCreate() 方法Activity:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.details_activity);
Intent intent = getIntent();
int id = intent.getIntExtra("id", -1);
if(id != -1){
//We have the resource ID so we can retreive the item
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), id);
ImageView imageView = (ImageView) findViewById(R.id.image);
imageView.setImageBitmap(bitmap);
}else{
//We don't have the resource ID so show default View or perform task
}
}