So I have a simple application in which I am taking an image with the camera and then loading the images into a GridView, when I click on the GridView it must open a bigger version of that image. I cannot get the image to open bigger.
The problem is that I have no reference to that image when passing it to the Activity which makes the image bigger. Code is below.
MainActivity.java
protected static final String EXTRA_RES_ID = "POS";
private ArrayList<String> mThumbIdsSelfies = new ArrayList<String>();
if(populateArrayList())
{
GridView gridview = (GridView) findViewById(R.id.gridview);
// Create a new ImageAdapter and set it as the Adapter for this GridView
gridview.setAdapter(new ImageAdapter(this, mThumbIdsSelfies));
// Set an setOnItemClickListener on the GridView
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View v,
int position, long id)
{
//Create an Intent to start the ImageViewActivity
Intent intent = new Intent(MainActivity.this, ImageViewActivity.class);
// Add the ID of the thumbnail to display as an Intent Extra
intent.putExtra(EXTRA_RES_ID, (int) id);
// Start the ImageViewActivity
startActivity(intent);
}
});
}
private boolean populateArrayList()
{
File dir = getAlbumDir();
//Bitmap myBitmap;
if (dir.isDirectory())
{
File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++)
{
//myBitmap = BitmapFactory.decodeFile(files[i].toString());
mThumbIdsSelfies.add(files[i].toString());
}
}
return true;
}
ImageViewActivity.java - This is the one that makes the image bigger
public class ImageViewActivity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Get the Intent used to start this Activity
Intent intent = getIntent();
// Make a new ImageView
ImageView imageView = new ImageView(getApplicationContext());
// Get the ID of the image to display and set it as the image for this ImageView
imageView.setImageResource(intent.getIntExtra(MainActivity.EXTRA_RES_ID, 0));
setContentView(imageView);
}
}
ImageAdapter.java
public class ImageAdapter extends BaseAdapter
{
private static final int PADDING = 8;
private static final int WIDTH = 250;
private static final int HEIGHT = 250;
private Context mContext;
private List<String> mThumbIds;
// Store the list of image IDs
public ImageAdapter(Context c, List<String> ids)
{
mContext = c;
this.mThumbIds = ids;
}
// Return the number of items in the Adapter
#Override
public int getCount()
{
return mThumbIds.size();
}
// Return the data item at position
#Override
public Object getItem(int position)
{
return mThumbIds.get(position);
}
// Will get called to provide the ID that
// is passed to OnItemClickListener.onItemClick()
#Override
public long getItemId(int position)
{
return mThumbIds.indexOf(position);
}
// Return an ImageView for each item referenced by the Adapter
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
ImageView imageView = (ImageView) convertView;
// if convertView's not recycled, initialize some attributes
if (imageView == null)
{
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(WIDTH, HEIGHT));
imageView.setPadding(PADDING, PADDING, PADDING, PADDING);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
}
//imageView.setImageResource(mThumbIds.get(position));
Bitmap b = BitmapFactory.decodeFile(mThumbIds.get(position));
imageView.setImageBitmap(b);
return imageView;
}
}
So the problem with the above function is that I cannot use getItemId as it does not return a long, rather it returns a string and I have no way of getting something useful from it.
The other thing I have tried is passing the bitmap image as an extra in my bundle and reading it on the other side, still I have no luck in getting the actual image to display.
I finally figured this out, so here is what I did.
MainActivity.java - Changed the following line
intent.putExtra(EXTRA_RES_ID, mThumbIdsSelfies.get(position)/*(int) id*/);
ImageViewActivity.java
String s = intent.getStringExtra(MainActivity.EXTRA_RES_ID);
Bitmap bitmap = BitmapFactory.decodeFile(s);
imageView.setImageBitmap(bitmap);
So those changes finally helped me, all I had to do was pass a string reference to the file location of the thumbnail I just clicked on. Then in the Activity that enlarges that image, I had to get that string reference and generate a bitmap out of it and then set that bitmap to the imageView.
Assuming that mThumbIdsSelfies is an ArrayList of the image paths you can use this:
Intent intent = new Intent(MainActivity.this, ImageViewActivity.class);
intent.putExtra(EXTRA_RES_ID, mThumbIdsSelfies[position]);
startActivity(intent);
Then retrieve it in your Activity(ImageViewActivity) and use it as you do in your adapter's getView() method.
Related
I have been working on this issue for days now. I am using the kankan Android wheel example/library, but am wanting to dynamically add images to the wheel when a button is pressed. The image added depends on the button's text. It seems like a fairly easy task, but perhaps I am missing something. I tried calling the adapter's notifyDataChangedEvent() after passing and adding the selected image to the adapter's list of cached images. Debugging has showed that the images were being added to the list of images, but they are not showing up on the wheel. If someone could please help me out with this problem I would appreciate it!
Code:
public void addItem(String text) {
for(Item c: Item.values()){
if(c.getName().equals(text)) {
slotMachineAdapter.addImage(c.getImage());
break;
}
}
slotMachineAdapter.notifyDataChangedEvent();
}
Adapter
private class SlotMachineAdapter extends AbstractWheelAdapter {
// Image size
final int IMAGE_WIDTH = 700;
final int IMAGE_HEIGHT = 150;
// Slot machine symbols
private final int items[] = new int[] {
R.mipmap.ic_flipper
};
// Cached images
private List<SoftReference<Bitmap>> images;
// Layout inflater
private Context context;
/**
* Constructor
*/
public SlotMachineAdapter(Context context) {
this.context = context;
images = new ArrayList<SoftReference<Bitmap>>();
for (int id : items) {
images.add(new SoftReference<Bitmap>(loadImage(id)));
}
}
/**
* Loads image from resources
*/
private Bitmap loadImage(int id) {
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), id);
Bitmap scaled = Bitmap.createScaledBitmap(bitmap, IMAGE_WIDTH, IMAGE_HEIGHT, true);
bitmap.recycle();
return scaled;
}
#Override
public int getItemsCount() {
return items.length;
}
// Layout params for image view
final ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(IMAGE_WIDTH, IMAGE_HEIGHT);
#Override
public View getItem(int index, View cachedView, ViewGroup parent) {
ImageView img;
if (cachedView != null) {
img = (ImageView) cachedView;
} else {
img = new ImageView(context);
}
img.setLayoutParams(params);
SoftReference<Bitmap> bitmapRef = images.get(index);
Bitmap bitmap = bitmapRef.get();
if (bitmap == null) {
bitmap = loadImage(items[index]);
images.set(index, new SoftReference<Bitmap>(bitmap));
}
img.setImageBitmap(bitmap);
return img;
}
//Adds image to list of images
public void addImage(int img){
images.add(new SoftReference<Bitmap>(loadImage(img)));
}
}
Because the count you return referenced to items variable, But addImage function did not change items size. Try to change your code like below and test it again:
#Override
public int getItemsCount() {
return images.size();
}
I am creating thumbnails from videos stored in my sd card ,displaying thumbnails and its names in grid view. On item selected event of the grid view pop ups a dialog and asking x, y, right, bottom positions then pasting it to the main activity . I got the video files, and tried to create thumbnail using media store also am retrieving thumbnail as bitmap, but the bitmap is null. In the grid view video names are shown and i am able to select the corresponding thumbnail and can give positions also am able set the thumbnail to the main activity. The problem is the bitmap is null and bitmap image not showing(text vie video name shown). What's the problem ? I can't figure it out? Plz help me? My code is given below. thanks in advance.
if (f.isFile()) {
if (fName.endsWith(".mpg")
|| fName.endsWith(".mov")
|| fName.endsWith(".wmv")
|| fName.endsWith(".rm")
|| fName.endsWith(".mp4")) {
tv.setText(fName);
path = f.getAbsolutePath();
System.out.println("Video file path=>"+path);
thumb = ThumbnailUtils.createVideoThumbnail(f.getAbsolutePath(),MediaStore.Video.Thumbnails.MICRO_KIND);
if(thumb==null)
{
/**Every time it printing null**/
System.out.println("Thumb is null");
}
iv.setImageBitmap(thumb);
From ThumbnailUtils.createVideoThumbnail documentation: May return null if the video is corrupt or the format is not supported.
By default, almost all supported formats are mp4 and 3gp. See here: http://developer.android.com/guide/appendix/media-formats.html for full list of default-supported media formats.
If you are creating thumbnail from sd card video this would create ThumbnailUtils.createVideoThumbnail otherwise use a cursor.
See this example.
Try this code. It is getting the thumbnail of videos from urls. instead of pass the path of sd card .it will help you . Dont forgot to add internet permission in manifest file.
public class VideoThumbnailActivity extends Activity {
public static final String Downloader = null;
static String uri1="http://daily3gp.com/vids/lucky_guy.3gp";
static String uri2="http://daily3gp.com/vids/reporter_hit_by_plane.3gp";
static String uri3="http://daily3gp.com/vids/motorcycle_wipesout_explodes.3gp";
static String uri4="http://commonsware.com/misc/test2.3gp";
public static String uri_array[]={uri1,uri2,uri3,uri4,uri1,uri2,uri3,uri4,uri1,uri2,uri3,uri4};
ImageView imageView;
String url;
Gallery ga1,ga2;
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imageView = (ImageView)findViewById(R.id.imageView);
ga1 = (Gallery)findViewById(R.id.gallery1);
ga1.setAdapter(new ImageAdapter(getApplicationContext()));
imageView.setImageBitmap(ThumbnailUtils.createVideoThumbnail(uri_array[0], MediaStore.Video.Thumbnails.FULL_SCREEN_KIND));
//on click event on gallery
ga1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, final int position,long arg3) {
imageView.setImageBitmap(ThumbnailUtils.createVideoThumbnail(uri_array[position], MediaStore.Video.Thumbnails.FULL_SCREEN_KIND));
//on click event on imageview to play video
imageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// TODO Auto-generated method stub
Intent intent = new Intent(getApplicationContext(),PlayActivity.class);
intent.putExtra("path",uri_array[position]);
startActivity(intent);
}
});
}
});
}
public class ImageAdapter extends BaseAdapter {
private Context ctx;
int imageBackground;
public ImageAdapter(Context c) {
ctx = c;
TypedArray ta = obtainStyledAttributes(R.styleable.Gallery1);
imageBackground = ta.getResourceId(R.styleable.Gallery1_android_galleryItemBackground, 1);
ta.recycle();
}
#Override
public int getCount() {
return uri_array.length;
}
#Override
public Object getItem(int arg0) {
return arg0;
}
#Override
public long getItemId(int arg0) {
return arg0;
}
#Override
public View getView(int position, View view, ViewGroup arg2) {
ImageView iv = new ImageView(ctx);
Bitmap curThumb = null;
curThumb = ThumbnailUtils.createVideoThumbnail(uri_array[position],MediaStore.Video.Thumbnails.FULL_SCREEN_KIND);
iv.setImageBitmap(curThumb);
iv.setScaleType(ImageView.ScaleType.FIT_XY);
iv.setLayoutParams(new Gallery.LayoutParams(150,120));
iv.setBackgroundResource(imageBackground);
return iv;
}
}
let me know your problem is resolved or not.
So I have a Gridview and and ImageAdapter class. The images all get grab from a folder and then populated into the grid view. I then have another class that displays the full image when clicked. However whenever someone clicks an image ImageAdapter has to get called again and all the images need to be repopulated into my variables and then I just pick out the one I need. This is terribly inefficient but I don't know how to do it otherwise.
Here is my code.
Main Classes (favorites in this case) with the grid view
public class Favorites extends Activity {
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.favorites);
GridView gridview = (GridView) findViewById(R.id.favgridview);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent,View v, int position, long id){
Intent i = new Intent(getApplicationContext(), FullImageActivity.class);
i.putExtra("id", position);
startActivity(i);
}
});
}
}
My ImageAdapter class, you can see that I load all the images as bitmaps into an array.
public class ImageAdapter extends BaseAdapter{
private Context mContext;
private Bitmap[]mis_fotos;
public ImageAdapter(Context c){
mContext = c;
}
public int getCount(){
get_images();
return mis_fotos.length;
}
public Bitmap getItem(int position){
get_images();
return mis_fotos[position];
}
public long getItemId(int position){
return 0;
}
public View getView(int position, View convertView, ViewGroup parent){
ImageView imageView;
if (convertView == null){
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85,85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageBitmap(mis_fotos[position]);
return imageView;
}
private void get_images(){
String dirPath = mContext.getFilesDir().getAbsolutePath() + File.separator + "favorites";
File directory = new File(dirPath);
File[] archivos = directory.listFiles();
mis_fotos = new Bitmap[archivos.length];
for (int cont=0; cont<archivos.length;cont++){
File imgFile = new File(archivos[cont].toString());
mis_fotos[cont] = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
}
}
}
And Finally my Full Image Class
public class FullImageActivity extends Activity {
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.full_image);
Intent i = getIntent();
int position = i.getExtras().getInt("id");
ImageAdapter imageAdapter = new ImageAdapter(this);
ImageView imageView = (ImageView) findViewById(R.id.full_image_view);
imageView.setImageBitmap(imageAdapter.getItem(position));
}
}
So you can see that when I use the full image all I can pass is the position integer from the gridview class. I then have to call get_images() again in the ImageAdapter class and repopulate an array all over again.
All I need to to pass a single image from the gridview to the fullimage class when an image is clicked. I know there is an easier and far more efficient way to do this. I hope this makes sense.
Work around required, you are calling get_images() multiple times inside an Adapter class which is a bad way. Better solution is remove it from Adapter class and keep inside the MainActivity and just call it before setting the Adapter like,
GridView gridview = (GridView) findViewById(R.id.gridView);
get_images();
gridview.setAdapter(new ImageAdapter(this));
And then your method for Adapter class should be like,
public int getCount() {
return mis_fotos.length;
}
public Object getItem(int position) {
return mis_fotos[position];
}
Now, I come to your issue that is you want to show an Image as fullscreen to Next Activity. So, why don't you fetch the Bitmap from clicked ListView Item and pass it to Next Activity?. So, how can you do that? Here it is,
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
Bitmap bitmap = (Bitmap) parent.getAdapter().getItem(position);
Intent i = new Intent(getApplicationContext(), FullImageActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable("bitmap", bitmap);
i.putExtras(bundle);
startActivity(i);
});
So, nothing tricky, just getting the Bitmap using getItem(position); and the sending it to Next Activity using Bundle. Now you can easily get the Bitmap using
Bundle bundle = getIntent().getExtras();
Bitmap bitmap = bundle.getParcelable("bitmap");
// create new Bitmap with any height, width required by you.
Bitmap newBitmap = Bitmap.createScaledBitmap(bitmap, 200, 200, true);
and show to ImageView.
I have a working Gallery that shows one picture at a time and can be "swiped" to rotate through the images. I want to have the option of the user to view 2 or 3 pictures at a time by using the menu and selecting how many to show. So far Ive tried adjusting the Gallery width, and LinearLayout params and all crash the Activity. any advice would be appreciated.
I declare and initialize the Gallery here and have the onOptionsItemSelected method sekeleton.
public class SpeechAppActivity extends Activity implements OnClickListener{
//Menu Items
// Class variables
Gallery myGallery;
ImageView imageView;
MyDBAdapter db;
Item item1;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
db = new MyDBAdapter(this);
db.insertEntry(item1 = new Item("Bathtub", "Bathroom", "Typical", "Clean", "fill, wash", "Round, deep", "Bathroom", "Toilet, Bathroom", R.drawable.ic_launcher));
Log.i("item", "item: " + item1.toString());
// Bind the gallery defined in the main.xml
// Apply a new (customized) ImageAdapter to it.
myGallery = (Gallery) findViewById(R.id.myGallery);
myGallery.setAdapter(new ImageAdapter(this));
//myGallery.setLayoutParams(new Gallery.LayoutParams(250, 250));
myGallery.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View v,
int position, long id) {
}
public void onNothingSelected(AdapterView<?> parent) {
}
});
public boolean onOptionsItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.settings:
startActivity(new Intent(this, Prefs.class));
return true;
case R.id.show1:
//myGallery.findViewById(R.id.myGallery).setLayoutParams(new Gallery.LayoutParams(500, 250));
return true;
case R.id.show2:
//myGallery.findViewById(R.id.myGallery).setLayoutParams(new Gallery.LayoutParams(500, 250));
return true;
case R.id.show3:
//myGallery.findViewById(R.id.myGallery).setLayoutParams(new Gallery.LayoutParams(500, 250));
return true;
}
return false;
}
This is the Image Adapter class for the Gallery
public class ImageAdapter extends BaseAdapter {
/** The parent context */
private Context myContext;
// Put some images to project-folder: /res/drawable/
// format: jpg, gif, png, bmp, ...
private int[] myImageIds = { R.drawable.apple, R.drawable.orange,
R.drawable.ic_launcher };
/** Simple Constructor saving the 'parent' context. */
public ImageAdapter(Context c) {
this.myContext = c;
}
// inherited abstract methods - must be implemented
// Returns count of images, and individual IDs
public int getCount() {
return this.myImageIds.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
// Returns a new ImageView to be displayed,
public View getView(int position, View convertView,
ViewGroup parent) {
// Get a View to display image data
ImageView iv = new ImageView(this.myContext);
iv.setImageResource(this.myImageIds[position]);
// Image should be scaled somehow
//iv.setScaleType(ImageView.ScaleType.CENTER);
iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
//iv.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
//iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
//iv.setScaleType(ImageView.ScaleType.FIT_XY);
//iv.setScaleType(ImageView.ScaleType.FIT_END);
//iv.setScaleType(ImageView.ScaleType.FIT_START);
// Set the Width & Height of the individual images
//get scale for finding dip of a set # of pixels
final float scale = parent.getContext().getResources().getDisplayMetrics().density;
iv.setLayoutParams(new Gallery.LayoutParams((int) (300 * scale + 0.5f), (int) (250 * scale + 0.5f)));
return iv;
}
}// ImageAdapter
In your adapter,
Use View object (witn custom view) and put ImageView inside it.
This was you can put more than one images per view.
Best results can be achieved by few layout files based on number of images and using correct one according to user selection.
Let me know if you need more specific code template.
How can we switch the pictures with some information? When we switch the picture then information should also be get switched in Gallery view in android.
public class ImageAdapter extends BaseAdapter {
String[] Merchantname=null,Cardname=null,Points=null,Expirydate=null,status=null;
private Context ctx;
int imageBackground;
Bitmap[] image_data;
public ImageAdapter(Context c, Bitmap []card_image,String [] Merchantname,String [] Cardname,String []points,String[] Expirydate, String []status) {
ctx = c;
image_data = card_image;
TypedArray ta = obtainStyledAttributes(R.styleable.Gallery1);
imageBackground = ta.getResourceId(R.styleable.Gallery1_android_galleryItemBackground, 1);
ta.recycle();
this.Merchantname=Merchantname;
this.Cardname=Cardname;
this.Points=points;
this.Expirydate=Expirydate;
this.status=status;
}
public int getCount() {
return image_data.length;
}
public Object getItem(int arg0) {
return arg0;
}
public long getItemId(int arg0) {
return arg0;
}
public View getView(int position, View arg1, ViewGroup arg2) {
TextView tv1,tv2,tv3,tv4,tv5;
ImageView i ;//= new ImageView(this.ctx);
if (arg1 == null) {
i = new ImageView(this.ctx);
} else {
i = (ImageView) arg1;
}
tv1=(TextView)findViewById(R.id.Merchantname);
tv2=(TextView)findViewById(R.id.Cardname);
tv3=(TextView)findViewById(R.id.Expirydate);
tv4=(TextView)findViewById(R.id.status);
tv1.setText(Merchantname[position]);
tv2.setText(Cardname[position]);
tv3.setText(Expirydate[position]);
tv4.setText(status[position]);
// ImageView iv = new ImageView(ctx);
// Drawable drawable = new BitmapDrawable(getResources(), image_data[position]);
i.setImageBitmap(image_data[position]);
i.setImageDrawable(new BitmapDrawable(getResources(), image_data[position]));
i.setScaleType(ImageView.ScaleType.FIT_XY);
i.setLayoutParams(new Gallery.LayoutParams(300,200));
i.setBackgroundResource(imageBackground);
return i;
}
}
You simple need to use an ArrayList whose Index would be linked with the Gallery views individual views, and the lenth of the ArrayList would match the Length of Gallery View, on the setOnItemClickListener use the position variable to change the Content from the Array List matching the same index
// Reference the Gallery view
Gallery g = (Gallery) findViewById(R.id.gallery);
// Set the adapter to our custom adapter (below)
g.setAdapter(new ImageAdapter(this));
// Set a item click listener, and just Toast the clicked position
g.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int position, long id) {
Toast.makeText(Gallery1.this, "" + position, Toast.LENGTH_SHORT).show();
}
});
Create layout with ImageView and TextView. Then write your custom adapter for Gallery and there in getView method put to ImageView and TextView your values. Them set this adapter to your Gallery.
The Problem Lies here,
tv1=(TextView)findViewById(R.id.Merchantname);
tv2=(TextView)findViewById(R.id.Cardname);
tv3=(TextView)findViewById(R.id.Expirydate);
tv4=(TextView)findViewById(R.id.status);
You forgot to mention the Parent View before asking for the LayoutFile, add (TextView)arg1.findViewById() for all the TextViews and let us know.
Hope it helps