I am trying to learn to create a meme generator app. First I had a problem with my app crashing when I clicked on the images in the grid view as the images were too big. I was advised to use image id to pass the image to the second activity. I (thought, I) changed the code accordingly. Now when clicked on the image, I can see the next activity with enter top and bottom text options but still image does not appear. I know the problem is the way I am passing image id but don't know what. I hope you can give me specific code as I am very new to programming.
I know using uri also is an option but being a beginner I am not sure how I would execute that here. If you think it is a better (in terms of speed of the app and memory usage / easier to learn and execute), you would be kind enough to help me out with the code too, would be appreciated.
Thank You in advance!
Here is my code:
Main 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;
}
}
There are a few issues with your code. To start, you are obtaining your images from the resources but when you create a new ImageItem and add it to the ArrayList you are not passing in the individual resource ID. Here is the relevant part of your getData() method:
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));
}
Next, you are incorrectly passing and retrieving data between Activities. Here's your relevant code:
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");
And finally, I want to make it clear that you are not storing these ImageItems anywhere, so, you wouldn't be able to retrieve the correct ImageItem with the ID to get the image.
So, what's the solution?
As you may know Bitmaps can be quite large and passing them between Activities isn't the best approach as there can be many issues in doing so. One way of getting around this is storing them in a File and retrieving that same File in the other Activity. Fortunately, all of the Bitmaps you need are already stored in your resources, so, you can just get them from there.
First, fix your getData() method:
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;
}
Then, your onCreate() method in DetailsActivity:
#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
}
}
item.getId() is the unique ID in memory , not the image's resource ID, you should use resource ID.
the simple way , you can set resource ID as imageItems ID in setgetData().
Related
I want to create a dynamic ImageView which downloads image from online server and loads in app. I am using code from this tutorial
The problem is that code is working on static ImageView I created in layout file but not when I use it for dynamic ImageView. It loads loader image but does not replace with original image from URL after downloading to phone memory. It generates below error -
D/skia: --- decoder->decode returned false
Here is my ImageAdapter.java code -
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import com.pixelandpublish.shreeshasirestaurant.R;
import com.pixelandpublish.shreeshasirestaurant.activity.ProductsActivity;
import com.pixelandpublish.shreeshasirestaurant.model.Categories;
import java.util.List;
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private DatabaseHandler db;
// Constructor
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
db = new DatabaseHandler(mContext);
List<Categories> categories = db.getAllCategories();
return categories.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(final int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(340, 340));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
imageView.setId(position);
}
else
{
imageView = (ImageView) convertView;
}
//imageView.setImageResource(mThumbIds[position]);
db = new DatabaseHandler(mContext);
List<Categories> categories = db.getAllCategories();
final String[] log = new String[categories.size()];
final Integer[] id = new Integer[categories.size()];
int i = 0;
for (Categories cn : categories) {
log[i] = cn.getName();
id[i] = cn.getID();
i++;
}
// Loader image - will be shown before loading image
int loader = R.drawable.ic;
// Imageview to show
//ImageView image = (ImageView) findViewById(R.id.image);
// Image url
String image_url = "http://api.androidhive.info/images/sample.jpg";
// ImageLoader class instance
ImageLoader imgLoader = new ImageLoader(mContext);
// whenever you want to load an image from url
// call DisplayImage function
// url - image url to load
// loader - loader image, will be displayed before getting image
// image - ImageView
imgLoader.DisplayImage(image_url, loader, imageView);
//imageView.setImageResource(mThumbIds[position]);
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(mContext, ProductsActivity.class);
//Create the bundle
Bundle bundle = new Bundle();
//Add your data to bundle
bundle.putString("categoryId", String.valueOf(id[position]));
//Add the bundle to the intent
i.putExtras(bundle);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.getApplicationContext().startActivity(i);
}
});
return imageView;
}
}
Thanx in advance. :)
you can simply use picasso library for downloading images from internet...
http://code.tutsplus.com/tutorials/android-sdk-working-with-picasso--cms-22149
You can use the Univeral Image Loader for it...Refer this link
Universal Image Loader
ImageLoader imageLoader = ImageLoader.getInstance();
ImageLoader.getInstance().init(ImageLoaderConfiguration.createDefault(activity));
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.YOUR_DRWABLE)
.showImageForEmptyUri(R.drawable.YOUR_DRWABLE)
.showImageOnFail(R.drawable.YOUR_DRWABLE)
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
imageLoader.DisplayImage("YOUR URL", R.drawable.YOUR_DRWABLE, IMAGEVIEW_HERE);
I have tried all the suggestions I could find on S.O., and I was able to use this exact code successfully on a ListView of mine, but for some reason I can't set a long click listener on my GridView. I log inside the method setupGridViewListener(); and it does not even run, yet I have my method inside onCreateView(). Don't know why it won't work. The alert dialog should pop up once long-clicked, but it doesn't. Method is at bottom of my class.
UPDATE:
I did not mention that my onClickListener does work fine. So I can at least do a single click, and this displays my activity. But, that code is in my adapter, so maybe they should be together in the same class? I am including my adapter and my 2 xmls below.
UPDATE 2
I discovered several things that were worth mentioning, even after I got my code working again. First of all, putting my click listeners into my adapter was a mistake. It slowed things down HUGELY... so much so, I was frantic about finding a way to get things on another thread. But in the end, I did not need to. I realized that I could actually get both of my click listeners into my PhotoTab.java class. This immediately made it faster (back to normal). But another curious thing, the IDE would not let me use OnClickListener, but insisted I go back to OnItemClickListener. So once I changed those back, everything worked again. So the listeners ended up being on my GridView variables, e.g. gridView.setOnItemClickListener(new OnItemClickListener() {} not my ImageView item variables. Perhaps this is what made things faster? There is one GridView, but 24 ImageViews (GridView cells). But that is just a guess. I have updated my code to the current, working code. Except I'm still working on the long click code, so that's not right yet. The dialog alert works though, and each item in the GridView is clickable.
PhotoTab.java
package org.azurespot.cutecollection.phototab;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import org.azurespot.R;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.ArrayList;
/**
* Created by mizu on 2/8/15.
*/
public class PhotoTab extends Fragment {
private GridView gridView;
File[] files;
ArrayList<PhotoGridItem> photoList = new ArrayList<>();
ArrayAdapter<PhotoGridItem> adapter;
Bitmap bitmap;
byte[] byteArray = null;
private String[] allSDCardFiles = null;
PhotoGridItem photoGridItem;
public PhotoTab() {
super();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.photo_tab, container, false);
// with fragments, make sure you include the rootView when finding id
gridView = (GridView) v.findViewById(R.id.photo_grid);
// this null check won't instantiate again if it was already
// if(adapter == null)
adapter = new GridViewPhotoAdapter(getActivity(), R.layout.photo_grid_item);
// Set the Adapter to GridView
gridView.setAdapter(adapter);
// load contents of SD card
loadSDCard();
// add the default icons remaining, to GridView, if less than 24 files on SD card
for (int i = 0; i < (24 - allSDCardFiles.length); i++) {
adapter.add(new PhotoGridItem(BitmapFactory.decodeResource(getResources(),
R.drawable.ic_photo_placeholder)));
adapter.notifyDataSetChanged();
i++;
}
//Convert the bitmap to byte array, so can pass through intent
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
final byte[] byteArray = stream.toByteArray();
this.byteArray = byteArray;
setupGridViewListener();
return v;
}
public void loadSDCard() {
try {
// gets directory CutePhotos from sd card
File cutePhotosDir = new File(Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PICTURES), "Cute Photos");
// lists all files in CutePhotos, loads in Files[] array
files = cutePhotosDir.listFiles();
for (File singleFile : files) {
String filePath = singleFile.getAbsolutePath();
// this method makes size small for the view (to save memory)
bitmap = decodeImageBitmap(filePath, 270, 270);
photoGridItem = new PhotoGridItem(bitmap);
// Check if this is a new bitmap file
adapter.add(photoGridItem);
adapter.notifyDataSetChanged();
}
} catch (Exception e) {
e.printStackTrace();
}
// get number of files in Cute Photos directory
allSDCardFiles = new String[files.length];
}
private void setupGridViewListener(){
gridView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter,
View item, int pos, long id) {
Intent i = new Intent(getActivity(), PhotoViewerActivity.class);
i.putExtra("photo", byteArray);
startActivity(i);
}
});
// to delete a photo item
gridView.setOnItemLongClickListener(new OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> aView, View item,
final int pos, long id) {
new AlertDialog.Builder(getActivity())
.setTitle("Delete")
.setMessage("Delete this cute photo?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// delete from ArrayList first
// PhotoTab.photoList.remove(position);
// get file name then delete it from SD card
File cutePhotosDir = new File(Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PICTURES), "CutePhotos/" + photoGridItem);
cutePhotosDir.delete();
// after each item delete, must refresh load so can delete again
// photoTab.loadSDCard();
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
dialog.cancel();
}
})
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
return true;
}
});
}
// next 2 methods scale the bitmap image to a better size (so not huge)
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;
}
public static Bitmap decodeImageBitmap(String path, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
Bitmap bm = BitmapFactory.decodeFile(path, options);
return bm;
}
}
GridViewPhotoAdapter
package org.azurespot.cutecollection.phototab;
/**
* Created by mizu on 2/5/15.
*/
// package org.azurespot.cutecollection;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import org.azurespot.R;
/**
* Created by mizu on 2/5/15.
*/
public class GridViewPhotoAdapter extends ArrayAdapter<PhotoGridItem> {
public Context context;
private int resourceId;
ViewHolder holder = null;
int position;
public GridViewPhotoAdapter(Context context, int layoutResourceId) {
super(context, layoutResourceId);
this.context = context;
this.resourceId = layoutResourceId;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
this.position = position;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(resourceId, parent, false);
holder = new ViewHolder();
holder.imageView = (ImageView) row.findViewById(R.id.photo_grid_view);
// stores holder with view
row.setTag(holder);
} else {
holder = (ViewHolder)row.getTag();
}
// gets position of whichever photo you click on in the GridView
final PhotoGridItem photoGridItem = getItem(position);
if (photoGridItem != null) {
Bitmap bm = photoGridItem.getImage();
holder.imageView.setImageBitmap(bm);
// positioning the image in the GridView slot
holder.imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
holder.imageView.setLayoutParams(new LinearLayout.LayoutParams(270, 270));
}
return row;
}
public class ViewHolder{
ImageView imageView;
}
}
photo_tab.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root_view"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#2198bb">
<GridView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/photo_grid"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:verticalSpacing="5dp"
android:horizontalSpacing="2dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="25dp"
android:columnWidth="100dp"
android:gravity="center"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:scrollbarStyle="outsideOverlay"
android:verticalScrollbarPosition="right" />
</RelativeLayout>
photo_grid_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/photo_grid_view"
android:focusable="false"
android:focusableInTouchMode="false"/>
</LinearLayout>
package com.example.slideanim;
import java.util.ArrayList;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.Toast;
public class MyGridAdapter extends BaseAdapter {
private ArrayList<String> list = new ArrayList<String>();
private Activity activity;
private LayoutInflater layoutInflater;
public MyGridAdapter(Activity activity, ArrayList<String> list) {
// TODO Auto-generated constructor stub
this.activity = activity;
this.list = list;
layoutInflater = activity.getLayoutInflater();
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return list.get(arg0);
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int pos, View convertView, ViewGroup arg2) {
// TODO Auto-generated method stub
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = layoutInflater.inflate(R.layout.row, null);
holder.imageView = (ImageView) convertView
.findViewById(R.id.photo_grid_view);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.imageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
}
});
holder.imageView.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(activity, "got", Toast.LENGTH_SHORT).show();
return true;
}
});
return convertView;
}
private static class ViewHolder {
public ImageView imageView;
}
}
It would be better to either use click and long click for the imageview, or both on the gridview item.
If you want on imageview, do not setup the GridViewListener and try this in your adapter:
holder.imageView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
//your code
return true;
}
});
holder.imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(context, PhotoViewerActivity.class);
i.putExtra("photo", byteArray);
context.startActivity(i);
}
});
-First of all check if any Views In your gridview are Focusable or Clickable or not make them False and then check your log again
-Let me inform if further issue exist
-THanks
Hi I'm trying to create a GridView using images from an online depository using Picasso.
I also want the user to be able to click on the image and it load up full screen to view.
So far I have managed to get it working almost perfectly. The only problem is the image that shows when they click on the grid is not the one that they clicked on, in fact it randomly chooses an image each time.
I was hoping somebody could take a look at my code and tell me where I am going wrong.
Thanks.
So this is my MainActivity class:
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView gv = (GridView) findViewById(R.id.grid_view);
gv.setAdapter(new GridViewAdapter(this));
gv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
// Sending image id to FullScreenActivity
Intent i = new Intent(getApplicationContext(), FullImageActivity.class);
// passing array index
i.putExtra("id", position);
startActivity(i);
}
});
}
}
This is my GridView class:
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static android.widget.ImageView.ScaleType.CENTER_CROP;
final class GridViewAdapter extends BaseAdapter {
final Context context;
final List<String> urls = new ArrayList<String>();
public GridViewAdapter(Context context) {
this.context = context;
// Ensure we get a different ordering of images on each run.
Collections.addAll(urls, Info.URLS);
Collections.shuffle(urls);
// Triple up the list.
ArrayList<String> copy = new ArrayList<String>(urls);
urls.addAll(copy);
urls.addAll(copy);
}
#Override public View getView(int position, View convertView, ViewGroup parent) {
SquaredImageView view = (SquaredImageView) convertView;
if (view == null) {
view = new SquaredImageView(context);
view.setScaleType(CENTER_CROP);
}
// Get the image URL for the current position.
String url = getItem(position);
// Trigger the download of the URL asynchronously into the image view.
Picasso.with(context) //
.load(url) //
.placeholder(R.drawable.placeholder) //
.error(R.drawable.error) //
.fit() //
.into(view);
return view;
}
#Override public int getCount() {
return urls.size();
}
#Override public String getItem(int position) {
return urls.get(position);
}
#Override public long getItemId(int position) {
return position;
}
}
And finally my FullScreen Class:
import com.squareup.picasso.Picasso;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ImageView;
public class FullImageActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.full_image);
// get intent data
Intent i = getIntent();
// Selected image id
int position = i.getExtras().getInt("id");
GridViewAdapter ia = new GridViewAdapter(this);
ImageView iv = (ImageView) findViewById(R.id.full_image_view);
Picasso.with(this) //
.load(ia.getItem(position)) //
.placeholder(R.drawable.placeholder) //
.error(R.drawable.error) //
.fit()
.centerCrop()//
.into(iv);
}
}
I believe this is your culprit:
Collections.addAll(urls, Info.URLS);
Collections.shuffle(urls); // this reshuffles on every new instance
GridViewAdapter ia = new GridViewAdapter(this); // your full screen activity is creating a new instance.
Since I cannot comment yet, the answer is No. When you say startActivity, it will create a new instance of the FullScreenActivity, and then in that FullScreenActivity you are also instantiating a new Adapter which in turn does the shuffle work.
Please put in a breakpoint if you are in doubt.
You reinitialized the adapter for whatever reason here GridViewAdapter ia = new GridViewAdapter(this); That's when the shuffling occurs, in the constructor.
You should not have an adapter in your 2nd Activity. Adapters are for lists. You should simply pass that Activity the image URL.
GridView gv = (GridView) findViewById(R.id.grid_view);
GridViewAdapter adapter = new GridViewAdapter(this);
gv.setAdapter(adapter);
gv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
// Sending image url to FullScreenActivity
Intent i = new Intent(getApplicationContext(), FullImageActivity.class);
i.putExtra("url", adapter.getItem(position));
startActivity(i);
}
});
and
public class FullImageActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.full_image);
// get intent data
Intent i = getIntent();
string url = i.getExtras().getString("url");
ImageView iv = (ImageView) findViewById(R.id.full_image_view);
Picasso.with(this) //
.load(url) //
.placeholder(R.drawable.placeholder) //
.error(R.drawable.error) //
.fit()
.centerCrop()//
.into(iv);
}
}
You are creating an adapter twice - once in MainActivity, second time in FullImageActivity. Each time it is created shuffled, that's the reason. Nice copy-paste from Picasso sample btw ;)
I have this code on my app which have 3 tab with 3 different Activity. One is this but i cant resolve this problem:
package com.example.myapplication;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import com.example.myapplication.universalimageloader.AbsListViewBaseActivity;
import com.example.myapplication.universalimageloader.Constants;
import com.example.myapplication.universalimageloader.ImagePagerActivity;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
public class Foto extends AbsListViewBaseActivity {
String[] imageUrls;
DisplayImageOptions options;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ac_image_grid);
Bundle bundle = getIntent().getExtras();
imageUrls = bundle.getStringArray(Constants.Extra.IMAGES);
options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.ic_stub)
.showImageForEmptyUri(R.drawable.ic_empty)
.showImageOnFail(R.drawable.ic_error)
.cacheInMemory()
.cacheOnDisc()
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
listView = (GridView) findViewById(R.id.gridview);
((GridView) listView).setAdapter(new ImageAdapter());
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
startImagePagerActivity(position);
}
});
}
private void startImagePagerActivity(int position) {
Intent intent = new Intent(this, ImagePagerActivity.class);
intent.putExtra(Constants.Extra.IMAGES, imageUrls);
intent.putExtra(Constants.Extra.IMAGE_POSITION, position);
startActivity(intent);
}
public class ImageAdapter extends BaseAdapter {
#Override
public int getCount() {
return imageUrls.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ImageView imageView;
if (convertView == null) {
imageView = (ImageView) getLayoutInflater().inflate(R.layout.item_grid_image, parent, false);
} else {
imageView = (ImageView) convertView;
}
imageLoader.displayImage(imageUrls[position], imageView, options);
return imageView;
}
}
runc correctly but when i click on this tab i have a NullPointerException on
imageUrls = bundle.getStringArray(Constants.Extra.IMAGES);
can anyone help me?
Intent Foto= new Intent().setClass(this, Foto.class);
TabSpec Foto= tabHost.newTabSpec("Foto")
.setIndicator("Foto")
.setContent(Foto);
but i think the problem is this but i dont know where:
public final class Constants {
public static final String[] IMAGES = new String[] {
// Heavy images
"https://lh6.googleusercontent.com/-jZgveEqb6pg/T3R4kXScycI/AAAAAAAAAE0/xQ7CvpfXDzc/s1024/sample_image_01.jpg",
"https://lh4.googleusercontent.com/-K2FMuOozxU0/T3R4lRAiBTI/AAAAAAAAAE8/a3Eh9JvnnzI/s1024/sample_image_02.jpg",
"https://lh5.googleusercontent.com/-SCS5C646rxM/T3R4l7QB6xI/AAAAAAAAAFE/xLcuVv3CUyA/s1024/sample_image_03.jpg",
"https://lh6.googleusercontent.com/-f0NJR6-_Thg/T3R4mNex2wI/AAAAAAAAAFI/45oug4VE8MI/s1024/sample_image_04.jpg",
"https://lh3.googleusercontent.com/-n-xcJmiI0pg/T3R4mkSchHI/AAAAAAAAAFU/EoiNNb7kk3A/s1024/sample_image_05.jpg",
"https://lh3.googleusercontent.com/-X43vAudm7f4/T3R4nGSChJI/AAAAAAAAAFk/3bna6D-2EE8/s1024/sample_image_06.jpg",
"https://lh5.googleusercontent.com/-MpZneqIyjXU/T3R4nuGO1aI/AAAAAAAAAFg/r09OPjLx1ZY/s1024/sample_image_07.jpg",
"https://lh6.googleusercontent.com/-ql3YNfdClJo/T3XvW9apmFI/AAAAAAAAAL4/_6HFDzbahc4/s1024/sample_image_08.jpg",
"https://lh5.googleusercontent.com/-Pxa7eqF4cyc/T3R4oasvPEI/AAAAAAAAAF0/-uYDH92h8LA/s1024/sample_image_09.jpg",
"https://lh4.googleusercontent.com/-Li-rjhFEuaI/T3R4o-VUl4I/AAAAAAAAAF8/5E5XdMnP1oE/s1024/sample_image_10.jpg",
"https://lh5.googleusercontent.com/-_HU4fImgFhA/T3R4pPVIwWI/AAAAAAAAAGA/0RfK_Vkgth4/s1024/sample_image_11.jpg",
"https://lh6.googleusercontent.com/-0gnNrVjwa0Y/T3R4peGYJwI/AAAAAAAAAGU/uX_9wvRPM9I/s1024/sample_image_12.jpg",
"https://lh3.googleusercontent.com/-HBxuzALS_Zs/T3R4qERykaI/AAAAAAAAAGQ/_qQ16FaZ1q0/s1024/sample_image_13.jpg",
"https://lh4.googleusercontent.com/-cKojDrARNjQ/T3R4qfWSGPI/AAAAAAAAAGY/MR5dnbNaPyY/s1024/sample_image_14.jpg",
"https://lh3.googleusercontent.com/-WujkdYfcyZ8/T3R4qrIMGUI/AAAAAAAAAGk/277LIdgvnjg/s1024/sample_image_15.jpg",
"https://lh6.googleusercontent.com/-FMHR7Vy3PgI/T3R4rOXlEKI/AAAAAAAAAGs/VeXrDNDBkaw/s1024/sample_image_16.jpg",
"https://lh4.googleusercontent.com/-mrR0AJyNTH0/T3R4rZs6CuI/AAAAAAAAAG0/UE1wQqCOqLA/s1024/sample_image_17.jpg",
"https://lh6.googleusercontent.com/-z77w0eh3cow/T3R4rnLn05I/AAAAAAAAAG4/BaerfWoNucU/s1024/sample_image_18.jpg",
"https://lh5.googleusercontent.com/-aWVwh1OU5Bk/T3R4sAWw0yI/AAAAAAAAAHE/4_KAvJttFwA/s1024/sample_image_19.jpg",
"https://lh6.googleusercontent.com/-q-js52DMnWQ/T3R4tZhY2sI/AAAAAAAAAHM/A8kjp2Ivdqg/s1024/sample_image_20.jpg",
"https://lh5.googleusercontent.com/-_jIzvvzXKn4/T3R4t7xpdVI/AAAAAAAAAHU/7QC6eZ10jgs/s1024/sample_image_21.jpg",
"https://lh3.googleusercontent.com/-lnGi4IMLpwU/T3R4uCMa7vI/AAAAAAAAAHc/1zgzzz6qTpk/s1024/sample_image_22.jpg",
"https://lh5.googleusercontent.com/-fFCzKjFPsPc/T3R4u0SZPFI/AAAAAAAAAHk/sbgjzrktOK0/s1024/sample_image_23.jpg",
"https://lh4.googleusercontent.com/-8TqoW5gBE_Y/T3R4vBS3NPI/AAAAAAAAAHs/EZYvpNsaNXk/s1024/sample_image_24.jpg",
"https://lh6.googleusercontent.com/-gc4eQ3ySdzs/T3R4vafoA7I/AAAAAAAAAH4/yKii5P6tqDE/s1024/sample_image_25.jpg",
"https://lh5.googleusercontent.com/--NYOPCylU7Q/T3R4vjAiWkI/AAAAAAAAAH8/IPNx5q3ptRA/s1024/sample_image_26.jpg",
"https://lh6.googleusercontent.com/-9IJM8so4vCI/T3R4vwJO2yI/AAAAAAAAAIE/ljlr-cwuqZM/s1024/sample_image_27.jpg",
"https://lh4.googleusercontent.com/-KW6QwOHfhBs/T3R4w0RsQiI/AAAAAAAAAIM/uEFLVgHPFCk/s1024/sample_image_28.jpg",
"https://lh4.googleusercontent.com/-z2557Ec1ctY/T3R4x3QA2hI/AAAAAAAAAIk/9-GzPL1lTWE/s1024/sample_image_29.jpg",
"https://lh5.googleusercontent.com/-LaKXAn4Kr1c/T3R4yc5b4lI/AAAAAAAAAIY/fMgcOVQfmD0/s1024/sample_image_30.jpg",
"https://lh4.googleusercontent.com/-F9LRToJoQdo/T3R4yrLtyQI/AAAAAAAAAIg/ri9uUCWuRmo/s1024/sample_image_31.jpg",
"https://lh4.googleusercontent.com/-6X-xBwP-QpI/T3R4zGVboII/AAAAAAAAAIs/zYH4PjjngY0/s1024/sample_image_32.jpg",
"https://lh5.googleusercontent.com/-VdLRjbW4LAs/T3R4zXu3gUI/AAAAAAAAAIw/9aFp9t7mCPg/s1024/sample_image_33.jpg",
"https://lh6.googleusercontent.com/-gL6R17_fDJU/T3R4zpIXGjI/AAAAAAAAAI8/Q2Vjx-L9X20/s1024/sample_image_34.jpg",
"https://lh3.googleusercontent.com/-1fGH4YJXEzo/T3R40Y1B7KI/AAAAAAAAAJE/MnTsa77g-nk/s1024/sample_image_35.jpg",
"https://lh4.googleusercontent.com/-Ql0jHSrea-A/T3R403mUfFI/AAAAAAAAAJM/qzI4SkcH9tY/s1024/sample_image_36.jpg",
"https://lh5.googleusercontent.com/-BL5FIBR_tzI/T3R41DA0AKI/AAAAAAAAAJk/GZfeeb-SLM0/s1024/sample_image_37.jpg",
"https://lh4.googleusercontent.com/-wF2Vc9YDutw/T3R41fR2BCI/AAAAAAAAAJc/JdU1sHdMRAk/s1024/sample_image_38.jpg",
"https://lh6.googleusercontent.com/-ZWHiPehwjTI/T3R41zuaKCI/AAAAAAAAAJg/hR3QJ1v3REg/s1024/sample_image_39.jpg",
// Light images
"http://tabletpcssource.com/wp-content/uploads/2011/05/android-logo.png",
"http://simpozia.com/pages/images/stories/windows-icon.png",
"https://si0.twimg.com/profile_images/1135218951/gmail_profile_icon3_normal.png",
"http://www.krify.net/wp-content/uploads/2011/09/Macromedia_Flash_dock_icon.png",
"http://radiotray.sourceforge.net/radio.png",
"http://www.bandwidthblog.com/wp-content/uploads/2011/11/twitter-logo.png",
"http://weloveicons.s3.amazonaws.com/icons/100907_itunes1.png",
"http://weloveicons.s3.amazonaws.com/icons/100929_applications.png",
"http://www.idyllicmusic.com/index_files/get_apple-iphone.png",
"http://www.frenchrevolutionfood.com/wp-content/uploads/2009/04/Twitter-Bird.png",
"http://3.bp.blogspot.com/-ka5MiRGJ_S4/TdD9OoF6bmI/AAAAAAAAE8k/7ydKtptUtSg/s1600/Google_Sky%2BMaps_Android.png",
"http://www.desiredsoft.com/images/icon_webhosting.png",
"http://goodereader.com/apps/wp-content/uploads/downloads/thumbnails/2012/01/hi-256-0-99dda8c730196ab93c67f0659d5b8489abdeb977.png",
"http://1.bp.blogspot.com/-mlaJ4p_3rBU/TdD9OWxN8II/AAAAAAAAE8U/xyynWwr3_4Q/s1600/antivitus_free.png",
"http://cdn3.iconfinder.com/data/icons/transformers/computer.png",
"http://cdn.geekwire.com/wp-content/uploads/2011/04/firefox.png?7794fe",
"https://ssl.gstatic.com/android/market/com.rovio.angrybirdsseasons/hi-256-9-347dae230614238a639d21508ae492302340b2ba",
"http://androidblaze.com/wp-content/uploads/2011/12/tablet-pc-256x256.jpg",
"http://www.theblaze.com/wp-content/uploads/2011/08/Apple.png",
"http://1.bp.blogspot.com/-y-HQwQ4Kuu0/TdD9_iKIY7I/AAAAAAAAE88/3G4xiclDZD0/s1600/Twitter_Android.png",
"http://3.bp.blogspot.com/-nAf4IMJGpc8/TdD9OGNUHHI/AAAAAAAAE8E/VM9yU_lIgZ4/s1600/Adobe%2BReader_Android.png",
"http://cdn.geekwire.com/wp-content/uploads/2011/05/oovoo-android.png?7794fe",
"http://icons.iconarchive.com/icons/kocco/ndroid/128/android-market-2-icon.png",
"http://thecustomizewindows.com/wp-content/uploads/2011/11/Nicest-Android-Live-Wallpapers.png",
"http://c.wrzuta.pl/wm16596/a32f1a47002ab3a949afeb4f",
"http://macprovid.vo.llnwd.net/o43/hub/media/1090/6882/01_headline_Muse.jpg",
// Special cases
"file:///sdcard/Universal Image Loader ##&=+-_.,!()~'%20.png", // Image from SD card with encoded symbols
"assets://Living Things ##&=+-_.,!()~'%20.jpg", // Image from assets
"drawable://" + R.drawable.ic_launcher, // Image from drawables
"https://www.eff.org/sites/default/files/chrome150_0.jpg", // Image from HTTPS
"http://bit.ly/soBiXr", // Redirect link
"http://img001.us.expono.com/100001/100001-1bc30-2d736f_m.jpg", // EXIF
"", // Empty link
"http://wrong.site.com/corruptedLink", // Wrong link
};
private Constants() {
}
public static class Config {
public static final boolean DEVELOPER_MODE = false;
}
public static class Extra {
public static final String IMAGES = "com.example.myapplication.universalimageloader.IMAGES";
public static final String IMAGE_POSITION = "com.example.myapplication.universalimageloader.IMAGE_POSITION";
}
}
Why do you pass the array of images (IMAGES) as an extra? You can access it from everywhere because it is a ...
public static final
....variable.
Just change this....
imageUrls = bundle.getStringArray(Constants.Extra.IMAGES);
For this....
imageUrls = Constants.IMAGES;
...or dont even use imageUrls and access the images all the time through Constants.IMAGES.
You dont need a bundle and put Extras.
Anyway in case you want to pass extras...
Intent i = new Intent(context, YourActivity.class);
i.putExtra("key",/*value you wanna pass*/);
startActivity(i);
And when you get the values, try always to check if the bundle is null...
Bundle bundle = getIntent().getExtras();
if(bundle!=null){
//Get the values in the bundle
}
Stack Trace
Picture of stack trace here
Values aren't being passed to the other intent. Every time I try to start the activity with the intent in it, it crashes.
//This activity will retrieve and display the different rewards that are available.
public class RewardsActivity extends Activity {
#Override
public void onCreate(Bundle SavedInstanceState)
{
super.onCreate(SavedInstanceState);
setContentView(R.layout.rewards);
//stores retrieves and stores the current gridview
GridView gridView = (GridView)findViewById(R.id.grid_view);
//Instance of ImageAdapter class that will load the images into the gridview
gridView.setAdapter(new ImageAdapter(this));
//This function is used to set a listener on each item in the grid so that when its clicked it will go to the other view.
gridView.setOnItemClickListener(new OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View v,int position, long id)
{
Intent i = new Intent(getApplicationContext(),RewardsViewActivity.class);
i.putExtra("id", position);
startActivity(i);
}
});
}
This new intent is being passed to, when it's passed here it is stored in a variable then used in a ImageView to load an image.
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ImageView;
public class RewardsViewActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.full_view);
// get intent data
Intent i = getIntent();
// Selected image id
int position = i.getExtras().getInt("id");
ImageAdapter imageAdapter = new ImageAdapter(this);
ImageView imageView = (ImageView) findViewById(R.id.full_image);
imageView.setImageResource(imageAdapter.finalImages[position]);
}
}
ImageAdapter.java
package org.android.pps;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
/*This class will be used handle the loading of the image view that will display all the
images of the rewards. (this will be used along with RewardsActivity and rewards.xml)
*/
public class ImageAdapter extends BaseAdapter {
//variable that will store the current context of the application
private Context c;
private Integer num = 6;
private int[] rewards_num=new int[num];
private Integer[] Images = new Integer[6];
public Integer[] finalImages;
//for loop will set the correct image to the array if its either activated or deactivated
public Integer[] fillImageArray()
{
//Array that will be used to show the reward images
Integer[] Activated ={
R.drawable.rewards1,
R.drawable.rewards2,
R.drawable.rewards3,
R.drawable.rewards4,
R.drawable.rewards5,
R.drawable.rewards6,
};
Integer[] Deactivated ={
R.drawable.rewards1b,
R.drawable.rewards2b,
R.drawable.rewards3b,
R.drawable.rewards4b,
R.drawable.rewards5b,
R.drawable.rewards6b,
};
//for loop that checks to see all the rewards that a particular users has to assign a particular image.
for(int x = 0;x<rewards_num.length;x++)
{
for(int y = 0;y<6;y++)
{
if(rewards_num[x]==y)
{
Images[x]=Activated[y];
}
else
{
Images[x]=Deactivated[y];
}
}
}
return Images;
}
//constructor with the context being passed.
public ImageAdapter(Context m)
{
c = m;
}
public int getCount() {
return 6;
}
public Object getItem(int position) {
return Images[position];
}
public long getItemId(int position) {
return 0;
}
// The function View create a new ImageView for each item that is being referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
finalImages = fillImageArray();
ImageView imageView = new ImageView(c);
imageView.setImageResource(finalImages[position]);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(300, 300));
return imageView;
}
}
finalImages in noi initialized there .........
it is finalImages in the getview which is not get called in 2nd activity (RewardsViewActivity )...........
if possible move this line to constructor finalImages = fillImageArray();