I have AudioListFile with Player Program.
When i click an item of GridView, sound will be played.!
enter image description here
Now, i wonder, How can i update ProgressBar in GridView?
I need mediaplayer.getDuration() in adapter.
please help me. thank you so much.
My adapter:
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
// Initialize views
holder = new Holder();
convertView = inflater.inflate(R.layout.raw_audio_list_item, null);
holder.tvFileName = (TextView) convertView.findViewById(R.id.row_audio_list_item_tv_file_name);
holder.tvFileSize = (TextView) convertView.findViewById(R.id.row_audio_list_item_tv_file_size);
holder.pbPlayProgress = (ProgressBar) convertView.findViewById(R.id.audio_file_list_pb);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
// get the map object from list
AudioDataModel audioFileModel = audioFileList.get(position);
// set data to view
holder.tvFileName.setText(audioFileModel.getFileName());
holder.tvFileSize.setText(audioFileModel.getFileSize());
holder.pbPlayProgress.setMax(Integer.parseInt(audioFileModel.getFileDuration()));
convertView.setId(Integer.valueOf(audioFileModel.getFileId()));
return convertView;
}
actually you can easily do this but you have to use sparseIntegerHashmap to track the current progress for particular view because gridview or listview recycle the view they reuse the view for efficiency. so first check in getview method check whether this particular view are for this particular progress bar (means it not reused ) then set it's value from hashmap and if this view is newly created (no entry found in hashmap then) please apply default value for progress bar . simple you have to track individual view with progress in hashmap . current code might not be working because i am not on my workstation right now hope you will understand e.g
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
// Initialize views
holder = new Holder();
convertView = inflater.inflate(R.layout.raw_audio_list_item, null);
holder.tvFileName = (TextView) convertView.findViewById(R.id.row_audio_list_item_tv_file_name);
holder.tvFileSize = (TextView) convertView.findViewById(R.id.row_audio_list_item_tv_file_size);
holder.pbPlayProgress = (ProgressBar) convertView.findViewById(R.id.audio_file_list_pb);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
// get the map object from list
AudioDataModel audioFileModel = audioFileList.get(position);
// set data to view
holder.tvFileName.setText(audioFileModel.getFileName());
holder.tvFileSize.setText(audioFileModel.getFileSize()); holder.pbPlayProgress.setMax(Integer.parseInt(audioFileModel.getFileDuration()));
convertView.setId(Integer.valueOf(audioFileModel.getFileId()));
//your unique id for compare
if(map.get(audioFileModel.getFileId())==holder.getId) {
holder.pbPlayProgress.setProgress(map.get(audioFileModel.getFileId()));
} else {
holder.pbPlayProgress.setProgress(//add default value );
// also add entry in hashmap
map.add(audioFileModel.getFileId(),default value)
}
return convertView;
}
Related
Currently my listview is working fine to return one view but I want it to
check when the currentVerse.getVerseNumber()==1 and return two different views (rows) if the condition is true. I cannot figure it out, Any help will be highly appreciated.
public View getView(int position, View convertView, ViewGroup parent) {
VersesModel currentVerse = verses.get(position);
if (convertView == null) {
convertView = getActivity().getLayoutInflater().inflate(
R.layout.verses_custom_list, parent, false);
viewHolder = new ViewHolder();
font = Typeface.createFromAsset(convertView.getContext().getAssets(), "my_font.ttf");
viewHolder.textView = (TextView) convertView.findViewById(R.id.textView_Verse);
viewHolder.nView = (TextView) convertView.findViewById(R.id.textView_verseNumber);
viewHolder.textView.setTypeface(font);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.textView.setText(currentVerse.getVerseText().toString());
viewHolder.nView.setText(currentVerse.getVerseNumber() + "");
convertView.setTag(viewHolder);
return convertView;
}
Its simple according to me ....
Create a layout with both views in the same layout which you want to show...
And suppose for condition true you want to show LinearLayout-A and for false u want to show LinearLayout-B then its simple use View.Visibility
if(true)
{
LinearLayout-B.setVisibility(View.GONE);
LinearLayout-A.setVisibility(View.VISIBLE);
}
else
{
LinearLayout-A.setVisibility(View.GONE);
LinearLayout-B.setVisibility(View.VISIBLE);
}
btw im using both because rememember listview paints everytime the view is created after its hidden so to make it easy and robust otherwise it wud just mess up alot...
Hope it helps u ...
Thanks
i have a big problem with my ListViewAdapter.
My listview shows 2 entrys at the same time. Each entry should get a different picture from my server.
The first and the second entrys working fine, but if i'm scrolling down, the next entrys will have the same pictures.
My Code looks like this:
if (viewHolder.imgPic != null) {
String strUrl = mainUrl+list.get(position).getUrl();
new ImageDownload(viewHolder.imgPic).execute(strUrl);
}
I'm checking the view and just doing it, if it's null.
Can someone help me?
Thanks
from your question I can assume that you don't know about the ListView recycling mechanisem
basically, view that that not visible anymore (after user scrolled it away from sight) it been recycled to displayed new item that need to shown. that's the convertView parameter at the getView() method...
probably you are see the same image because the recycled view stays with the same image..
also there is the issue of the asynchronous task (your ImageDownload class) that can finish it execute when the original item that started the request already been recycled.
I recommend you to "dig" as dipper as you can to understand all about ListView - this is one of the most complex and important UI component. reading the post I linked you is a good start.
also this video is very important:
http://www.youtube.com/watch?v=wDBM6wVEO70
Here is my GetView:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;
if(rowResourceId!=R.layout.search_empty_list) {
if (convertView == null) {
LayoutInflater inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflator.inflate(rowResourceId, null);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.textName = (TextView) view.findViewById(R.id.textView1);
viewHolder.imgPic = (ImageView) view.findViewById(R.id.imgPic);
if (viewHolder.imgPic != null) {
String strUrl = mainUrl+list.get(position).getUrl();
new ImageDownload(viewHolder.imgPic).execute(strUrl);
}
view.setTag(viewHolder);
} else {
view = convertView;
}
ViewHolder holder = (ViewHolder) view.getTag();
holder.textName.setText(list.get(position).getName());
} else {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(rowResourceId, parent, false);
TextView textView1 = (TextView) view.findViewById(R.id.textView1);
textView1.setText(list.get(0).getName());
}
return view;
}
I've a custom adapter for my ListView where I send to it a List, and if the position is in the list then the imageview (that is in the custom row) change its src to another.. Here is the GetView method:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.start_row, null); // line
// 47
holder = new ViewHolder();
holder.tv_SuraName = (TextView) convertView.findViewById(R.id.Start_Name);
holder.tv_SuraName.setTypeface(Font);
holder.tv_PageNumber = (TextView) convertView.findViewById(R.id.Start_Numbering);
holder.im_Audio = (ImageView) convertView.findViewById(R.id.Start_ImageView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tv_SuraName.setText(SuraList_SuraNamesCode[position]);
holder.tv_PageNumber.setText(Integer.toString(PageNumber[position]));
holder.im_Audio.setOnClickListener(new imageViewClickListener(position));
if (TilawaAvailable.contains(position))
holder.im_Audio.setImageResource(R.drawable.quran_list_audioavailable);
return convertView;
}
I send a List with 1 position.If I scroll the ListView slowly, this works good and only 1 imageview gets changed as it should be. But if I scroll fast, other imagesviews that are close to the correct position also gets changed!
Can anyone tell me why?
You don't ever set the imageResource to something else if position isn't contained in your list. When the view with the custom image leaves the screen it is probably getting placed at a lower position in the list and getting reused.
Try changing this:
if (TilawaAvailable.contains(position))
holder.im_Audio.setImageResource(R.drawable.quran_list_audioavailable);
To this:
if (TilawaAvailable.contains(position))
holder.im_Audio.setImageResource(R.drawable.quran_list_audioavailable);
else
holder.im_audio.setImageResource(r.drawable.SOME_THING_ELSE);
I have list view with custom array adapter. I want to get items click position from getView method. I am getting a few list view items position but when i add more then 7 items into my list i get wrong position from getView method. I mean when i click 9th list item it returns 1.
Here is my code
#Override
public View getView(int pos, View convertView, ViewGroup parent) {
this.position = pos;
Log.v("View position", Integer.toString(pos));
lineView = convertView;
if(lineView==null)
{
adapterLine=new AdapterLine();
layoutInflater=context.getLayoutInflater();
lineView=layoutInflater.inflate(com.inomera.sanalmarket.main.R.layout.adapter, null,true);
adapterLine.sListText = (TextView) lineView.findViewById(R.id.sListText);
adapterLine.sListCheckbox = (CheckBox) lineView.findViewById(R.id.sListCheckbox);
adapterLine.sListImageView = (ImageView) lineView.findViewById(R.id.imageView1);
adapterLine.gestureOverlayView = (GestureOverlayView) lineView.findViewById(com.inomera.sanalmarket.main.R.id.gestureOverlayView1);
adapterLine.gestureOverlayView.setGestureVisible(false);
// To remember whitch tab is selected
adapterLine.sListImageView.setTag(pos);
adapterLine.sListCheckbox.setTag(pos);
adapterLine.sListText.setTag(pos);
Log.v("adapter", "position of adapter is " + Integer.toString(pos));
Thanks for any help!
The array adapter will only create one object per visible row in your list view. After this, the adapter will recycle that already created view. This is the purpose of the:
if(lineView==null)
line in your adapter.
You will want to put in an else section that sets up the row using the recycled view. This other article may be helpful:
How can I make my ArrayAdapter follow the ViewHolder pattern?
This implementation is incomplete add else section which sets value from data. here is implementation which worked for me
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflator = reportViewContext.getLayoutInflater();
convertView = inflator.inflate(R.layout.tabitems, null);
viewHolder.name= (TextView) convertView
.findViewById(R.id.user_reportTab_userName);
//set other values needed in viewHolder if any
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder)convertView.getTag();
}
//data is list of Data model
if(data.size()<=0) {
//if data unavailable }
else {
/***** Get each Model object from Array list ********/
System.out.println("Position:"+position);
/************ Set Model values in Holder elements ***********/
viewHolder.name.setText(data.get(position).getName());
}
return convertView;
}
I know the question is very old, answered in case anyone stumbled on similar problem
I am using a customised BaseAdapter to display items on a ListView. The items are just strings held in an ArrayList.
The list items have a delete button on them (big red X), and I'd like to remove the item from the ArrayList, and notify the ListView to update itself.
However, every implementation I've tried gets mysterious position numbers given to it, so for example clicking item 2's delete button will delete item 5's. It seems to be almost entirely random.
One thing to note is that elements may be repeated, but must be kept in the same order. For example, I can have "Irish" twice, as elements 3 and 7.
My code is below:
private static class ViewHolder {
TextView lang;
int position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.language_link_row, null);
holder = new ViewHolder();
holder.lang = (TextView)convertView.findViewById(R.id.language_link_text);
holder.position = position;
final ImageView deleteButton = (ImageView)
convertView.findViewById(R.id.language_link_cross_delete);
deleteButton.setOnClickListener(this);
convertView.setTag(holder);
deleteButton.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.lang.setText(mLanguages.get(position));
return convertView;
}
I later attempt to retrieve the deleted element's position by grabbing the tag, but it's always the wrong position in the list. There is no noticeable pattern to the position given here, it always seems random.
// The delete button's listener
public void onClick(View v) {
ViewHolder deleteHolder = (ViewHolder) v.getTag();
int pos = deleteHolder.position;
...
...
...
}
I would be quite happy to just delete the item from the ArrayList and have the ListView update itself, but the position I'm getting is incorrect so I can't do that.
Please note that I did, at first, have the deleteButton clickListener inside the getView method, and used 'position' to delete the value, but I had the same problem.
Any suggestions appreciated, this is really irritating me.
You have to set the position each time. Your implementation only sets the position on the creation of the view. However when the view is recycled (when convertView is not null), the position will not be set to the correct value.
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.language_link_row, null);
holder = new ViewHolder();
holder.lang = (TextView)convertView.findViewById(R.id.language_link_text);
final ImageView deleteButton = (ImageView)
convertView.findViewById(R.id.language_link_cross_delete);
deleteButton.setOnClickListener(this);
convertView.setTag(holder);
deleteButton.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.lang.setText(mLanguages.get(position));
holder.position = position;
return convertView;
}
you need to implement OnItemClickListener interface, and delete the item in the onItemClick method, one parameter of the method is the position.
My final solution was to use the accepted answer by Greg and the following:
Store the holders in a HashMap, with the item positions as the keys (this is initialised as empty in the constructor)
private HashMap mHolders;
Use this as the onClickListener method:
public void onClick(View v) {
ViewHolder deleteHolder = (ViewHolder) v.getTag();
int pos = deleteHolder.position;
mHolders.remove(pos);
ViewHolder currentHolder;
// Shift 'position' of remaining languages
// down since 'pos' was deleted
for(int i=pos+1; i<getCount(); i++){
currentHolder = mHolders.get(i);
currentHolder.position = i-1;
}
mLanguages.remove(pos);
notifyDataSetChanged();
}
[Please excuse the weird formatting. The code embedding isn't working properly]