How to display all images in drawable res folder in a Recycler View (Grid Layout)? What if there are hundereds of them?
I tried the regular method and it worked but I had only 5 images then. How to do the same for 100 images, it is a lot of work.
recyclerView.setLayoutManager(new GridLayoutManager(this, numberOfColumns));
and to view image you have to use Picasso in your recycler adapter
You could try creating a drawbles array that would store all your images, then using a loop to display all of them.
Drawble [] drawables = new Drawable[]{ContextCompat.getDrawable(getActivity(), R.drawable.digit00),ContextCompat.getDrawable(getActivity(),R.drawable.digit01),ContextCompat.getDrawable(getActivity(), R.drawable.digit02));
You can also use a loop to print out what you will put in the drawable array, so you can save on typing.
For example create a loop that prints 'ContextCompat.getDrawable(getActivity(), R.drawable.digit' + int')' to the logcat (the int is an int that will be incremented each time, this is why i said to name your drawables with a number at the end, like digit00 - digit99). Then you can just copy all that into your real code.
Related
I have to display posts from a json feed inside a RecyclerView and I have a layout for how a single row looks inside the RecyclerView as follows
I have not yet implemented the bottom part in my actual layout which contains the red and green boxes from the figure above and my layout looks like this
I am also implementing Swipe to delete with undo which as you know requires a FrameLayout as the root , and 2 nodes under it, one showing the normal area and one showing the layout which is revealed on swipe. In my case, when I swipe the item, this is what you will see.
Now the problem is, there are 13 views per row and I don't like the odds of that, I will be displaying a maximum of 100 items in the RecyclerView at a given time and as you see it would lead to a large number of Views.
I have certain approaches in mind to make a custom View to reduce the number of Views in the row. What would be the best way according to you to optimise this View or should I say, reduce the number of Views per row in the RecyclerView. I get all the data from JSON and the central text area needs to be expandable in nature with a Read More or Read Less depending on its state.
Approach 1
Slight simplification
In this approach, I will combine the person's profile picture at the top left, the TextView with the name and updated time into a single Custom View, in other words, it will extend from View, have its own canvas for drawing the Bitmap, the Strings but I'll have to manually code RTL and LTR and other items using a StaticLayout in Android. I need the central text area to be expandable in nature so I will stick with one of the Expandable Views everyone keeps mentioning on stackoverflow.
Approach 2
Highly modular Custom UI component.
The entire diagram composed of the user's image, text with name, time, central text and image can be made into a single CustomView, I am not sure how I can make this expandable yet because a StaticLayout once initialised in Android cannot be modified. What do you think? Is this the correct approach to go? I will end up having only 4 children per row if I make the entire thing a single View. Is that a valid use case for custom Views?
Well, I found the answer myself. There are two types of post items I am dealing with, ones that contain an ImageView to display a 16:9 post image and the ones that don't. My RecyclerView was lagging heavily in the scroll operation till now since I had a single layout file which had an ImageView with its width set to match_parent and height set to wrap_content. When I was scrolling, the posts with Images were using Glide to load images and were calling requestLayout() since the size of those items were changing. This was resulting in too many requestLayout() calls causing the heavy lag while scrolling.
How did I fix this?
I made an Adapter which was sectioned having 2 types of rows.
#Override
public int getItemViewType(int position) {
if (mResults != null) {
return mResults.get(position).getPicture() != null ? IMAGE : NO_IMAGE;
}
return NO_IMAGE;
}
Based on whether the result at the current position contains an Image in the post or not, I had my onCreateViewHolder method modified to set a predefined size for the ImageView incase my item had a post image.
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == IMAGE) {
view = mLayoutInflater.inflate(R.layout.row_post_image, parent, false);
RowImageHolder holder = new RowImageHolder(view);
//To set the width and height of the ImageView of our image in the post, we get its LayoutParams and adjust its width and height to maintain 16:9 ratio
ViewGroup.LayoutParams params = holder.mPostPicture.getLayoutParams();
params.width = mPostImageWidth;
params.height = mPostImageHeight;
holder.mPostPicture.setLayoutParams(params);
return holder;
} else {
view = mLayoutInflater.inflate(R.layout.row_post_image, parent, false);
RowNoImageHolder holder = new RowNoImageHolder(view);
return holder;
}
}
And thats all which needs to be done. The onBindViewHolder sets an image if the type of the item supports an image. The benefit is that space is reserved in advance for those items that have images and the performance of the RecyclerView on scroll improves tremendously. I achieved this without using any custom views so far :)
I have a grid layout where the number of rows and columns in it varies depending on the value of an int that is parsed to the activity. I'm now trying to randomly put one of the 12 images I have into each of the grid spaces to get a random mix of images in a square on the screen. So how do I put drawables into grid spaces without using xml and would a table layout be better? I will also need to be able to detect what image is in the grid space when it is clicked on.
I had the same problem while implementing a memory game some time ago.
To get a drawable object you first need to get your app resources.
Resources res = getResources();
Then, what I do for generate the random position is to put all my images in an ArrayList that has the number of elements equal to the number of grids your have:
ArrayList<Drawable> imagesArray = new ArrayList<Drawable>();
imagesArray.add(res.getDrawable(R.drawable.yourdrawablename));
imagesArray.add(res.getDrawable(R.drawable.yourdrawable2name));
//and so on for the following drawables you have.
After that, you could generate a random number using your ArrayList's size, that is the same amount of images you have, and after that, you put the images on your grid and remove it from the array.
for(int i = 0 ; i < imagesArray.size() ; i++) {
int randomPosition = Random.nextInt(imagesArray.size());
//here's the code to put your drawable in your grid view, in my case, it was just a button
//background, so I didn't know exactly how to put it inside a position of the grid, but it
//should not be that difficult to get it from documentation
//In my case, I do:
button.setBackground(imagesArray.get(randomPosition));
//And then delete that position on the array...
imagesArray.remove(randomPosition);
//And repeat until array's length is null;
}
For the last question, for discovering witch drawable is in which grid, you could get the constantState of it like this:
gridViewElement.getBackground();
This will return the background as a drawable that is associated with that gridView.
Also, be aware that if you want to compare to drawables inside two differente grids, you should use this:
if(gridViewElement1.getBackground().getConstantState()
.equals(gridViewElement2.getBackground().getConstantState())) {
//code goes here.
}
i.setLayoutParams(new GridView.LayoutParams(iwidth , iheight ));
i.setImageBitmap(duplicate.get(arg0));
i.setPadding(1, 1, 1, 1);
I am using the above to provide spaces actually i'm splitting an image and using gridview for placing the splitted images in gridview allowing the user to play picture puzzle in grid view but the splitted images are not fitted exactly in grid view the moddle row images are shrink and the right side images are enlarged one more issue is spacing between them ,it is providing spaces as from one row to next row but it's not providing spaces column to column can any one help me
I just looked at the docs and there's a setVerticalSpacing() and a setHorizontalSpacing() methods. Check them out.
So instead of setting the spacing in the ImageView, you can set it at the grid level.
I create one simple image banner apps in which I use the viewflipper for swipe image one by one. My apps run very well but the first image is repeated two time. Here I use the image array and apply in view flipper.
The Array is:
int imageDrawable[] = new int[]{R.drawable.advanturestorybanner_ipad_landscap,
R.drawable.femouspeopleofthebiblebanner_ipad_landscap,
R.drawable.littlebanner_ipad_landscap,
R.drawable.thechildrenbiblebanner_ipad_landscap,
R.drawable.thecomicbookbiblebanner_ipad_landscap,
R.drawable.thehandybiblebanner_ipad_landscap };
bannerImageView.setBackgroundResource(imageDrawable[j]);
I have a 2D array of ImageViews and am currently displaying each of them in a tableLayout. If I wanted to switch the ImageViews, I think that I need to swap the bitmaps that each [i][j] imageViews are assigned to. For example, if I wanted to swap positions of the images at [0][0] and [0][1], how would I do this?
I have a feeling that I would need to reassign each underlying bitmap to the appropriate imageview.
You could try getting the Drawable, on the imageviews and save it to variables:
Drawable d1 = imageViews[0][0].getDrawable();
Drawable d2 = imageViews[0][1].getDrawable();
Then you swap the drawables by:
imageViews[0][0].setImageDrawable(d2);
imageViews[0][1].setImageDrawable(d1);
I think that will switch the images of the views, or do you actually need to move the positions of the imageviews?