Android Studio - Help me to understand this code
up vote
0
down vote
favorite
Im trying to understand this code:
private class ViewHolder {
TextView txtName, txtSinger;
ImageView playB, stopB;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
final ViewHolder viewHolder;
if (view == null) {
viewHolder = new ViewHolder();
// inflate (create) another copy of our custom layout
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(layout, null);
viewHolder.txtName = (TextView) view.findViewById(R.id.songName_text);
viewHolder.txtSinger = (TextView) view.findViewById(R.id.singer_text);
viewHolder.playB = (ImageView) view.findViewById(R.id.play_png);
viewHolder.stopB = (ImageView) view.findViewById(R.id.stop_png);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
final Song song = arrayList.get(position);
// make changes to our custom layout and its subviews
viewHolder.txtName.setText(song.getName());
viewHolder.txtSinger.setText(song.getSinger());
// play music
viewHolder.playB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// MediaPlayer has not been initialized OR clicked song is not the currently loaded song
if (currentSong == null || song != currentSong) {
// Sets the currently loaded song
currentSong = song;
mediaPlayer = MediaPlayer.create(context, song.getSong());
Toast.makeText(context, "Playing: "+ song.getSinger() + " " + song.getName(), Toast.LENGTH_LONG).show();
}
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
viewHolder.playB.setImageResource(R.drawable.play);
} else {
mediaPlayer.start();
viewHolder.playB.setImageResource(R.drawable.pause);
}
}
});
// stop
viewHolder.stopB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// If currently loaded song is set the MediaPlayer must be initialized
if (currentSong != null) {
mediaPlayer.stop();
mediaPlayer.release();
currentSong = null; // Set back currently loaded song
}
viewHolder.playB.setImageResource(R.drawable.play);
}
});
return view;
}
But not the whole code!
The part that is confusing me is the ViewHolder part.
My questions:
- Why do i have to create a
private classcalledViewHolderinstead
of just creating apublic methodto store all my views (txtName,) and use that in my
txtSinger, playB, stopBinflater? - what does
view.setTag(viewHolder)means? - What is exactly
setTagandgetTagin this context?
If anyone can break this down for me it would be very helpful to progress my understanding of code.
Thank you.
java
add a comment |
up vote
0
down vote
favorite
Im trying to understand this code:
private class ViewHolder {
TextView txtName, txtSinger;
ImageView playB, stopB;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
final ViewHolder viewHolder;
if (view == null) {
viewHolder = new ViewHolder();
// inflate (create) another copy of our custom layout
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(layout, null);
viewHolder.txtName = (TextView) view.findViewById(R.id.songName_text);
viewHolder.txtSinger = (TextView) view.findViewById(R.id.singer_text);
viewHolder.playB = (ImageView) view.findViewById(R.id.play_png);
viewHolder.stopB = (ImageView) view.findViewById(R.id.stop_png);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
final Song song = arrayList.get(position);
// make changes to our custom layout and its subviews
viewHolder.txtName.setText(song.getName());
viewHolder.txtSinger.setText(song.getSinger());
// play music
viewHolder.playB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// MediaPlayer has not been initialized OR clicked song is not the currently loaded song
if (currentSong == null || song != currentSong) {
// Sets the currently loaded song
currentSong = song;
mediaPlayer = MediaPlayer.create(context, song.getSong());
Toast.makeText(context, "Playing: "+ song.getSinger() + " " + song.getName(), Toast.LENGTH_LONG).show();
}
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
viewHolder.playB.setImageResource(R.drawable.play);
} else {
mediaPlayer.start();
viewHolder.playB.setImageResource(R.drawable.pause);
}
}
});
// stop
viewHolder.stopB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// If currently loaded song is set the MediaPlayer must be initialized
if (currentSong != null) {
mediaPlayer.stop();
mediaPlayer.release();
currentSong = null; // Set back currently loaded song
}
viewHolder.playB.setImageResource(R.drawable.play);
}
});
return view;
}
But not the whole code!
The part that is confusing me is the ViewHolder part.
My questions:
- Why do i have to create a
private classcalledViewHolderinstead
of just creating apublic methodto store all my views (txtName,) and use that in my
txtSinger, playB, stopBinflater? - what does
view.setTag(viewHolder)means? - What is exactly
setTagandgetTagin this context?
If anyone can break this down for me it would be very helpful to progress my understanding of code.
Thank you.
java
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
Im trying to understand this code:
private class ViewHolder {
TextView txtName, txtSinger;
ImageView playB, stopB;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
final ViewHolder viewHolder;
if (view == null) {
viewHolder = new ViewHolder();
// inflate (create) another copy of our custom layout
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(layout, null);
viewHolder.txtName = (TextView) view.findViewById(R.id.songName_text);
viewHolder.txtSinger = (TextView) view.findViewById(R.id.singer_text);
viewHolder.playB = (ImageView) view.findViewById(R.id.play_png);
viewHolder.stopB = (ImageView) view.findViewById(R.id.stop_png);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
final Song song = arrayList.get(position);
// make changes to our custom layout and its subviews
viewHolder.txtName.setText(song.getName());
viewHolder.txtSinger.setText(song.getSinger());
// play music
viewHolder.playB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// MediaPlayer has not been initialized OR clicked song is not the currently loaded song
if (currentSong == null || song != currentSong) {
// Sets the currently loaded song
currentSong = song;
mediaPlayer = MediaPlayer.create(context, song.getSong());
Toast.makeText(context, "Playing: "+ song.getSinger() + " " + song.getName(), Toast.LENGTH_LONG).show();
}
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
viewHolder.playB.setImageResource(R.drawable.play);
} else {
mediaPlayer.start();
viewHolder.playB.setImageResource(R.drawable.pause);
}
}
});
// stop
viewHolder.stopB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// If currently loaded song is set the MediaPlayer must be initialized
if (currentSong != null) {
mediaPlayer.stop();
mediaPlayer.release();
currentSong = null; // Set back currently loaded song
}
viewHolder.playB.setImageResource(R.drawable.play);
}
});
return view;
}
But not the whole code!
The part that is confusing me is the ViewHolder part.
My questions:
- Why do i have to create a
private classcalledViewHolderinstead
of just creating apublic methodto store all my views (txtName,) and use that in my
txtSinger, playB, stopBinflater? - what does
view.setTag(viewHolder)means? - What is exactly
setTagandgetTagin this context?
If anyone can break this down for me it would be very helpful to progress my understanding of code.
Thank you.
java
Im trying to understand this code:
private class ViewHolder {
TextView txtName, txtSinger;
ImageView playB, stopB;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
final ViewHolder viewHolder;
if (view == null) {
viewHolder = new ViewHolder();
// inflate (create) another copy of our custom layout
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(layout, null);
viewHolder.txtName = (TextView) view.findViewById(R.id.songName_text);
viewHolder.txtSinger = (TextView) view.findViewById(R.id.singer_text);
viewHolder.playB = (ImageView) view.findViewById(R.id.play_png);
viewHolder.stopB = (ImageView) view.findViewById(R.id.stop_png);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
final Song song = arrayList.get(position);
// make changes to our custom layout and its subviews
viewHolder.txtName.setText(song.getName());
viewHolder.txtSinger.setText(song.getSinger());
// play music
viewHolder.playB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// MediaPlayer has not been initialized OR clicked song is not the currently loaded song
if (currentSong == null || song != currentSong) {
// Sets the currently loaded song
currentSong = song;
mediaPlayer = MediaPlayer.create(context, song.getSong());
Toast.makeText(context, "Playing: "+ song.getSinger() + " " + song.getName(), Toast.LENGTH_LONG).show();
}
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
viewHolder.playB.setImageResource(R.drawable.play);
} else {
mediaPlayer.start();
viewHolder.playB.setImageResource(R.drawable.pause);
}
}
});
// stop
viewHolder.stopB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// If currently loaded song is set the MediaPlayer must be initialized
if (currentSong != null) {
mediaPlayer.stop();
mediaPlayer.release();
currentSong = null; // Set back currently loaded song
}
viewHolder.playB.setImageResource(R.drawable.play);
}
});
return view;
}
But not the whole code!
The part that is confusing me is the ViewHolder part.
My questions:
- Why do i have to create a
private classcalledViewHolderinstead
of just creating apublic methodto store all my views (txtName,) and use that in my
txtSinger, playB, stopBinflater? - what does
view.setTag(viewHolder)means? - What is exactly
setTagandgetTagin this context?
If anyone can break this down for me it would be very helpful to progress my understanding of code.
Thank you.
java
java
asked Nov 9 at 22:39
Delice
236
236
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
1
down vote
accepted
What is exactly setTag and getTag in this context?
Android views support "tags", which are arbitrary objects you can attach to them. There's no real definition for tags, because they're whatever you want them to be. All of these are equally valid:
view.setTag(2)view.setTag("Hello world")view.setTag(new Object())
what does view.setTag(viewHolder) means?
You're attaching the viewHolder object to view as its tag. This doesn't do anything by itself, but it lets you retrieve the viewHolder later on by calling (ViewHolder) view.getTag().
Why do i have to create a private class called ViewHolder [...]
When you're working with ListView adapters, there are two things that can slow the performance of your app way down: calling inflate() and calling findViewById().
You get around the first by using the passed-in view argument when it's not null, and only calling inflate() when the passed in view argument is null. That's this bit of your code:
if (view == null) {
...
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(layout, null);
...
} else {
...
}
You get around the second by using this "ViewHolder pattern". You create an object (the view holder) to "hold" the views after you look them up. That's this bit of your code:
final ViewHolder viewHolder;
if (view == null) {
viewHolder = new ViewHolder();
...
viewHolder.txtName = (TextView) view.findViewById(R.id.songName_text);
viewHolder.txtSinger = (TextView) view.findViewById(R.id.singer_text);
viewHolder.playB = (ImageView) view.findViewById(R.id.play_png);
viewHolder.stopB = (ImageView) view.findViewById(R.id.stop_png);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
Once that block is done, you'll have a ViewHolder instance named viewHolder that you can use to access views directly. When the passed-in view argument is null, you create the view holder, populate it by calling findViewById(), and save it by calling setTag(). When the passed-in view argument is not null, you can simply retrieve the view holder by calling getTag().
Put that all together, and that means you can write code like this:
viewHolder.txtName.setText(song.getName());
Instead of this slower code:
TextView txtName = view.findViewById(R.id.songName_text);
txtName.setText(song.getName());
I have a question regarding the 3th question you answered "Why do i have to create a private class called ViewHolder [...]" --> Why does it have to be aclass? is it possible to make it apublic method?
– Delice
Nov 9 at 23:35
Why do you want it to be a method? But, short answer, no. You can only pass objects tosetTag(), so you have to define a class for your view holder.
– Ben P.
Nov 9 at 23:42
I've had an older project where i made a public method calledmyViews()that i used in myonCreatemethod in anif-statement.. so i just wondered why i had to useclassthis time.
– Delice
Nov 9 at 23:54
1
I think the major difference here is that, when you have just one Activity, you can use a method to organize all of yourfindViewById()calls... but in this case you have a different view holder for every row, so you need many different "groups" offindViewById()calls. A view holder object/class is the best way to do that.
– Ben P.
Nov 10 at 3:24
Ok thanks I think i got it now!
– Delice
Nov 10 at 13:36
add a comment |
up vote
1
down vote
A viewholder is a design pattern used in android apps in order to replace the more expensive findviewbyid calls.
Quoting docs
Your code might call findViewById() frequently during the scrolling of ListView, which can slow down performance. Even when the Adapter returns an inflated view for recycling, you still need to look up the elements and update them. A way around repeated use of findViewById() is to use the "view holder" design pattern.
Regarding the second and third question the settag and gettag is basically a way for your view to have "memories" you can refer here for further information and a more detailed explanation!
Hope this helps!
Thank you for your input! I think i almost understood everything. I just need to verify one last question and i put that into Ben P. answer.
– Delice
Nov 9 at 23:36
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53234158%2fandroid-studio-help-me-to-understand-this-code%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
What is exactly setTag and getTag in this context?
Android views support "tags", which are arbitrary objects you can attach to them. There's no real definition for tags, because they're whatever you want them to be. All of these are equally valid:
view.setTag(2)view.setTag("Hello world")view.setTag(new Object())
what does view.setTag(viewHolder) means?
You're attaching the viewHolder object to view as its tag. This doesn't do anything by itself, but it lets you retrieve the viewHolder later on by calling (ViewHolder) view.getTag().
Why do i have to create a private class called ViewHolder [...]
When you're working with ListView adapters, there are two things that can slow the performance of your app way down: calling inflate() and calling findViewById().
You get around the first by using the passed-in view argument when it's not null, and only calling inflate() when the passed in view argument is null. That's this bit of your code:
if (view == null) {
...
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(layout, null);
...
} else {
...
}
You get around the second by using this "ViewHolder pattern". You create an object (the view holder) to "hold" the views after you look them up. That's this bit of your code:
final ViewHolder viewHolder;
if (view == null) {
viewHolder = new ViewHolder();
...
viewHolder.txtName = (TextView) view.findViewById(R.id.songName_text);
viewHolder.txtSinger = (TextView) view.findViewById(R.id.singer_text);
viewHolder.playB = (ImageView) view.findViewById(R.id.play_png);
viewHolder.stopB = (ImageView) view.findViewById(R.id.stop_png);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
Once that block is done, you'll have a ViewHolder instance named viewHolder that you can use to access views directly. When the passed-in view argument is null, you create the view holder, populate it by calling findViewById(), and save it by calling setTag(). When the passed-in view argument is not null, you can simply retrieve the view holder by calling getTag().
Put that all together, and that means you can write code like this:
viewHolder.txtName.setText(song.getName());
Instead of this slower code:
TextView txtName = view.findViewById(R.id.songName_text);
txtName.setText(song.getName());
I have a question regarding the 3th question you answered "Why do i have to create a private class called ViewHolder [...]" --> Why does it have to be aclass? is it possible to make it apublic method?
– Delice
Nov 9 at 23:35
Why do you want it to be a method? But, short answer, no. You can only pass objects tosetTag(), so you have to define a class for your view holder.
– Ben P.
Nov 9 at 23:42
I've had an older project where i made a public method calledmyViews()that i used in myonCreatemethod in anif-statement.. so i just wondered why i had to useclassthis time.
– Delice
Nov 9 at 23:54
1
I think the major difference here is that, when you have just one Activity, you can use a method to organize all of yourfindViewById()calls... but in this case you have a different view holder for every row, so you need many different "groups" offindViewById()calls. A view holder object/class is the best way to do that.
– Ben P.
Nov 10 at 3:24
Ok thanks I think i got it now!
– Delice
Nov 10 at 13:36
add a comment |
up vote
1
down vote
accepted
What is exactly setTag and getTag in this context?
Android views support "tags", which are arbitrary objects you can attach to them. There's no real definition for tags, because they're whatever you want them to be. All of these are equally valid:
view.setTag(2)view.setTag("Hello world")view.setTag(new Object())
what does view.setTag(viewHolder) means?
You're attaching the viewHolder object to view as its tag. This doesn't do anything by itself, but it lets you retrieve the viewHolder later on by calling (ViewHolder) view.getTag().
Why do i have to create a private class called ViewHolder [...]
When you're working with ListView adapters, there are two things that can slow the performance of your app way down: calling inflate() and calling findViewById().
You get around the first by using the passed-in view argument when it's not null, and only calling inflate() when the passed in view argument is null. That's this bit of your code:
if (view == null) {
...
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(layout, null);
...
} else {
...
}
You get around the second by using this "ViewHolder pattern". You create an object (the view holder) to "hold" the views after you look them up. That's this bit of your code:
final ViewHolder viewHolder;
if (view == null) {
viewHolder = new ViewHolder();
...
viewHolder.txtName = (TextView) view.findViewById(R.id.songName_text);
viewHolder.txtSinger = (TextView) view.findViewById(R.id.singer_text);
viewHolder.playB = (ImageView) view.findViewById(R.id.play_png);
viewHolder.stopB = (ImageView) view.findViewById(R.id.stop_png);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
Once that block is done, you'll have a ViewHolder instance named viewHolder that you can use to access views directly. When the passed-in view argument is null, you create the view holder, populate it by calling findViewById(), and save it by calling setTag(). When the passed-in view argument is not null, you can simply retrieve the view holder by calling getTag().
Put that all together, and that means you can write code like this:
viewHolder.txtName.setText(song.getName());
Instead of this slower code:
TextView txtName = view.findViewById(R.id.songName_text);
txtName.setText(song.getName());
I have a question regarding the 3th question you answered "Why do i have to create a private class called ViewHolder [...]" --> Why does it have to be aclass? is it possible to make it apublic method?
– Delice
Nov 9 at 23:35
Why do you want it to be a method? But, short answer, no. You can only pass objects tosetTag(), so you have to define a class for your view holder.
– Ben P.
Nov 9 at 23:42
I've had an older project where i made a public method calledmyViews()that i used in myonCreatemethod in anif-statement.. so i just wondered why i had to useclassthis time.
– Delice
Nov 9 at 23:54
1
I think the major difference here is that, when you have just one Activity, you can use a method to organize all of yourfindViewById()calls... but in this case you have a different view holder for every row, so you need many different "groups" offindViewById()calls. A view holder object/class is the best way to do that.
– Ben P.
Nov 10 at 3:24
Ok thanks I think i got it now!
– Delice
Nov 10 at 13:36
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
What is exactly setTag and getTag in this context?
Android views support "tags", which are arbitrary objects you can attach to them. There's no real definition for tags, because they're whatever you want them to be. All of these are equally valid:
view.setTag(2)view.setTag("Hello world")view.setTag(new Object())
what does view.setTag(viewHolder) means?
You're attaching the viewHolder object to view as its tag. This doesn't do anything by itself, but it lets you retrieve the viewHolder later on by calling (ViewHolder) view.getTag().
Why do i have to create a private class called ViewHolder [...]
When you're working with ListView adapters, there are two things that can slow the performance of your app way down: calling inflate() and calling findViewById().
You get around the first by using the passed-in view argument when it's not null, and only calling inflate() when the passed in view argument is null. That's this bit of your code:
if (view == null) {
...
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(layout, null);
...
} else {
...
}
You get around the second by using this "ViewHolder pattern". You create an object (the view holder) to "hold" the views after you look them up. That's this bit of your code:
final ViewHolder viewHolder;
if (view == null) {
viewHolder = new ViewHolder();
...
viewHolder.txtName = (TextView) view.findViewById(R.id.songName_text);
viewHolder.txtSinger = (TextView) view.findViewById(R.id.singer_text);
viewHolder.playB = (ImageView) view.findViewById(R.id.play_png);
viewHolder.stopB = (ImageView) view.findViewById(R.id.stop_png);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
Once that block is done, you'll have a ViewHolder instance named viewHolder that you can use to access views directly. When the passed-in view argument is null, you create the view holder, populate it by calling findViewById(), and save it by calling setTag(). When the passed-in view argument is not null, you can simply retrieve the view holder by calling getTag().
Put that all together, and that means you can write code like this:
viewHolder.txtName.setText(song.getName());
Instead of this slower code:
TextView txtName = view.findViewById(R.id.songName_text);
txtName.setText(song.getName());
What is exactly setTag and getTag in this context?
Android views support "tags", which are arbitrary objects you can attach to them. There's no real definition for tags, because they're whatever you want them to be. All of these are equally valid:
view.setTag(2)view.setTag("Hello world")view.setTag(new Object())
what does view.setTag(viewHolder) means?
You're attaching the viewHolder object to view as its tag. This doesn't do anything by itself, but it lets you retrieve the viewHolder later on by calling (ViewHolder) view.getTag().
Why do i have to create a private class called ViewHolder [...]
When you're working with ListView adapters, there are two things that can slow the performance of your app way down: calling inflate() and calling findViewById().
You get around the first by using the passed-in view argument when it's not null, and only calling inflate() when the passed in view argument is null. That's this bit of your code:
if (view == null) {
...
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(layout, null);
...
} else {
...
}
You get around the second by using this "ViewHolder pattern". You create an object (the view holder) to "hold" the views after you look them up. That's this bit of your code:
final ViewHolder viewHolder;
if (view == null) {
viewHolder = new ViewHolder();
...
viewHolder.txtName = (TextView) view.findViewById(R.id.songName_text);
viewHolder.txtSinger = (TextView) view.findViewById(R.id.singer_text);
viewHolder.playB = (ImageView) view.findViewById(R.id.play_png);
viewHolder.stopB = (ImageView) view.findViewById(R.id.stop_png);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
Once that block is done, you'll have a ViewHolder instance named viewHolder that you can use to access views directly. When the passed-in view argument is null, you create the view holder, populate it by calling findViewById(), and save it by calling setTag(). When the passed-in view argument is not null, you can simply retrieve the view holder by calling getTag().
Put that all together, and that means you can write code like this:
viewHolder.txtName.setText(song.getName());
Instead of this slower code:
TextView txtName = view.findViewById(R.id.songName_text);
txtName.setText(song.getName());
answered Nov 9 at 22:49
Ben P.
22k31846
22k31846
I have a question regarding the 3th question you answered "Why do i have to create a private class called ViewHolder [...]" --> Why does it have to be aclass? is it possible to make it apublic method?
– Delice
Nov 9 at 23:35
Why do you want it to be a method? But, short answer, no. You can only pass objects tosetTag(), so you have to define a class for your view holder.
– Ben P.
Nov 9 at 23:42
I've had an older project where i made a public method calledmyViews()that i used in myonCreatemethod in anif-statement.. so i just wondered why i had to useclassthis time.
– Delice
Nov 9 at 23:54
1
I think the major difference here is that, when you have just one Activity, you can use a method to organize all of yourfindViewById()calls... but in this case you have a different view holder for every row, so you need many different "groups" offindViewById()calls. A view holder object/class is the best way to do that.
– Ben P.
Nov 10 at 3:24
Ok thanks I think i got it now!
– Delice
Nov 10 at 13:36
add a comment |
I have a question regarding the 3th question you answered "Why do i have to create a private class called ViewHolder [...]" --> Why does it have to be aclass? is it possible to make it apublic method?
– Delice
Nov 9 at 23:35
Why do you want it to be a method? But, short answer, no. You can only pass objects tosetTag(), so you have to define a class for your view holder.
– Ben P.
Nov 9 at 23:42
I've had an older project where i made a public method calledmyViews()that i used in myonCreatemethod in anif-statement.. so i just wondered why i had to useclassthis time.
– Delice
Nov 9 at 23:54
1
I think the major difference here is that, when you have just one Activity, you can use a method to organize all of yourfindViewById()calls... but in this case you have a different view holder for every row, so you need many different "groups" offindViewById()calls. A view holder object/class is the best way to do that.
– Ben P.
Nov 10 at 3:24
Ok thanks I think i got it now!
– Delice
Nov 10 at 13:36
I have a question regarding the 3th question you answered "Why do i have to create a private class called ViewHolder [...]" --> Why does it have to be a
class? is it possible to make it a public method ?– Delice
Nov 9 at 23:35
I have a question regarding the 3th question you answered "Why do i have to create a private class called ViewHolder [...]" --> Why does it have to be a
class? is it possible to make it a public method ?– Delice
Nov 9 at 23:35
Why do you want it to be a method? But, short answer, no. You can only pass objects to
setTag(), so you have to define a class for your view holder.– Ben P.
Nov 9 at 23:42
Why do you want it to be a method? But, short answer, no. You can only pass objects to
setTag(), so you have to define a class for your view holder.– Ben P.
Nov 9 at 23:42
I've had an older project where i made a public method called
myViews() that i used in my onCreate method in an if-statement.. so i just wondered why i had to use class this time.– Delice
Nov 9 at 23:54
I've had an older project where i made a public method called
myViews() that i used in my onCreate method in an if-statement.. so i just wondered why i had to use class this time.– Delice
Nov 9 at 23:54
1
1
I think the major difference here is that, when you have just one Activity, you can use a method to organize all of your
findViewById() calls... but in this case you have a different view holder for every row, so you need many different "groups" of findViewById() calls. A view holder object/class is the best way to do that.– Ben P.
Nov 10 at 3:24
I think the major difference here is that, when you have just one Activity, you can use a method to organize all of your
findViewById() calls... but in this case you have a different view holder for every row, so you need many different "groups" of findViewById() calls. A view holder object/class is the best way to do that.– Ben P.
Nov 10 at 3:24
Ok thanks I think i got it now!
– Delice
Nov 10 at 13:36
Ok thanks I think i got it now!
– Delice
Nov 10 at 13:36
add a comment |
up vote
1
down vote
A viewholder is a design pattern used in android apps in order to replace the more expensive findviewbyid calls.
Quoting docs
Your code might call findViewById() frequently during the scrolling of ListView, which can slow down performance. Even when the Adapter returns an inflated view for recycling, you still need to look up the elements and update them. A way around repeated use of findViewById() is to use the "view holder" design pattern.
Regarding the second and third question the settag and gettag is basically a way for your view to have "memories" you can refer here for further information and a more detailed explanation!
Hope this helps!
Thank you for your input! I think i almost understood everything. I just need to verify one last question and i put that into Ben P. answer.
– Delice
Nov 9 at 23:36
add a comment |
up vote
1
down vote
A viewholder is a design pattern used in android apps in order to replace the more expensive findviewbyid calls.
Quoting docs
Your code might call findViewById() frequently during the scrolling of ListView, which can slow down performance. Even when the Adapter returns an inflated view for recycling, you still need to look up the elements and update them. A way around repeated use of findViewById() is to use the "view holder" design pattern.
Regarding the second and third question the settag and gettag is basically a way for your view to have "memories" you can refer here for further information and a more detailed explanation!
Hope this helps!
Thank you for your input! I think i almost understood everything. I just need to verify one last question and i put that into Ben P. answer.
– Delice
Nov 9 at 23:36
add a comment |
up vote
1
down vote
up vote
1
down vote
A viewholder is a design pattern used in android apps in order to replace the more expensive findviewbyid calls.
Quoting docs
Your code might call findViewById() frequently during the scrolling of ListView, which can slow down performance. Even when the Adapter returns an inflated view for recycling, you still need to look up the elements and update them. A way around repeated use of findViewById() is to use the "view holder" design pattern.
Regarding the second and third question the settag and gettag is basically a way for your view to have "memories" you can refer here for further information and a more detailed explanation!
Hope this helps!
A viewholder is a design pattern used in android apps in order to replace the more expensive findviewbyid calls.
Quoting docs
Your code might call findViewById() frequently during the scrolling of ListView, which can slow down performance. Even when the Adapter returns an inflated view for recycling, you still need to look up the elements and update them. A way around repeated use of findViewById() is to use the "view holder" design pattern.
Regarding the second and third question the settag and gettag is basically a way for your view to have "memories" you can refer here for further information and a more detailed explanation!
Hope this helps!
answered Nov 9 at 23:00
Georgios S.
1799
1799
Thank you for your input! I think i almost understood everything. I just need to verify one last question and i put that into Ben P. answer.
– Delice
Nov 9 at 23:36
add a comment |
Thank you for your input! I think i almost understood everything. I just need to verify one last question and i put that into Ben P. answer.
– Delice
Nov 9 at 23:36
Thank you for your input! I think i almost understood everything. I just need to verify one last question and i put that into Ben P. answer.
– Delice
Nov 9 at 23:36
Thank you for your input! I think i almost understood everything. I just need to verify one last question and i put that into Ben P. answer.
– Delice
Nov 9 at 23:36
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53234158%2fandroid-studio-help-me-to-understand-this-code%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown