GridGalleryThumbnailFragment to photoActivity
All the gallery objects are obtained from internet, my current setup is whenever user reaches the Fragment a network request is made and if it successful the gallery objects with thumbnails and image urls are returned. When the user clicks on an individual item a intent will start the activity and puts extra intent data with image title and image url and the image is opened in full screen. Now I want to implement a next/previous functionality in the Activity, what is the best approach for it.
Make a second network request in the activity and get the values from this new adapter.
Remove the activity workflow and just replace View in the fragment with the full image view.
Store all the values obtained the first time around in android local storage.
You need two adapters which have the same data in the same order:
a GalleryAdapter and a ImagePagerAdapter
When the GalleryView starts the ImageView the ImageView needs the gallery-s current offset. next/previous is just adding 1 to or subtracting 1 from the offset.
I have implemented something similar but based on a database query using a CursorAdapter and a android.support.v4.view.PagerAdapter . Both GalleryView and ImageView share the same sql.
[Update]
If you donot want to load the data twice you can use a LoaderManager where GalleryView and ImageView both use the same loader-Impementation/loader-ID
Related
Using Android kotlin firebase recycle view
I want to make the user take a picture of his phone or get a photo from gallery and add it to recyclerView list , and every time he takes a photo the recycler list increase automatically it works if i get the photo from drawable now i want to get it from camera or gallery. how to achieve it thanks
Please refer to the documentation https://developer.android.com/guide/topics/ui/layout/recyclerview, under section Add a list adapter you can read a following information :
To feed all your data to the list, you must extend the RecyclerView.Adapter class. This object creates views for items, and replaces the content of some of the views with new data items when the original item is no longer visible.
So, basically you have to create adapter for your recycler view, from which you can insert new item (photo) to you recyclerview.
More information about implementation the functionality is here:
How to update RecyclerView Adapter Data?
To capture/select photo from your gallery first you need permission accessing internal/external storage and camera I suggest you to read this https://developer.android.com/training/permissions/requesting
If you are willing to use Firebase to get these drawable/imgs, so you've to get the URL of the image as a string and put it in ArrayList/List.
Then your adapter class get URL and then use bitmap to download the image and convert it to bitmap (data type), How to load an ImageView by URL in Android?
Now when retrieving data from fire base: https://firebase.google.com/docs/database/admin/retrieve-data
add the string you got from the database in your arraylist then usenotifyOnDataChanged() to update your recyclerview.
How to update RecyclerView Adapter Data?
I have an activity which can take a few seconds to load its content (mainly pictures) from the cloud. Let's say this content is pictures & description from a person. The user can go to pictures & description from another person by clicking on the next button. I'd like to avoid the loading time When this button is clicked.
To do this I have two activities : firstPersonActivity for the first person content, and secondPersonActivity for the second person content.
What I try to do is to load the content of the secondPersonActivity when the user is in the firstPersonActivity, so that the secondPersonActivity can be displayed "directly" (= without needing to load content from the cloud when the next button is clicked in the firstPersonActivity).
But I do not succeed in doing this, I don't know how to modify the views of the secondPersonActivity layout from the firstPersonActivity class.
I tested the following code in my firstPersonActivity but it doesn't work (there is no connexion to the cloud, it's just a test to better understand how it works). R.id.first_image_second_person is the id of my imageview in the secondPersonLayout (= the layout used in the secondPersonActivity).
ImageView firstImageSecondPerson = (ImageView) findViewById(R.id.first_image_second_person);
firstImageSecondPerson.setImageResource(R.drawable.mypicture);
When I click on the next button to go from the firstPersonActivity to the secondPersonActivity, my firstImageSecondPerson imageview is not filled.
Do you see what's wrong ?
Is there a better way to avoid the loading time when the user click on the next button ?
It is not possible to change activity if activity instance is not created. In my opinion to do what You need I would go to single activity with hidden content of second person ( VIEW.INVISIBLE ) and show/hide it when it is needed.
But if second activity must be there, then create some structure for saving bitmaps in memory. In Your code sample You get picture from drawable so we are not talking about some delays, but if images are downloaded from some server then You can create some class which will have those bitmaps created from url and instance of this class can be used on any activity.
So for example Your class for caching pictures would have some method for creating bitmaps like -How to load an ImageView by URL in Android?. And those bitmaps should be saved in some Array or HashMap to have access to it, for example ( pseudo code ):
//some structure for cashing pictures in app
class PictureCache {
static PictureCache instance;
final HashMap<Integer, Bitmap> bitmaps;
//singleton
static PictureCache getInstance(){
if (instance==null)
instance = new PictureCache();
return instance;
}
public PictureCache(){
bitmaps = new HashMap<>;
}
private Bitmap loadBitmap(String url);//#1
public addPicture(Integer personId, String href){
//add to hashMap
bitmaps.put(personId, loadBitmap(href));
}
public Bitmap getPicture(Integer personId){
return bitmaps.get(personId);
}
}
#1 - method from How to load an ImageView by URL in Android?
Using it in first activity:
PictureCache.getInstance().addPicture(12,"http://url.to.bitmap");
Using it in second activity:
Bitmap pic = PictureCache.getInstance().getPicture(12);
Important note - above code was written here and was not tested, it shows solution concept.
Important second note - using such approach with bitmaps in memory can cause to much memory usage
You cannot access the views of SecondActivity before its creation. If you called this activity once only then you are able to access its views by making them static.
One more Solution for this is..
Access the whole data at once and save it in static arraylist with the help of getter-setters. Then on SecondActivity set data from that arraylist.
Hope this will work.
I don't think you can access the view before creating the activity.
You can try to use Glide for caching your images and minimizing loading time.
Try this
Picasso.with(getContext()).load(R.drawable.generatedId).into(imageView);
or
imageView.setImageDrawable(ActivityCompat.getDrawable(getContext(),
R.drawable.generatedID));`
I have a listview with text and images from web with JSON (works fine) and when I click on that I want to go to a DetailActivity with some TextViews and the ImageView from list. I can pass all the Textviews from the ListActivity to the DetailActivity but not the ImageView.
I tried to pass the bitmap with putextras and model but nothing. How can approach that issue? Can I call the bitmap from cache direct to the DetailActivity?
You can use ImageLoader
Intent i = getIntent();
// Get the result of flag
flag = i.getStringExtra("flag"); // image
// Locate the TextViews and images in singleitemview.xml
ImageView imgflag = (ImageView) findViewById(R.id.flag);
imageLoader.DisplayImage(flag, imgflag); // use lazylist image loader
You can see this example.
Did you save the image in the local storage? In this case, it would be better to send the Uri of the saved file instead of the raw bitmap.
Passing large amounts of data by intent does not always work. Although not documented, this often fails. See
Issue: Passing large data to second Activity
Starting an activity with large intent extras
and many more.
A good work-around would be to (a) save the bitmap to a file (b) pass the filename, by intent, to the detail activity, (c) In the detail activity re-create the bitmap.
The easiest way to pass complex objects that I have found is using EventBus: https://github.com/greenrobot/EventBus
Using EventBus you avoid having to serialize the data in any way, they are made directly available for other Activities/Fragments and regular classes even.
My answer to this question has some explanation on the subject: Saving information from one fragment and dialog if the user navigates to another fragment
This article also has some nice small examples of how simple it is plus some comparison to other approaches: http://www.stevenmarkford.com/passing-objects-between-android-activities/
As the title says, I'm using a BaseAdapter to display items in a ListView. Obviously a ListView will reuse views, including TextViews and NetworkImageViews.
Assuming 3 items can be displayed at once, the NetworkImageView will be reused for items at index: 1, 4, 7, ....
Depending on what's being displayed, the NetworkImageView will either:
request the image from the Network and display it,
display a cached Bitmap,
or display a local drawable resource.
Items 2 and 3 work fine, however in Scenario 1, let's say we're displaying item at index 4 from the network, and the user scrolls to item 7 before 4 is loaded and it's a local resource, we display the local resource. However our network image request may just be finishing now, so we end up displaying an incorrect image.
How can I enforce the proper (expected)behavior?
The answer from #Snicolas is spot on, but lacks some pointers on how to actually accomplish that. So here goes.
The general idea is to keep track of the ongoing image requests for every row. That way, when you encounter a recycled row, you can cancel the pending request and kick off a new one for the new data relevant to that row.
One straightforward way to accomplish that is to make the ImageContainer that you can get back when requesting an image load, part of the adapter's ViewHolder/RowWrapper. If you're not using this pattern yet, you should. Plenty of examples out there, including a good I/O talk.
Once you've added the ImageContainer to your holder, make an image request and store the container that you get back. Somewhat like this:
ImageListener listener = ImageLoader.getImageListener(holder.imageview, defaultImageResId, errorImageResId);
holder.mImageContainer = ImageLoader.get(url, listener);
The next time a recycled row comes in the adapter's getView() method, you can get your holder back from it and check wether it has a ImageContainer set. One of the following 3 scenarios may apply:
There is no ImageContainer, which means you're good to go to make a new image request.
There is an ImageContainer and the url that it is loading is the same as for the new row data. In this case you don't have to do anything, since it's already loading the image you're after.
There is an ImageContainer but the url that it is loading is different from the new row data. In this case, cancel the request and make a new one for the current row data.
If you like, you can move some of this logic by having your BaseAdapter extension implement AbsListView.RecyclerListener (and set the adapter as recycler listener for the ListView or GridView). The onMovedToScrapHeap(View view) method gets passed in the view that has just been recycled, which means you can cancel any pending image requests in there.
You don't need to enforce anything if you use the provided NetworkImageView.
NetworkImageView detects when it has been recycled and cancels the request automatically.
I don't know this API but my guess is that you should cancel any pending request before recycling such a view. How you can do that I can't say.
Did you here of alternatives like :
picasso ?
robospice UI Module ?
I'm doing a listview in Android that takes the date from a json with some information, I want to know the fastest way to create a new activity with all the data of one item.
What is more efficiently pass and id of the item in the intent and make a new request in the new activity or pass all the data of the new activity in the intent?
I guess that make two requests is worse than make one and pass the data in the intent, but maybe this information is too big to pass in the intent.putextra();
Thank you!
If you have the same information in the Listview that you'll have in the activity, then passing that info should be faster than making another request.
Nevertheless, if you only show a small piece of info in your ListView (which will also make it smoother) and then you show the full item when an element is clicked, then the first aproach is better.
Example:
I have a list with my contacts names and when i select one, i open a new activity requesting and showing all data of that contact.
This will be faster than have all unused info in my ListView.