Consider the code below:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = (ImageView) convertView; //here
if (imageView == null) {
imageView = (ImageView) inflater.inflate(R.layout.item_gallery_image, parent, false);
}
ImageLoader.getInstance().displayImage(IMAGE_URLS[position], imageView, options);
return imageView;
}
Findbugs plugin from Android Studio is complaining about the first line from the method getview, it says:
Unchecked/unconfirmed cast
This cast is unchecked, and not all instances of the type casted from can be cast to the type it is being cast to. Check that your program logic ensures that this cast will not fail.
Any ideas of how do I resolve this issue?
If you want to please FindBugs you can assert that convertView is an ImageView.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_gallery_image, parent, false);
}
assert convertView instanceof ImageView : convertView;
ImageLoader.getInstance().displayImage(IMAGE_URLS[position], (ImageView) imageView, options);
return imageView;
}
Not every View is an ImageView, so FindBugs is trying to warn you that the cast may result in a ClassCastException.
However, you actually can't get a ClassCastException because the way convertView works is that you either recieve null or you receive a View previously returned by the getView() method. Since your method always returns an ImageView, everything is fine.
FindBugs finds potential problems with your code, and sometimes they are actually not problems at all.
i think you try to fill every row of a listView or recycle view with image...first you should make layout that contains an image view then you can do it in this way:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
view=inflater.inflate(R.layout.adapter_row,parent,false);
ImageView mImage=(ImageView) view.findViewById(R.id.imageid);
ImageLoader.getInstance().displayImage(IMAGE_URLS[position], mImage, options);
return view;
}
Related
Why do we need to :-
Create a View x.
Then set x = a
Then use a if command on x if you can directly use a.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// check if the current view is reused else inflate the view
View listItemView = convertView;
if(listItemView == null){
listItemView = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
}
Instead , Why can't we do this?
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
}
First and second examples are valid. Only if first case you are creating an local copy of your class variable. It is useless. Why are developers doing this way? Who knows :)
About inflating. Inflate operations some expensive, cause your adapter items are simular, it is possible to inflate view only once.
The second option also works perfectly. I don't know why you think you can't do that.
Just make sure you return convertView after doing other stuffs inside there.
As the develeoper in some cases wanted to assign a value LayoutInflater.from(...).inflate(...), different from the argument convertView, he chose not to overwrite the argument, but to introduce a new variable. It's good style not to modify method arguments.
So, in the case that convertView is null, listItemView gets a value from the LayoutInflater call, to be used further down the method. And the fact that the method was called with a null argument is still visible.
As a more concise alternative, this can be done using Java's ternary operator:
View listItemView = convertView != null ?
convertView :
LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
This way the variable can even be declared final.
I am developing an app that show all album cover images of the songs. So I am using glide for loading and caching images and to avoid OutofMemoryError but I still get that error:
11-11 11:05:55.866 11120-11120/com.xrobot.andrew.musicalbumsE/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.xrobot.andrew.musicalbums, PID: 11120 java.lang.OutOfMemoryError: OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack trace available
This is my getView in the AlbumAdapter:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
RelativeLayout albumsLay = (RelativeLayout)songInf.inflate
(R.layout.album_layout, parent, false);
ImageView coverView = (ImageView)albumsLay.findViewById(R.id.song_cover);
//get song using position
Song currSong = songs.get(position);
if (Drawable.createFromPath(currSong.getCover()) != null) {
Drawable img = Drawable.createFromPath(currSong.getCover());
Glide.with(mContext).load("").placeholder(img).override(50,50).into(coverView);
}
albumsLay.setTag(position);
return albumsLay;
}
Try using Glide directly with the image path:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
RelativeLayout albumsLay = (RelativeLayout)songInf.inflate
(R.layout.album_layout, parent, false);
ImageView coverView = (ImageView)albumsLay.findViewById(R.id.song_cover);
//get song using position
Song currSong = songs.get(position);
// If you are sure currSong.getCover() exists you can remove the if statement
if(new File(currSong.getCover().exists))
Glide.with(mContext).load(currSong.getCover()).override(50,50).into(coverView);
albumsLay.setTag(position);
return albumsLay;
}
And you could also use a holder for the view. This would reduce the memory usage:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
CoverHolder holder = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.album_layout, null);
holder = new CoverHolder();
holder.coverView = (ImageView)convertView.findViewById(R.id.song_cover);
convertView.setTag(holder);
} else {
holder = (CoverHolder)convertView.getTag();
}
Glide.with(mContext).load(currSong.getCover()).override(50,50).into(holder.coverView);
return convertView;
}
// The holder
public static class CoverHolder{
public ImageView coverView;
}
Still, if you really need performance on a huge list. You can take a look at the RecyclerView here.
I am fighting for a week now with a "getGroupView(int listPosition, boolean isExpanded, View convertView, ViewGroup parent)" method.
I've found one key thing:
listPosition and convertView are NOT always related
#Override
public View getGroupView(int listPosition, boolean isExpanded, View convertView, ViewGroup parent) {
String listTitle = getGroup(listPosition).toString();
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list_group, null);
}
TextView listTitleTextView = (TextView) convertView.findViewById(R.id.listTitle);
Item item = (Item) getGroup(listPosition); //Returns item from ArrayList
// The part behind && should ensure that no wrong passes happen. But they do anyway.
if (item.AllFound() && item.toString(Item.BASE_TITLE_FORMAT).equals(listTitleTextView.getText())){
//listTitleTextView.setBackgroundColor(Color.GREEN);
convertView.setBackgroundColor(Color.GREEN);
}
listTitleTextView.setText(listTitle);
return convertView;
}
What is this:
Background color of convertView (or listTitleTextView) should change to GREEN if item at groupPosition returns TRUE from method AllFound()
A lot of times, the convertView gets colored even though it should not.
But that's just my gibberish. I am willing to rewrite the whole thing.
So how to change (title) view of ExpandableList depending on Object that has created it? (Obviously you cannot depend on listPosition so how should I retrieve the correct object?)
the convertView will be reused, consider all situation
if (item.AllFound() && item.toString(Item.BASE_TITLE_FORMAT).equals(listTitleTextView.getText())){
//listTitleTextView.setBackgroundColor(Color.GREEN);
convertView.setBackgroundColor(Color.GREEN);
} else{
**Add code here to set backgroundColor**
}
I am using ListView with alternate rows colored. But when the ListView exceeds the length of the screen, on scrolling, the alternate color disappears.
Below is my code:
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getActivity().getLayoutInflater()
.inflate(R.layout.problem_list_row, null);
if(position%2!=0) {
convertView.setBackgroundColor(Color.parseColor("#ebebeb"));
}
}
if(position%2!=0){
convertView.setBackgroundColor(Color.parseColor("#ebebeb"));
}
/* some code */
return convertView;
}
Attached below, the image of the ListView.
Try this code
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getActivity().getLayoutInflater()
.inflate(R.layout.problem_list_row, null);
}
if(position%2==0)
{
// SET EVEN POSITION COLOR
convertView.setBackgroundColor(Color.parseColor("#ebebeb"));
}
else
{
//SET ODD POSITION COLOR
}
/* some code */
return convertView;
}
I hope this helps you.
convertView is null if the entire ListView fits on the screen. However once you start scrolling, Views that move off the screen get passed to the getView() method as convertView. Sometimes the convertView received will be grey even though you want the View to be white. Your code doesn't deal with this case because it only colours Views grey, it never clears the background colour when it is no longer wanted. To solve this problem you need to set the colour both for odd and even positions.
This should work.
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getActivity().getLayoutInflater()
.inflate(R.layout.problem_list_row, null);
}
convertView.setBackgroundColor(Color.parseColor(position%2!=0 ? "#ebebeb" : "#ffffff"));
/* some code */
return convertView;
}
I would recommend you to use multiple views, so two .xml file in your case.
I did exactly the same thing you want in an article on my website: http://raverat.github.io/android-listview-multi-views/
Hope this will help!
Hi i'm having this kind of problem, when scrolling imageviews change their positions and
their background images. I saw other answers on this topic on this site, but non of them
helped me.
Like this once:
grid view scrolling issue
GridView scrolling problem on Android
GridView elements changes their place dynamically when scroll screen
and many others...but they don't solve my problem.
Important thing is that i don't use custom layout for gridview or gridview items(imageViews).I create them programmatically. This is very important to me so if someone know the answer pls help me...Thanks.
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView==null){
imageView = new ImageView(ctx);
} else {
imageView = (ImageView) convertView;
}
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
imageView.setBackgroundResource(tmp[position]);
imageView.setImageResource(blank);
return imageView;
}
Its a simple method. Adapters recycle each and every view while scrolling. So we just need to create the ones which are being re-used after the first time. Holders help to avoid expensive calls like findViewById and re-use the items by just getting the old ones and changing its properties.
One point you need to keep in mind is that we need to hold the images which are to be displayed in any one of the containers like array[] or List and reset each time before returning the view, or else it will display the previously last recycled view.
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_layout, null);
holder = new ViewHolder();
holder.cover = (ImageView) convertView
.findViewById(R.id.item_cover);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.cover.setBackgroundResource(tmp[position]);
return convertView ;
}
static class ViewHolder {
ImageView cover;
}
try this
class Holder {
ImageView imageView;
}
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if(holder.imageView==null){
holder=new Holder();
holder.imageView = new ImageView(ctx);
holder.imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
holder.imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
holder.imageView.setPadding(8, 8, 8, 8);
imageView.setTag(holder);
} else {
holder= (Holder) imageView.getTag();
}
holder.imageView.setBackgroundResource(tmp[position]);
holder.imageView.setImageResource(blank);
return imageView;
}