Pass image from Listview to a detail activity - android

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/

Related

How to create functionality as TikTok / Musical.ly for android app?

Screen 1: GridView
Screen 2: Detail Page
Task Achieve:
1) Load all the videos in gridview from the server.
2) User clicks at any position of gridview item.
3) Open and play the particular video in detail screen.
4) On vertical scroll play next or previous videos.
Current Implementation:
GridFragment {
ArrayList<VideoPostModel> videoPostList;
RecyclerView gridView;
onnItemClick() {
Intent intent = new Intent(this, DetailActivity.class);
intent.putExtra("data", videoPostList);
intent.putExtra("click_index", clickedIndex);
intent.putExtra("pagination_index", paginationIndex);
startActivity(intent);
}
}
DetailActivity {
VerticlaViewPager vertiCalViewPager;
ArrayList<VideoPostModel> videoPostList;
onCreate() {
videoPostList = getIntent().getParcelableArrayListExtra("data");
clickedIndex = getIntent().getIntExtra("clickindex", 0);
paginationIndex = getIntent().getIntExtra("pagination_index", 0);
VideoFragmentStatePagerAdapter viewPagerAdapter = new VideoFragmentStatePagerAdapter(videoPostList);
vertiCalViewPager.setAdapter(viewPagerAdapter);
}
}
Problem:
If videoPostList has more data(approx 100+ objects of VideoPostModel) while passing data from fragment to activity then app crashes, as there is a limitation of sending data with intent(https://stackoverflow.com/a/37054839/3598052).
Hacky Alternatives:
1) Static arraylist
2) Arraylist in Application class
Looking for the OPTIMAL and EFFICIENT solution to achieve above functionality.
Any suggestion, reference link or code in the direction of achieving this would be highly appreciated, and thanks in advance.
Update 1:
Another solution I found is passing data with enum, but as per comments I'm not sure about it's performance. Refrence: https://stackoverflow.com/a/14706456/3598052
I think you can write in an activity or use Arraylist in the application as you mentioned. Or it could be a library that recently appeared in the Android Jetpack. It is similar in nature to the Arraylist in application.
ViewModel objects that make it easier to manage and store data.
It lets you access data at different activities or fragments in an application. You try it and hope it will be useful to you
You have several options. I'll put my opinion here.
Static list
Enum
Singleton class with list
LiveData
Most easy would be making static list at activity or application level. Just make sure you are freeing up List memory after use by making it NULL.
Another solution I found is passing data with enum, but as per
comments I'm not sure about it's performance
There would be sure some differences in each of above approaches. But that would not be measurable difference, because each approach put List in memory, use it and then free up.
Looking for the OPTIMAL and EFFICIENT solution to achieve above
functionality.
Make static List, and make it NULL after use. will be most efficient and easy way.
You can make List NULL in onDestroy() of your Fragment.
You can use LiveData but I think it would be not a good idea to add LiveData library just for one use in app. Also you need to understand it first. So you can go with static list.
in Activity
showFragment();
ApplicationClass.list = myList;
In Fragment
onViewCreated(){
...
setAdapter(ApplicationClass.list);
...
}
onDestroy(){
ApplicationClass.list = null;
}
Important
It is never a good idea to pull all data at once from server. Please do pagination, which you app needs most, because there can be thousands of users online at one time.
So by that approach you will pass only few items to Fragment. then you will do pagination in Fragment.
This approach needs time to change flow a bit. But is most robust way in your case.
Edit
If you are already using pagination and still getting large data at one time, that's again an issue. Because pagination is used to escape these memory issues.
You can do 2 things as solution.
1. Ask for limited data at once, say 50-60 items per request.
2. You can map and remove unnecessary fields from your list when passing in intent.
I would prefer the first one.
I know I'm late but this will help some future visitor.
Add Pagination & transfer data with arraylist & clicked position to detail activity using intent & after, set the current position of clicked position.
like viewpager.setCurrentPosition(clickedPosition);

How to change textviews & imageviews of another activity in Android

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));`

Android Gallery objects obtained from network to Individual gallery object

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

Pass an Image from Activity to Adapter Class

I am trying to pass an Image from SingleItem activity to CartAdapter, but i am facing problem, while trying to pass an Item Image.
I want whenever user do click on Add to Cart button in SingleItem activity, need to send Item Image and Strings from SingleItem.java to CartAdapter.java
Note: Able to pass String but trying to pass an Item Image, I am missing some code onButtonClick in SingleItem.java
Like using below line i am getting value for Item Title
myTitle = txttitle.getText().toString();
Log.d(SingleItem.LOG_TAG, "Title :: " + myTitle);
but i don't know how to get an Item Image
myThumb = // here what i should need to write
See my code below:
SingleItem.java::
// below i need your help
myThumb = // here i want to write code to get Image,
// like above i have written code to get String
Instead of sending Bitmap, write the Bitmap to file system and send its location so that the other activity can read the Bitmap from that location.
Sending large data through intents could cause ANRs
Bitmap Class implements Parcelable so you can pass your Bitmap from one class to another class but i will not recommend this. In my experience in case of large Bitmaps, this could cause ANR in android, you can use Singleton Pattern for Interclass communication for heavy objects, if you are using Singleton make sure you read multithreading issues.
Use Hash Map. In hash map put bitmap with key and pass this hash map to the Adapter. And Get that hash map in adapter class.

How pass an image resource from my app to another?

I have 2 apps running, and I need to pass an image resource from the first app to the second.
The ImageView have a setImageURI(Uri) method, that I could use in the second app, but does not have a getUri() for me to use in the first.
Any idea how to do this?
-- update
looks like Content Providers can solve the problem. (studying)
The only way is to pass the data to the second Activity when you start it. If you check out the Intent API you can pass the Uri using one of the putExtra() methods, and in the onCreate for the new Activity you can retrieve the Uri using getStringExtra().
You can pass a (Bitmap)Drawable this way:
// sending side
BitmapDrawable bd = (BitmapDrawable)imageView.getDrawable();
intent.putExtra("img", bd);
// receiving side
Bitmap b = (Bitmap) intent.getParcelable("img");
imageView.setImageBitmap(b);

Categories

Resources