如何使用Image Id将图像传递给不同的活动?

时间:2016-02-25 02:30:03

标签: android android-intent android-arrayadapter

我正在努力学习创建一个meme生成器应用程序。首先,当我点击网格视图中的图像时,我的应用程序崩溃时出现问题,因为图像太大了。我被建议使用图像ID将图像传递给第二个活动。我(想,我)相应地更改了代码。现在,当点击图像时,我可以看到下一个活动,输入顶部和底部文本选项但不显示静止图像。我知道问题是我传递图像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;
    }
}

DetailsActivity.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;
    }
}

2 个答案:

答案 0 :(得分:0)

item.getId()是内存中的唯一ID,而不是图像的资源ID,您应该使用资源ID。 简单来说,您可以在setgetData()中将资源ID设置为imageItems ID。

答案 1 :(得分:0)

您的代码存在一些问题。首先,您将从资源中获取图像,但是当您创建新的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;
}

然后,在DetailsActivity中使用onCreate()方法:

@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
    }
}