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.
Related
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.
Is there any way to remove selected item from gridview.
I want to delete the selected item from my gridview.
I did not find any thing . my code is
public class ImageAdapter extends BaseAdapter{
Context context;
public ImageAdapter(Context context)
{
this.context = context;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return mThumbIds.length;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ImageView imageView;
if (convertView == null) { // if it's not recycled, initialize some attributes
imageView = new ImageView(context);
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(0, 5, 0, 0);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
public Integer[] mThumbIds = {
R.drawable.sample_1,R.drawable.sample_2,R.drawable.sample_3,
R.drawable.sample_3,R.drawable.sample_1,R.drawable.sample_2,
R.drawable.sample_2,R.drawable.sample_3,R.drawable.sample_1
};
}
//////////////////
public class ImageActivity extends Activity {
ImageAdapter iAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image);
iAdapter = new ImageAdapter(this);
final GridView gView = (GridView)findViewById(R.id.grid_view);
gView.setAdapter(iAdapter);
gView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
//gView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
// gView.setItemChecked(position, true);
Toast.makeText(ImageActivity.this, "" + position, Toast.LENGTH_SHORT).show();
}
});
iAdapter.notifyDataSetChanged();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_image, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.menu_delete)
{
Toast.makeText(this, "Delete",Toast.LENGTH_SHORT ).show();
}
return super.onOptionsItemSelected(item);
}
}
can anyone have idea .
thank
you are using a table :
public Integer[] mThumbIds = {
R.drawable.sample_1,R.drawable.sample_2,R.drawable.sample_3,
R.drawable.sample_3,R.drawable.sample_1,R.drawable.sample_2,
R.drawable.sample_2,R.drawable.sample_3,R.drawable.sample_1}
Tables are not modifiable.
Replace it by a List on which you will be able to make add or remove operations. Simply call notifyDataSetChanged when a change is made to let the adapter know that its list has been modified.
As Teovald and pskink suggested, you cannot have a fixed list of images and then implement the remove functionality that you are looking for. If you want to add remove, change your design and make sure your data set is also removable. What you have tried so far seems to be using some really basic code which is good to show basic GridView feature.
Just try this. Create a image data set class which returns the actual images. Store the images in a List that can be modified. Add setters/getters to this data set and also add a method to delete a particular item. Change your image adapter to use the image from this new data set. Whenever an image is deleted, call the notifyDataSetChanged on the adpater.
Good luck
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.
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
i have a big doubt about memory leak and screen rotation. I know that activity is destroy when that happens and new one is started. With my code, with is the best way to show the gridview? (this activity is part of a tab activity so in the main one i get the pictures from web services and put them on the object, using AsyncTask)
i would like to show the pictures at the same time they are saved on the object. Like simulating ajax...is that possible? at the moment, they are all show on the start or resume.
Also, im facing memory leak here?
last question, how can i show photos in the grid
my code:
public class LoteFotosActivity extends Activity {
Sistema sis=Sistema.getInstance();
Lote lote;
GridView gridview;
ImageAdapter iA;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.lote_foto_view);
Bundle extras = getIntent().getExtras();
lote=sis.getLoteDetalle(extras.getInt("LoteID"));
gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(iA=new ImageAdapter(this));
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
Toast.makeText(LoteFotosActivity.this, "" + position, Toast.LENGTH_SHORT).show();
}
});
}
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return lote.FOTOS.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(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) { // if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(200,200));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageBitmap(lote.FOTOS.get(position));
return imageView;
}
}
//test looking
public void onResume() {
super.onResume();
Toast.makeText(this,"ON RESUME",
Toast.LENGTH_SHORT).show();
// gridview.setAdapter(new ImageAdapter(this));
// foto.setImageDrawable(lote.FOTOS.get(0));
}
public void onPause() {
super.onPause();
Toast.makeText(this,"onPause",
Toast.LENGTH_SHORT).show();
iA=null;
gridview.setAdapter(iA=new ImageAdapter(this));
// foto.setImageDrawable(lote.FOTOS.get(0));
}
thx in advance !
I think you should add this to your activity
android:configChanges="orientation"
to avoid the destroying problem when rotating the screen... with this you dont need to save state to restore, there is no need because the activity is not destroyed and recreated everytime the screen rotation changes
For API 13+ the screenSize must also be handled:
android:configChanges="orientation|screenSize"