I am new to Android and Java. I am building an app that allows users to push a button which launches an image chooser where they can select from images on the sd card. The app loads with a grid view with 2 cells. One cell has an image view that has a default image. The other is the button. Once, the image is chosen, the image view needs to be displayed in the Image View of the Grid View.
I am using a string path that is being decoded from the images uri to create a bitmap. I then am calling imageView.setImageBitmap(bitmap). This is doing nothing. I have tried updating the image resource with a different image in the drawable folders and still nothing. I added a seperate image view just under the grid in my activity, and that image is updating fine which leads me to believe that this has to do with the grid view (this is my first grid view).
Any help is very much appreciated.
Thank you.
GridView is maybe not the right choice if you've only got two cells. You will probably have an easier time with a simple LinearLayout that has the two items you're dealing with.
But, here's how you do it with a GridView:
Create your adapter by extending BaseAdapter. The most important method is getView(), but it's where you should be doing the least amount of work.
When the GridView goes to redraw itself, it'll go through for each visible position and call getView() for each one. You'll be supplied a View. If the view is null, inflate a new one from your XML resources, populate it, and return it. If the view is NOT null, populate the existing one with the appropriate data. The widget is being efficient by recycling views.
The trick you need is that when you want the image to change, you need to call notifyDataSetChanged() on your adapter in order to trigger the redraw (which is when you'll populate the new image in the view for the appropriate cell).
That's the two-minute version. At Google I/O a year or two back, they did a talk on The World of ListView and posted it on YouTube. It was a good talk and pretty much everything there applies to GridView as well.
Related
I want to load list of images from the server.
1) I prefer if I can use the screen space optimally by adjusting the image columns.
2) User should be able to click each image individually and navigate to the next screen.
3) Further, when the screen first loads, I would like to load few image slots with loading image and replace them when we get the data from the server. It will add additional image slots as well (i.e after replacing first few) based on the data. so that user can see we are waiting for the data.
See below
What I already tried.
1) Using custom list view and adapter approach (http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/), I created a layout with two listviews, acting as two columns and loaded images each one separately. Issue is user will see two scrollbars when image list is long. Also cannot adjust the number of columns based on screen size.
2) Same custom list view with, row layout having two imageviews. Issue here is user cannot click individual imageview.
I was not able to replace images to implement the third requirement.
How can I implement this. Are there any resources/controls I can use.
Thanks
Pa
I would probably use a gridview and an adapter for the gridview items. Just load a local image for loading to the imageview of the griditems and replace them with the images from the server
I am working on an app which requires an autocompletetextview for suggesting contacts in dropdown view. I am using a custom cursor adapter. My layout for one drop down item has imageview on the left (for showing image of the contact if available, else a default image).
I have used Asynctask to load images from the contacts. In my bindView method, I have following snippet to load images from the Async task.
contactImage = new conactImage(viewHolder, cursor);
contactImage.execute(new String[] {userId});
and in the Asynctask's onPostExecute method, I set the image bitmap.
mViewHolder.cImage.setImageBitmap(imageResultBitmap);
mViewHolder is the viewholder passed as argument in the previous snippet.
The problem I am facing is a bad UX. Suppose I entered two characters in the autocompletetextview. The images show up in a second. When I scroll, the images don't change unless I wait another 2 3 seconds to get the correct image loaded. And when I scroll fast, the views flicker a lot because of the random image bitmap changes.
I understand it is a view recycling thing, but this gets annoying. Please suggest any other possible way to do the same.
on scrolling
Thanks!
I want to create a Custom listview like this the below image. I am creating a chat app, in that app have to pass text, images and video etc. see below image.
In that, when a user send/receive image in chat, if he wants to see that by clicking on the button beside that image, how to move to another activity with that image path (or) url, for showing full image, and when user clickngi on image have to show a Quick view. same way if that is video, i have to get that path (or) url to play video properly.
How to differenciate the list item depends on the item type.
If you want to show different rows for audio, image and text messages, you need to have 3 row layouts, then you will decide which row needs to be returned from your getView() of your CustomAdapter. There are two methods getViewTypeCount() and getItemViewType() of Adapter which will help your recycling the row to show up in ListView.
You will first tell that how many layouts in your ListView will be using getViewTypeCount() which tells the adapter how many row types will be there, next check what kind of data is present at that position in your data model and you return the view type from getItemViewType(), so getView() will receive the relevant recycled view (if there is any).
Here is my blog post about using 9 patch images, it demonstrate sender and receiver type of views, same can be applied for image and audio based on the item in your data model at that specific position.
You can
implement ScrollView and add views into it.
create adapter that contains all of the possible views and then decide which view to hide or to show
you can create adapter and dynamically add view into each row (in this case it's too slow).
My choise is #2 - create row view with all possible views and then decide what to hide, in this case you can save time because you won't have to inflate you views each time and you can use even ViewHolder pattern.
Feed in Four Square android app looks like this:
A rectangular box with actual post, below which is a Text like 10 people like this and so on.
Is this just a listView with Actual content having margins and a different background, and TextViews below it.
Because when i had a complicated ListView with an ImageView and 5-6 TextViews, it takes lot of time to load the UI.
1 of my friends who work on iOs said Instead of Custom ListView Items, use ImageView which look like a Custom View with images and textviews. Which makes loading lot faster. But ofcourse it takes lot to implement such thing.
I just want to know, if its just another custom listview?
And that my delay to load the UI is because of someother reason?
Such techniques are available in android too??
Thank You
Could be a ListView with complicated children views. Could also be an ExpandableListView.
There's a few reasons why it may load faster than something you've used before:
The images were probably already cached on the file system, so it loads from local storage rather than downloading the image.
The images were already the correct dimensions, so no resizing was needed.
Image loading was done on a background thread as to not lag the UI while images were being loaded into memory.
You could expand a complex layout for each ListView item in Adapter.getView() and remove (View.setVisibility(View.Gone)) on the views you don't need based on the item's object you want to render.
If you want to reuse the expanded layout don't forget to set the visibility of everithing again to View.VISIBLE.
I'm already doing this in my code:
if (post.getImageURL() != null && !post.getImageURL().isEmpty()) {
holder.image.setVisibility(View.VISIBLE);
holder.image.setScaleType(ScaleType.FIT_CENTER);
displayImage(post.getImageURL(), holder.image);
} else {
holder.image.setVisibility(View.GONE);
}
In this case I'm hidding an optional image.
I have a Gallery, which has an adapter connects to it. In the getView method, i have a custom layout, so that I can i have image and caption displayed together
The image is downloaded from an URL, which is done asynchously, and working as expected.
Currently i make each item to fill the screen, so i only have one item display at a time, basically i want to make it like a slide show.
let me be clear, currently i have an activity, and it only has one View, which is a Gallery.
problem occurs when I am swiping, the image bounces and stays at the same image. i need to swipe many times, hard, and long swipe, then i can get to next image.
i put a debug message in my custom adapter in the getView(), it seems getView is getting called many times (4 times), and position being passed is either the current position or the previous one, which explains why i am stuck at the same screen.
if i remove the remote downloading image part, or just use a static image form the phone, i don't have any more issues, in fact, the getView only gets called once, with correct position.
i am very frustrated, not sure what the problem is, could it be because i am downloading image asynchously, which will cause the image to update which causes getView to get called again to redraw itself?
i am not sure..
please help
Unfortunately this is a bug with gallery. Listviews will scroll nicely regardless of data being updated asynchronously. However, the gallery is just not coded up to par with the listview
When the gallery tries to update a visible view (due to your image loading callback) this view will "snap" back to the focused position. If you are changing the view in any way when it is scrolling it will snap. This is likely why you have to scroll hard to get away from the current view. It is trying to perform a callback on your view and only scrolling fast will prevent the callback from occurring before you move away from that view.
I've reported this bug a while ago here:
Android Issues
There are a few workarounds posted in there you can try if you are set on using a Gallery.
Unfortunately it hasn't gained attention from the Android developers.
It seems the issue is caused with views being set to "wrap_content" and the gallery having to remeasure/redraw its views
I have since migrated away from using the gallery and instead use a ViewPager. It is much easier to manage and you don't have to worry about this problem. This has been a known problem with the Gallery since the gallery was first introduced. I have no idea if this was fixed in any of the newer Android versions (3.x/4.x). As of 2.3.7 it is not fixed.
At first you should note: Any AdapterView (Gallery, ListView etc) doesn't guarantee that each time getView() method is called it will pass the same View instance parameter. It only guarantees that each view will have the same type (see Adapter.getIntemViewType() method docs)
So, when you start image downloading you should only specify position of the element. Then after the image has been downloaded you should bind specified ImageView with downloaded image in Adapter.getView() method call.
Take a look to the ImageDownloader from the Android samples here
The other approach is to use WeakHashMap in order to contain map of adapter views to its positions. I can provide you with code samples if you need.