I am new to android and I'm trying to figure out how to create a gallery of ImageViews on an app.
I have a server running that serves the images to the app which download correctly into a Arraylist of ImageViews.
I just need to add all of these images to a grid view.
I know I need to use an adaptor but I don't know how.
This is the code I have in my activity (images is populated else where)
ArrayList<ImageView> images = new ArrayList<>();
GridView table = (GridView) findViewById(R.id.table);
table.setAdapter(new ImageAdaptor(this.getBaseContext(), images));
And this is my adaptor
public class ImageAdaptor extends BaseAdapter{
private Context context;
private ArrayList<ImageView> images;
public ImageAdaptor(Context context, ArrayList<ImageView> images){
this.context = context;
this.images = images;
}
public int getCount(){
return this.images.size();
}
public Object getItem(int position){
return this.images.get(position);
}
public long getItemId(int position){
return position;
}
public View getView(int position, View convertView, ViewGroup parent){
ImageView image;
if (convertView == null){
image = new ImageView(this.context);
image.setLayoutParams(new GridView.LayoutParams(115, 115));
image.setScaleType(ImageView.ScaleType.CENTER_CROP);
}else{
image = (ImageView) convertView;
}
return image;
}
}
First thing, you should not make the arraylist of views as it wont be efficient for reusing views. However if you still want to do that, then solution is ,
public View getView(int position, View convertView, ViewGroup parent){
return images.get(position);
}
Related
I have a custom adapter which is supposed to contain image buttons. However, I am bit confused on the implementation of the override for the getView() method. Since my image buttons are defined dynamically, I am able to recover an image button by using the code
#Override
public View getView(int i, View view, ViewGroup viewGroup){
ImageButton ibutton = (ImageButton) getItem(i);
How do I return its view? I have not specifically created an xml file for it since it is just an ImageButton (not in combination with anything else), but is it necessary to create an xml for it? Or is there a way to easily get the view from the imagebutton itself.
When I try this for getView(), the imagebutton is not clickable for some reason.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageButton imageButton = getItem(position);
return imageButton ;
}
Try to build you adapter something like this:
public class ImageButtonAdapter extends BaseAdapter {
private Context mContext;
// Constructor
public ImageButtonAdapter(Context c) {
mContext = c;
}
public int getCount() {
return listCount;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageButton for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageButton imageButton ;
if (convertView == null) {
imageButton = new ImageButton (mContext);
imageButton.setLayoutParams(lp);
}
else
{
imageButton = (ImageButton ) convertView;
}
imageButton.setBackgroundColor(Color.TRANSPARENT)
return imageButton ;
}
}
I'm not exactly sure what I'm missing, but I've been trying to get the most popular movie posters to display in a gridview from themoviedb API utilizing the Picasso library. Anyone know what I'm doing wrong?
Here's my ImageAdapter:
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return 20;
}
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.setScaleType(ImageView.ScaleType.CENTER_CROP);
Picasso.with(mContext).load("https://api.themoviedb.org/3/movie/popular?api_key={APIKEY_HERE}&poster_path&images").into(imageView);
} else {
imageView = (ImageView) convertView;
}
return imageView;
}
}
Above mentioned API will give popular movie list this..
results: [
{
poster_path: "/inVq3FRqcYIRl2la8iZikYYxFNR.jpg",
adult: false,
overview: "life.",
release_date: "2016-02-09",
backdrop_path: "/nbIrDhOtUpdD9HKDBRy02a8VhpV.jpg",
popularity: 91.92864,
vote_count: 3497,
video: false,
vote_average: 7.2
}
]
Extract poster_path of which movie image you want to display
Use the below URL to display image http://image.tmdb.org/t/p/w500/inVq3FRqcYIRl2la8iZikYYxFNR.jpg
You can find the document here http://docs.themoviedb.apiary.io/#reference/configuration/configuration
you have to check that url in picasso it returns the whole data not the image url, try to add the value of poster_path to the right url
I was following a NewBoston Tutorial (https://www.youtube.com/watch?v=nOdSARCVYic&list=PL6gx4Cwl9DGBsvRxJJOzG4r4k_zLKrnxl&index=48)
He showed how to put an image into a list but he never showed how to assign a different image to every piece of text.
Here is my MainActivity.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] Jobsites = {"River Park Place", "Mayfair", "Jameson House"};
ListAdapter jobsiteAdapter = new CustomAdapter(this, Jobsites);
ListView jobsiteListView = (ListView) findViewById(R.id.jobsiteListView);
jobsiteListView.setAdapter(jobsiteAdapter);
jobsiteListView.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String jobsite = String.valueOf(parent.getItemAtPosition(position));
//Toast.makeText(MainActivity.this, jobsite, Toast.LENGTH_LONG).show();
if (jobsite == "River Park Place"){
//Perform segue to the proper view where employess can sign in
//******************************************
System.out.println("*****************");
System.out.println("Attempting to segue");
System.out.println("*****************");
//******************************************
}else{
System.out.println("*****************");
System.out.println("These jobsites aren't avaliable yet!");
System.out.println("*****************");
Toast.makeText(MainActivity.this, "**These Sites aren't avaliable yet!**", Toast.LENGTH_LONG).show();
}
}
}
);
}
}
During the video we made a custom View that handles the images. Here is the code.
class CustomAdapter extends ArrayAdapter<String> {
public CustomAdapter(Context context, String[] jobsites) {
super(context,R.layout.custom_row ,jobsites);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater jobsiteInflater = LayoutInflater.from(getContext());
View customView = jobsiteInflater.inflate(R.layout.custom_row, parent, false);
String singleJobsiteItem = getItem(position);
ImageView josbiteImage = (ImageView) customView.findViewById(R.id.josbiteImage);
josbiteImage.setImageResource(R.drawable.riverparkplace);
return customView;
}
}
I have two other images that I want to add in for the bottom two items of text in the list. Right now it is just loading the SAME picture over and over again for all three rows in the list.
Let me guide you through this step by step. Before we continue, you need to understand that ArrayAdapter of your ListView populates each row with the data you specify to it. In other words, You would like to pass the image to the adapter just like you did with the Jobsites String array.
Define a simple wrapper object that contains your String (Jobsites) and the image you would like to assign to it.
public class SimpleObject {
private String jobSite;
private int imageID; // your R.drawable.image
public SimpleObject(String jobSite, int imageID) {
this.jobSite = jobSite;
this.imageID = imageID;
}
public String getJobSite() {
return jobSite;
}
public int getImageID() {
return imageID;
}
}
Initialise your SimpleObject array to be used by the adapter. In your onCreate() of the main activity, do the following:
ArrayList<SimpleObject> objectList = new ArrayList<>();
objectList.add(new SimpleObject("River Park Place", R.drawable.image1);
objectList.add(new SimpleObject("Mayfair", R.drawable.image2);
// the list goes on....
Now, change your CustomAdapter to hold the SimpleObject instead of String:
class CustomAdapter extends ArrayAdapter<SimpleObject> {
public CustomAdapter(Context context, ArrayList<SimpleObject> objectList) {
super(context,R.layout.custom_row ,objectList);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater jobsiteInflater = LayoutInflater.from(getContext());
View customView = jobsiteInflater.inflate(R.layout.custom_row, parent, false);
// Get the SimpleObject
SimpleObject item = (SimpleObject) getItem(position);
String singleJobsiteItem = item.getJobSite(); // get the String
ImageView josbiteImage = (ImageView) customView.findViewById(R.id.josbiteImage);
josbiteImage.setImageResource(item.getImageID()); // get the image ID and assign it to jobsiteImage :)
return customView;
}
}
Now make sure you initialise the adapter in your main activity with the new SimpleObject list:
ListAdapter jobsiteAdapter = new CustomAdapter(this, objectList);
You need to implement baseadapter because of the images
im new to android and java and i created a my own adapter and list view from a tutorial I was following online. I want to know how do i the image for each individual row because my adapter (from the tutorial) only has 1 image for all the rows. here is the code for my own adapter.
class HangarAdapter extends ArrayAdapter<String> {
public HangarAdapter(Context context, String[] values) {
super(context, R.layout.hangar_layout, values);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater theInflater = LayoutInflater.from(getContext());
View theView = theInflater.inflate(R.layout.hangar_layout, parent, false);
String ship = getItem(position);
TextView theTextView = (TextView) theView.findViewById(R.id.textView1);
theTextView.setText(ship);
ImageView theImageView = (ImageView) theView.findViewById(R.id.imageView);
theImageView.setImageResource(R.drawable.dot);
return theView;
}
}
theImageView.setImageResource(R.drawable.dot);
This line above is what you have to change in order to use a different images;
you could potentially do something like this;
if (position == 0){
theImageView.setImageResource(R.drawable.dot);
} else if (position == 1){
theImageView.setImageResource(R.drawable.circle);
}
It also depends on the backing data.
I am trying to implement a listview that displays a list of directories. and under each directory is a gridview with associated adapter (shown below) showing a list of image thumbnails (see below image). I have it working great except whenever the list item is off the screen then brought back on screen, the images are reloaded. I am using an asynctask to download the thumbnails and replace the placeholder image for each imageview so it is not acceptable that everytime an item is offscreen, all of its thumbnails are downloaded again. Does anyone have an example of this type of implementation (gridview adapter within a listview adapter) where the imageview (or images) are stored? What is the proper way to do this?
Thanks in advance for your help.
Gallery Adapter
public class GalleryAdapter extends BaseAdapter {
private Context mContext;
ArrayList<GalleryItem> GalleryList;
//MediaAdapter adapter;
public GalleryAdapter(Context c,ArrayList<GalleryItem> l) {
mContext = c;
GalleryList = l;
}
public int getCount() {
return GalleryList.size();
}
public Object getItem(int position) {
return GalleryList.get(position);
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
GalleryViewHolder viewHolder = null;
if(convertView==null){
// inflate the layout
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
convertView = inflater.inflate(R.layout.gallery_item, parent, false);
viewHolder = new GalleryViewHolder();
viewHolder.title = (TextView) convertView.findViewById(R.id.title);
viewHolder.folder_settings = (ImageView) convertView.findViewById(R.id.folder_settings);
viewHolder.mediaGrid = (GridView) convertView.findViewById(R.id.imagegrid);
viewHolder.gridHolder = (LinearLayout) convertView.findViewById(R.id.gridholder);
convertView.setTag(viewHolder);
}
else{
viewHolder = (GalleryViewHolder) convertView.getTag();
}
viewHolder.title.setText(GalleryList.get(position).getTitle());
//Formatting the gridView to fit the screen dim.
ImageTools mWidth = new ImageTools(mContext);
viewHolder.mediaGrid.setColumnWidth(mWidth.imageSize());
int rows = (int) Math.ceil((GalleryList.get(position).getMedia().size() / mWidth.columnNumber)+1);
LinearLayout.LayoutParams labelLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, mWidth.imageSize()*rows);
viewHolder.gridHolder.setLayoutParams(labelLayoutParams);
viewHolder.mediaGrid.setLayoutParams(labelLayoutParams);
viewHolder.mediaGrid.setMinimumHeight(mWidth.imageSize()*rows);
//Set Adapter for image views
viewHolder.mediaGrid.setAdapter(new MediaAdapter(convertView.getContext(),GalleryList.get(position).getMedia()));
viewHolder.folder_settings.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Dialogs.createListDialog(mContext,"Folder Actions", R.array.gallery_action_array).show();
}
});
viewHolder.mediaGrid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
}
});
return convertView;
}
private class GalleryViewHolder {
private TextView title;
private ArrayList<ImageView> imageList;
private GridView mediaGrid;
private ImageView folder_settings;
private LinearLayout gridHolder;
private int position;
}
}
Media Adapter
public class MediaAdapter extends BaseAdapter {
private Context mContext;
ArrayList<MediaItem> mediaitems;
public MediaAdapter(Context c,ArrayList<MediaItem> l) {
mContext = c;
mediaitems = l;
}
public int getCount() {
return mediaitems.size();
}
public Object getItem(int position) {
return mediaitems.get(position);
}
public long getItemId(int position) {
return 0;
}
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.setImageResource(R.drawable.loading);
imageView.setTag(R.integer.path,mediaitems.get(position).getPath().toString());
imageView.setTag(R.integer.fullsize,"false");
imageView.setTag(R.integer.parentpath,mediaitems.get(position).getParentPath().toString());
imageView.setTag(R.integer.index , String.valueOf(position));
try {
new thumbDownload(mContext).execute(imageView);
} catch (DbxException e) {
e.printStackTrace();
}
ImageTools mWidth = new ImageTools(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(mWidth.imageSize(), mWidth.imageSize()));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
} else {
imageView = (ImageView) convertView;
}
//imageView.setImageBitmap(mediaitems.get(position).getBitmap());
return imageView;
}
}
Try with this..may be its silly way, but its worked for me. Just add a line of code inside your method like this for gallery adapter:
public View getView(int position, View convertView, ViewGroup parent) {
GalleryViewHolder viewHolder = null;
// Add this line.
convertView = null;
if(convertView==null){
// inflate the layout
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
convertView = inflater.inflate(R.layout.gallery_item, parent, false);
viewHolder = new GalleryViewHolder();
viewHolder.title = (TextView) convertView.findViewById(R.id.title);
viewHolder.folder_settings = (ImageView) convertView.findViewById(R.id.folder_settings);
viewHolder.mediaGrid = (GridView) convertView.findViewById(R.id.imagegrid);
viewHolder.gridHolder = (LinearLayout) convertView.findViewById(R.id.gridholder);
convertView.setTag(viewHolder);
}
else{
viewHolder = (GalleryViewHolder) convertView.getTag();
}
// rest of your code
}
You can use StickyGridHeaders to implement your UI and Android-Universal-Image-Loader for flexible asynchronous image loading.
StickyGridHeaders is an Android library that provides a GridView that shows items in sections with headers. By default the section headers stick to the top like the People app in Android 4.x but this can be turned off.
Android-Universal-Image-Loader aims to provide a reusable instrument for asynchronous image loading, caching and displaying.
I ended up Using a HashMap<String,Bitmap> to store the images once they were downloaded. I made the hashMap static in my mediaAdapter so I could add the bitmap from my asynctask when it was downloaded. Then in my media Adapter getView(), I added a if statement to check if the image had already been downloaded. If it had, I used setImageBitmap(myHash.get(key)).