ListAdapter getView与位置错误值 [英] ListAdapter getView with wrong value for position
问题描述
这个问题根本上的地址同样的问题,因为旧版本
其重新写的,因为code是更可读,我改变了适配器从BaseAdapter扩展到ListAdapter接口实现(至极毫无意义)。
我与适配器的getView方法中位置变量这个奇怪的问题。这些6种不同视图类型的4,得到了在他们里面的按钮。该按钮将消息发送到服务(挑起了一些服务异步的东西),而且时间后无限期量中,该适配器获得由服务挑起notifyDataSetChanged()。
问题显示了当我垃圾邮件的发送消息的按钮。如果我在垃圾邮件速度不够快,错误的数据将被发送到该服务。我认为这个问题是垃圾邮件时,我会notifyDataSetChanged()过程中按下按钮,因为如果我发表评论,该服务使用,这种不一致不会发生的方法,这一呼吁。另外,如果我没有垃圾邮件的按钮(如1秒抽头之间的延迟),它会正常工作。
奇怪的是,getView方法中,一个的getItem(位置)调用,将返回不同的项目。它会返回构建视图本身正确的项目,但可能会在视图中的错误的项目返回到onClickListener按钮。
继承人的全适配器类:
公共类ListViewFolderAdapter实现ListAdapter { 私有静态最终诠释MAX_COUNT = 6; 私人MainActivity mActivity;
私人的ArrayList< ListViewDataItem>数据= NULL;
[]选择私人字符串;
私人MainPagerAdapter mainPagerAdapter;
私人诠释listPosition;
私人字符串目录名; 私人最终DataSetObservable mDataSetObservable; 私人LayoutInflater吹气;
公共ListViewFolderAdapter(MainActivity mActivity,MainPagerAdapter mainPagerAdapter,INT listPosition,
字符串目录名,ArrayList的< ListViewDataItem>数据){
this.mActivity = mActivity;
this.mainPagerAdapter = mainPagerAdapter;
this.listPosition = listPosition;
this.data =数据;
this.dirName =目录名;
this.inflater = mActivity.getLayoutInflater();
this.mDataSetObservable =新DataSetObservable();
} @覆盖
公共查看getView(最终诠释的立场,观点convertView,父母的ViewGroup){
查看排= convertView;
StandardFolderViewHolder standardFolderViewHolder = NULL;
StandardFileViewHolder standardFileViewHolder = NULL;
MusicFileStoppedViewHolder musicFileStoppedHolder = NULL;
MusicFilePlayingViewHolder musicFilePlayingHolder = NULL;
MusicFolderStoppedViewHolder musicFolderStoppedHolder = NULL;
MusicFolderPlayingViewHolder musicFolderPlayingHolder = NULL; 开关(getItemViewType(位置)){
案例Constants.MEDIA_FILE.TYPE.STANDARD_DIRECTORY:
如果(行== NULL){
standardFolderViewHolder =新StandardFolderViewHolder();
行= inflater.inflate(R.layout.listview_standard_folder_row,父母,假);
standardFolderViewHolder.icon =(ImageView的)row.findViewById(R.id.filetype_icon);
standardFolderViewHolder.tempTV =(TextView中)row.findViewById(R.id.listview_mixed_folder_row_test_tv);
row.setTag(standardFolderViewHolder);
}
其他{
standardFolderViewHolder =(StandardFolderViewHolder)row.getTag();
}
standardFolderViewHolder.icon.setImageDrawable(的getItem(位置).getDrawable());
standardFolderViewHolder.tempTV.setText(的getItem(位置).getName());
standardFolderViewHolder.tempTV.setSelected(真);
打破;
案例Constants.MEDIA_FILE.TYPE.STANDARD_FILE:
如果(行== NULL){
standardFileViewHolder =新StandardFileViewHolder();
行= inflater.inflate(R.layout.listview_standard_folder_row,父母,假);
standardFileViewHolder.icon =(ImageView的)row.findViewById(R.id.filetype_icon);
standardFileViewHolder.tempTV =(TextView中)row.findViewById(R.id.listview_mixed_folder_row_test_tv);
row.setTag(standardFileViewHolder);
}
其他{
standardFileViewHolder =(StandardFileViewHolder)row.getTag();
}
standardFileViewHolder.icon.setImageDrawable(的getItem(位置).getDrawable());
standardFileViewHolder.tempTV.setText(的getItem(位置).getName());
standardFileViewHolder.tempTV.setSelected(真);
打破;
案例Constants.MEDIA_FILE.TYPE.MUSIC_DIRECTORY_PLAYING_STATE:
如果(行== NULL){
musicFolderPlayingHolder =新MusicFolderPlayingViewHolder();
行= inflater.inflate(R.layout.listview_music_folder_playing_row,父母,假);
musicFolderPlayingHolder.icon =(ImageView的)row.findViewById(R.id.filetype_icon);
musicFolderPlayingHolder.songName =(TextView中)row.findViewById(R.id.row_title_tv);
musicFolderPlayingHolder.playButton =(按钮)row.findViewById(R.id.row_play_button);
musicFolderPlayingHolder.durationTV =(TextView中)row.findViewById(R.id.row_duration_tv);
musicFolderPlayingHolder.progressBar =(进度)row.findViewById(R.id.folder_progress_bar);
row.setTag(musicFolderPlayingHolder);
}
其他{
musicFolderPlayingHolder =(MusicFolderPlayingViewHolder)row.getTag();
}
musicFolderPlayingHolder.icon.setImageDrawable(的getItem(位置).getDrawable());
musicFolderPlayingHolder.songName.setText(的getItem(位置).getName());
musicFolderPlayingHolder.songName.setSelected(真);
musicFolderPlayingHolder.durationTV.setText(mActivity.formattedMillis(getItem(position).getDuration()));
musicFolderPlayingHolder.progressBar.setMax(的getItem(位置).getDuration());
musicFolderPlayingHolder.progressBar.setProgress(的getItem(位置).getProgress());
musicFolderPlayingHolder.playButton.setTag(的getItem(位置));
musicFolderPlayingHolder.playButton.setOnClickListener(新MyOnClickListener());
打破;
案例Constants.MEDIA_FILE.TYPE.MUSIC_DIRECTORY_STOPPED_STATE:
如果(行== NULL){
musicFolderStoppedHolder =新MusicFolderStoppedViewHolder();
行= inflater.inflate(R.layout.listview_music_folder_stopped_row,父母,假);
musicFolderStoppedHolder.icon =(ImageView的)row.findViewById(R.id.filetype_icon);
musicFolderStoppedHolder.songName =(TextView中)row.findViewById(R.id.row_title_tv);
musicFolderStoppedHolder.playButton =(按钮)row.findViewById(R.id.row_play_button);
musicFolderStoppedHolder.durationTV =(TextView中)row.findViewById(R.id.row_duration_tv);
row.setTag(musicFolderStoppedHolder);
}
其他{
musicFolderStoppedHolder =(MusicFolderStoppedViewHolder)row.getTag();
}
musicFolderStoppedHolder.icon.setImageDrawable(的getItem(位置).getDrawable());
musicFolderStoppedHolder.songName.setText(的getItem(位置).getName());
musicFolderStoppedHolder.songName.setSelected(真);
musicFolderStoppedHolder.durationTV.setText(mActivity.formattedMillis(getItem(position).getDuration()));
musicFolderStoppedHolder.playButton.setTag(的getItem(位置));
musicFolderStoppedHolder.playButton.setOnClickListener(新MyOnClickListener()); 打破;
案例Constants.MEDIA_FILE.TYPE.MUSIC_FILE_PLAYING_STATE:
如果(行== NULL){
musicFilePlayingHolder =新MusicFilePlayingViewHolder();
行= inflater.inflate(R.layout.listview_music_file_playing_row,父母,假);
musicFilePlayingHolder.icon =(ImageView的)row.findViewById(R.id.filetype_icon);
musicFilePlayingHolder.songName =(TextView中)row.findViewById(R.id.row_title_tv);
musicFilePlayingHolder.playButton =(按钮)row.findViewById(R.id.music_file_playing_row_play_button);
musicFilePlayingHolder.durationTV =(TextView中)row.findViewById(R.id.row_duration_tv);
musicFilePlayingHolder.progressBar =(进度)row.findViewById(R.id.folder_progress_bar);
row.setTag(musicFilePlayingHolder);
}
其他{
musicFilePlayingHolder =(MusicFilePlayingViewHolder)row.getTag();
}
musicFilePlayingHolder.icon.setImageDrawable(的getItem(位置).getDrawable());
musicFilePlayingHolder.songName.setText(的getItem(位置).getName());
musicFilePlayingHolder.songName.setSelected(真);
musicFilePlayingHolder.durationTV.setText(mActivity.formattedMillis(getItem(position).getDuration()));
musicFilePlayingHolder.progressBar.setMax(的getItem(位置).getDuration());
musicFilePlayingHolder.progressBar.setProgress(的getItem(位置).getProgress());
musicFilePlayingHolder.playButton.setTag(的getItem(位置));
musicFilePlayingHolder.playButton.setOnClickListener(新MyOnClickListener());
打破;
案例Constants.MEDIA_FILE.TYPE.MUSIC_FILE_STOPPED_STATE:
如果(行== NULL){
musicFileStoppedHolder =新MusicFileStoppedViewHolder();
行= inflater.inflate(R.layout.listview_music_file_stopped_row,父母,假);
musicFileStoppedHolder.icon =(ImageView的)row.findViewById(R.id.filetype_icon);
musicFileStoppedHolder.songName =(TextView中)row.findViewById(R.id.row_title_tv);
musicFileStoppedHolder.playButton =(按钮)row.findViewById(R.id.music_file_stopped_row_play_button);
musicFileStoppedHolder.durationTV =(TextView中)row.findViewById(R.id.row_duration_tv); row.setTag(musicFileStoppedHolder);
}
其他{
musicFileStoppedHolder =(MusicFileStoppedViewHolder)row.getTag();
}
musicFileStoppedHolder.icon.setImageDrawable(的getItem(位置).getDrawable());
musicFileStoppedHolder.songName.setText(的getItem(位置).getName());
musicFileStoppedHolder.songName.setSelected(真);
musicFileStoppedHolder.durationTV.setText(mActivity.formattedMillis(getItem(position).getDuration()));
musicFileStoppedHolder.playButton.setTag(的getItem(位置));
musicFileStoppedHolder.playButton.setOnClickListener(新MyOnClickListener());
打破;
} 如果(!的getItem(位置).wasAnimatedIn()){
row.startAnimation(的getItem(位置).getGoingIn());
}
否则如果(!的getItem(位置).wasAnimatedOut()){
动画outAnim =的getItem(位置).getGoingOut();
outAnim.setAnimationListener(新AnimationListener(){ @覆盖
公共无效onAnimationEnd(动画动画){
data.remove(的getItem(位置));
} @覆盖
公共无效onAnimationRepeat(动画动画){} @覆盖
公共无效onAnimationStart(动画动画){}
});
row.startAnimation(outAnim);
}
Log.e(getView+的getItem(位置).getName(),POS:+位置);
返回行;
} 公共无效插入(ListViewDataItem对象,诠释指数){
在data.set(索引,对象);
object.setAnimatedInFalse();
} 公共无效removeWithAnimation(字符串文件名){
的for(int i = 0; I< data.size();我++){
如果(data.get(I).getName()。与compareToIgnoreCase(文件名)== 0){
的getItem(ⅰ).setAnimatedOutFalse();
notifyDataSetChanged();
选择信息(一);
返回;
}
}
} 私人无效选择信息(INT itemPosition){
mainPagerAdapter.setSelectedItemInList(listPosition,itemPosition);
} 静态类StandardFolderViewHolder {
ImageView的图标;
TextView的tempTV;
TextView的tempTV2;
} 静态类StandardFileViewHolder {
ImageView的图标;
TextView的tempTV;
TextView的tempTV2;
} 静态类MusicFileStoppedViewHolder {
ImageView的图标;
TextView的SONGNAME;
按钮为playButton;
TextView的durationTV;
} 静态类MusicFilePlayingViewHolder {
ImageView的图标;
TextView的SONGNAME;
按钮为playButton;
TextView的durationTV;
进度进度;
} 静态类MusicFolderStoppedViewHolder {
ImageView的图标;
TextView的SONGNAME;
按钮为playButton;
TextView的durationTV;
} 静态类MusicFolderPlayingViewHolder {
ImageView的图标;
TextView的SONGNAME;
按钮为playButton;
TextView的durationTV;
进度进度;
} 无效setSelectedPosition(字符串[]选择){
this.selected =选择;
notifyDataSetChanged();
} 公众的String [] getSelectedPosition(){
返回this.selected;
} 公共字符串getDirName(){
返回this.dirName;
} @覆盖
公众诠释getViewTypeCount(){
返回MAX_COUNT;
} @覆盖
公众诠释的getCount(){
返回data.size();
} @覆盖
公共ListViewDataItem的getItem(INT位置){
返回data.get(位置);
} @覆盖
众长getItemId(INT位置){
返回的位置;
} / **
*必须回到0℃= INT< getCount将()
* /
@覆盖
公众诠释getItemViewType(INT位置){
返回的getItem(位置).getType();
} 公共无效notifyDataSetChanged(){
mDataSetObservable.notifyChanged();
} @覆盖
公共布尔hasStableIds(){
返回true;
} @覆盖
公共布尔的isEmpty(){
返回getCount将()== 0;
} @覆盖
公共无效registerDataSetObserver(DataSetObserver观察者){
mDataSetObservable.registerObserver(观察员);
} @覆盖
公共无效unregisterDataSetObserver(DataSetObserver观察者){
mDataSetObservable.unregisterObserver(观察员);
} @覆盖
公共布尔areAllItemsEnabled(){
返回true;
} @覆盖
公共布尔isEnabled(INT位置){
返回true;
} 公共无效updateTypeAndDuration(INT位置,整型,诠释时间){
ListViewDataItem lvDataItem =的getItem(位置);
lvDataItem.setType(类型);
lvDataItem.setDuration(持续时间);
notifyDataSetChanged();
} 公共无效updateProgressInFile(INT positionInPage,诠释maxProgress,诠释进度){
如果(positionInPage&下;的getCount()){
ListViewDataItem lvDataItem =的getItem(positionInPage);
lvDataItem.setDuration(maxProgress);
lvDataItem.setProgress(进度);
notifyDataSetChanged();
}
} 公共无效activatePlayingState(INT positionInPage){
如果(positionInPage&下;的getCount()){
ListViewDataItem lvDataItem =的getItem(positionInPage);
如果(lvDataItem.getType()== Constants.MEDIA_FILE.TYPE.MUSIC_DIRECTORY_STOPPED_STATE){
lvDataItem.setType(Constants.MEDIA_FILE.TYPE.MUSIC_DIRECTORY_PLAYING_STATE);
notifyDataSetChanged();
}
否则如果(lvDataItem.getType()== Constants.MEDIA_FILE.TYPE.MUSIC_FILE_STOPPED_STATE){
lvDataItem.setType(Constants.MEDIA_FILE.TYPE.MUSIC_FILE_PLAYING_STATE);
notifyDataSetChanged();
}
}
} 公共无效clearPlayState(){
布尔stateChanged = FALSE;
对于(ListViewDataItem lvDataItem:数据){
如果(lvDataItem.getType()== Constants.MEDIA_FILE.TYPE.MUSIC_DIRECTORY_PLAYING_STATE){
lvDataItem.setType(Constants.MEDIA_FILE.TYPE.MUSIC_DIRECTORY_STOPPED_STATE);
stateChanged = TRUE;
}
否则如果(lvDataItem.getType()== Constants.MEDIA_FILE.TYPE.MUSIC_FILE_PLAYING_STATE){
lvDataItem.setType(Constants.MEDIA_FILE.TYPE.MUSIC_FILE_STOPPED_STATE);
stateChanged = TRUE;
}
}
如果(stateChanged){
notifyDataSetChanged();
}
} 私有类MyOnClickListener实现OnClickListener { @覆盖
公共无效的onClick(视图v){
Log.e(点击,(字符串)((ListViewDataItem)v.getTag())的getName());
捆绑馍=新包();
bun.putString(Constants.BUNDLE_KEYS.PLAY_FILES,(字符串)((ListViewDataItem)v.getTag())的getPath());
消息消息= Message.obtain(NULL,Constants.OP_ code.PLAY_FILES);
message.setData(BUN);
尝试{
mActivity.mService.send(消息);
}
赶上(RemoteException的RE){
re.printStackTrace();
}
}
}
}
下面是我在位置1的垃圾邮件视图内的按钮LogCat中转储,文件名是02 Maniac.flac
11月10日至24日:39:06.929:E /点击(21489):02 Maniac.flac
十一月10日至24日:39:06.949:E /试图播放(21489):到/ mnt / SD卡/音乐/大篷车宫殿/大篷车宫殿 - 恐慌(2012)FLAC / 02 Maniac.flac
十一月10日至24日:39:06.949:E / getView 01 Queens.flac(21489):POS:0
十一月10日至24日:39:07.049:E / getView 02 Maniac.flac(21489):排名:1
十一月10日至24日:39:07.069:E / getView 03 street.flac的脏侧(21489):排名:2
十一月10日至24日:39:07.069:E / getView 04月12日3049.flac(21489):POS:3
十一月10日至24日:39:07.069:E / getView 05摇滚它me.flac(21489):排名:4
十一月10日至24日:39:07.069:E / getView 06 Clash.flac(21489):POS:5
十一月10日至24日:39:07.169:E / getView 01 Queens.flac(21489):POS:0
十一月10日至24日:39:07.169:E / getView 02 Maniac.flac(21489):排名:1
十一月10日至24日:39:07.169:E / getView 03 street.flac的脏侧(21489):排名:2
十一月10日至24日:39:07.179:E / getView 04月12日3049.flac(21489):POS:3
十一月10日至24日:39:07.179:E / getView 05摇滚它me.flac(21489):排名:4
十一月10日至24日:39:07.179:E / getView 06 Clash.flac(21489):POS:5
十一月10日至24日:39:07.239:E /点击(21489):02 Maniac.flac
十一月10日至24日:39:07.259:E /点击(21489):02 Maniac.flac
十一月10日至24日:39:07.269:E / getView 01 Queens.flac(21489):POS:0
十一月10日至24日:39:07.269:E /试图播放(21489):到/ mnt / SD卡/音乐/大篷车宫殿/大篷车宫殿 - 恐慌(2012)FLAC / 02 Maniac.flac
十一月10日至24日:39:07.289:E / getView 02 Maniac.flac(21489):排名:1
十一月10日至24日:39:07.299:E / getView 03 street.flac的脏侧(21489):排名:2
十一月10日至24日:39:07.329:E / getView 04月12日3049.flac(21489):POS:3
十一月10日至24日:39:07.339:E / getView 05摇滚它me.flac(21489):排名:4
十一月10日至24日:39:07.339:E / getView 06 Clash.flac(21489):POS:5
十一月10日至24日:39:07.409:W / MediaPlayer的(21489):媒体播放器还带走了未处理的事件
十一月10日至24日:39:07.419:E /试图播放(21489):到/ mnt / SD卡/音乐/大篷车宫殿/大篷车宫殿 - 恐慌(2012)FLAC / 02 Maniac.flac
十一月10日至24日:39:07.489:E / getView 01 Queens.flac(21489):POS:0
十一月10日至24日:39:07.499:E / getView 02 Maniac.flac(21489):排名:1
十一月10日至24日:39:07.499:E / getView 03 street.flac的脏侧(21489):排名:2
十一月10日至24日:39:07.519:E / getView 04月12日3049.flac(21489):POS:3
十一月10日至24日:39:07.519:E / getView 05摇滚它me.flac(21489):排名:4
十一月10日至24日:39:07.539:E / getView 06 Clash.flac(21489):POS:5
十一月10日至24日:39:07.599:E /点击(21489):05摇滚它me.flac
十一月10日至24日:39:07.619:E / getView 01 Queens.flac(21489):POS:0
十一月10日至24日:39:07.629:E / getView 02 Maniac.flac(21489):排名:1
十一月10日至24日:39:07.629:E / getView 03 street.flac的脏侧(21489):排名:2
十一月10日至24日:39:07.639:E / getView 04月12日3049.flac(21489):POS:3
十一月10日至24日:39:07.639:E / getView 05摇滚它me.flac(21489):排名:4
十一月10日至24日:39:07.639:E / getView 06 Clash.flac(21489):POS:5
十一月10日至24日:39:07.699:E /点击(21489):06 Clash.flac
十一月10日至24日:39:07.709:E /点击(21489):02 Maniac.flac
十一月10日至24日:39:07.789:E / getView 01 Queens.flac(21489):POS:0
十一月10日至24日:39:07.799:E / getView 02 Maniac.flac(21489):排名:1
十一月10日至24日:39:07.809:E / getView 03 street.flac的脏侧(21489):排名:2
十一月10日至24日:39:07.809:E /试图播放(21489):到/ mnt / SD卡/音乐/大篷车宫殿/大篷车宫殿 - 恐慌(2012)FLAC /摇滚05它me.flac
十一月10日至24日:39:07.829:E / getView 04月12日3049.flac(21489):POS:3
十一月10日至24日:39:07.859:E / getView 05摇滚它me.flac(21489):排名:4
十一月10日至24日:39:07.869:E / getView 06 Clash.flac(21489):POS:5
十一月10日至24日:39:08.039:D / dalvikvm(21489):GC_CONCURRENT释放185K,45%免费3396K / 6087K,外部327K / 839K,暂停为5ms + 6ms的
十一月10日至24日:39:08.049:E / getView 01 Queens.flac(21489):POS:0
十一月10日至24日:39:08.049:E / getView 02 Maniac.flac(21489):排名:1
十一月10日至24日:39:08.059:E / getView 03 street.flac的脏侧(21489):排名:2
十一月10日至24日:39:08.059:E / getView 04 6月12日3049.flac(21489):POS:3
十一月10日至24日:39:08.069:E / getView 05摇滚它me.flac(21489):排名:4
十一月10日至24日:39:08.069:E / getView 06 Clash.flac(21489):POS:5
十一月10日至24日:39:08.129:E /点击(21489):06 Clash.flac
十一月10日至24日:39:08.129:E /点击(21489):06 Clash.flac
十一月10日至24日:39:08.159:E /点击(21489):02 Maniac.flac
十一月10日至24日:39:08.239:E / getView 01 Queens.flac(21489):POS:0
十一月10日至24日:39:08.249:E / getView 02 Maniac.flac(21489):排名:1
十一月10日至24日:39:08.259:E /试图播放(21489):到/ mnt / SD卡/音乐/大篷车宫殿/大篷车宫殿 - 恐慌(2012)FLAC / 06 Clash.flac
十一月10日至24日:39:08.259:E / getView 03 street.flac的脏侧(21489):排名:2
十一月10日至24日:39:08.259:E / getView 04月12日3049.flac(21489):POS:3
十一月10日至24日:39:08.289:E / getView 05摇滚它me.flac(21489):排名:4
十一月10日至24日:39:08.319:E / getView 06 Clash.flac(21489):POS:5
十一月10日至24日:39:08.409:E / getView 01 Queens.flac(21489):POS:0
十一月10日至24日:39:08.419:E / getView 02 Maniac.flac(21489):排名:1
十一月10日至24日:39:08.419:E / getView 03 street.flac的脏侧(21489):排名:2
十一月10日至24日:39:08.419:E / getView 04月12日3049.flac(21489):POS:3
十一月10日至24日:39:08.429:E / getView 05摇滚它me.flac(21489):排名:4
十一月10日至24日:39:08.429:E / getView 06 Clash.flac(21489):POS:5
您可以看到getView mehod为每一项正确的位置正确调用:
11月10日至24日:39:06.949:E / getView 01 Queens.flac(21489):POS:0
十一月10日至24日:39:07.049:E / getView 02 Maniac.flac(21489):排名:1
十一月10日至24日:39:07.069:E / getView 03 street.flac的脏侧(21489):排名:2
十一月10日至24日:39:07.069:E / getView 04月12日3049.flac(21489):POS:3
十一月10日至24日:39:07.069:E / getView 05摇滚它me.flac(21489):排名:4
十一月10日至24日:39:07.069:E / getView 06 Clash.flac(21489):POS:5
但随后的按钮点击,为getItem方法返回的某个项目错误(还记得IM垃圾邮件02 Maniac.flac)
11月10日至24日:39:07.699:E /点击(21489):06 Clash.flac
十一月10日至24日:39:07.709:E /点击(21489):02 Maniac.flac
-
11月10日至24日:39:07.599:E /点击(21489):05摇滚它me.flac
-
11月10日至24日:39:08.129:E /点击(21489):06 Clash.flac
十一月10日至24日:39:08.129:E /点击(21489):06 Clash.flac
十一月10日至24日:39:08.159:E /点击(21489):02 Maniac.flac
这可能是与回收利用的意见...?
我有一个列表视图类似的问题,但我还没有找到一个好的解决办法,我一直在寻找它。
由于我的列表视图永远不会包含超过15行我使用一种非常unnefective的解决方案,而不是回收我的行,而我在研究如何解决这个问题。
This question addresses fundamentally the same problem as Old Version Its re-written, because the code is much more readable, and i changed the adapter from a BaseAdapter extension to a ListAdapter interface implementation (wich was pointless).
I have this weird problem with position variable inside getView method of the adapter. 4 of those 6 different view types, got a button inside them. That button sends a message to a service (provoking some async stuff on the service), and within an indefinite amount of time after, this adapter gets a notifyDataSetChanged() provoked by the service.
The problem shows when i spam the button that sends the message. If i spam it fast enough, the wrong data will be sent to the service. I think the problem is that during the spam, i will hit the button during a notifyDataSetChanged(), because if i comment that call on the methods that the service is using, this inconsistency wont happen. Also if i don't spam the button (like a 1 s delay between taps), it will work correctly.
The weird thing is that within the getView method, a getItem(position) call, will return different items. It will return the correct item to build the view itself, but may return the wrong item to a onClickListener of a button within the view.
Heres the full adapter class:
public class ListViewFolderAdapter implements ListAdapter{
private static final int MAX_COUNT = 6;
private MainActivity mActivity;
private ArrayList<ListViewDataItem> data = null;
private String[] selected;
private MainPagerAdapter mainPagerAdapter;
private int listPosition;
private String dirName;
private final DataSetObservable mDataSetObservable;
private LayoutInflater inflater;
public ListViewFolderAdapter(MainActivity mActivity, MainPagerAdapter mainPagerAdapter, int listPosition,
String dirName, ArrayList<ListViewDataItem> data) {
this.mActivity=mActivity;
this.mainPagerAdapter = mainPagerAdapter;
this.listPosition = listPosition;
this.data = data;
this.dirName=dirName;
this.inflater = mActivity.getLayoutInflater();
this.mDataSetObservable = new DataSetObservable();
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
StandardFolderViewHolder standardFolderViewHolder = null;
StandardFileViewHolder standardFileViewHolder = null;
MusicFileStoppedViewHolder musicFileStoppedHolder = null;
MusicFilePlayingViewHolder musicFilePlayingHolder = null;
MusicFolderStoppedViewHolder musicFolderStoppedHolder = null;
MusicFolderPlayingViewHolder musicFolderPlayingHolder = null;
switch(getItemViewType(position)) {
case Constants.MEDIA_FILE.TYPE.STANDARD_DIRECTORY:
if(row == null) {
standardFolderViewHolder = new StandardFolderViewHolder();
row = inflater.inflate(R.layout.listview_standard_folder_row, parent, false);
standardFolderViewHolder.icon = (ImageView)row.findViewById(R.id.filetype_icon);
standardFolderViewHolder.tempTV = (TextView)row.findViewById(R.id.listview_mixed_folder_row_test_tv);
row.setTag(standardFolderViewHolder);
}
else {
standardFolderViewHolder = (StandardFolderViewHolder)row.getTag();
}
standardFolderViewHolder.icon.setImageDrawable(getItem(position).getDrawable());
standardFolderViewHolder.tempTV.setText(getItem(position).getName());
standardFolderViewHolder.tempTV.setSelected(true);
break;
case Constants.MEDIA_FILE.TYPE.STANDARD_FILE:
if(row == null) {
standardFileViewHolder = new StandardFileViewHolder();
row = inflater.inflate(R.layout.listview_standard_folder_row, parent, false);
standardFileViewHolder.icon = (ImageView)row.findViewById(R.id.filetype_icon);
standardFileViewHolder.tempTV = (TextView)row.findViewById(R.id.listview_mixed_folder_row_test_tv);
row.setTag(standardFileViewHolder);
}
else {
standardFileViewHolder = (StandardFileViewHolder)row.getTag();
}
standardFileViewHolder.icon.setImageDrawable(getItem(position).getDrawable());
standardFileViewHolder.tempTV.setText(getItem(position).getName());
standardFileViewHolder.tempTV.setSelected(true);
break;
case Constants.MEDIA_FILE.TYPE.MUSIC_DIRECTORY_PLAYING_STATE:
if(row == null) {
musicFolderPlayingHolder = new MusicFolderPlayingViewHolder();
row = inflater.inflate(R.layout.listview_music_folder_playing_row, parent, false);
musicFolderPlayingHolder.icon = (ImageView)row.findViewById(R.id.filetype_icon);
musicFolderPlayingHolder.songName = (TextView)row.findViewById(R.id.row_title_tv);
musicFolderPlayingHolder.playButton = (Button)row.findViewById(R.id.row_play_button);
musicFolderPlayingHolder.durationTV = (TextView)row.findViewById(R.id.row_duration_tv);
musicFolderPlayingHolder.progressBar = (ProgressBar)row.findViewById(R.id.folder_progress_bar);
row.setTag(musicFolderPlayingHolder);
}
else {
musicFolderPlayingHolder = (MusicFolderPlayingViewHolder)row.getTag();
}
musicFolderPlayingHolder.icon.setImageDrawable(getItem(position).getDrawable());
musicFolderPlayingHolder.songName.setText(getItem(position).getName());
musicFolderPlayingHolder.songName.setSelected(true);
musicFolderPlayingHolder.durationTV.setText(mActivity.formattedMillis(getItem(position).getDuration()));
musicFolderPlayingHolder.progressBar.setMax(getItem(position).getDuration());
musicFolderPlayingHolder.progressBar.setProgress(getItem(position).getProgress());
musicFolderPlayingHolder.playButton.setTag(getItem(position));
musicFolderPlayingHolder.playButton.setOnClickListener(new MyOnClickListener());
break;
case Constants.MEDIA_FILE.TYPE.MUSIC_DIRECTORY_STOPPED_STATE:
if(row == null) {
musicFolderStoppedHolder = new MusicFolderStoppedViewHolder();
row = inflater.inflate(R.layout.listview_music_folder_stopped_row, parent, false);
musicFolderStoppedHolder.icon = (ImageView)row.findViewById(R.id.filetype_icon);
musicFolderStoppedHolder.songName = (TextView)row.findViewById(R.id.row_title_tv);
musicFolderStoppedHolder.playButton = (Button)row.findViewById(R.id.row_play_button);
musicFolderStoppedHolder.durationTV = (TextView)row.findViewById(R.id.row_duration_tv);
row.setTag(musicFolderStoppedHolder);
}
else {
musicFolderStoppedHolder = (MusicFolderStoppedViewHolder)row.getTag();
}
musicFolderStoppedHolder.icon.setImageDrawable(getItem(position).getDrawable());
musicFolderStoppedHolder.songName.setText(getItem(position).getName());
musicFolderStoppedHolder.songName.setSelected(true);
musicFolderStoppedHolder.durationTV.setText(mActivity.formattedMillis(getItem(position).getDuration()));
musicFolderStoppedHolder.playButton.setTag(getItem(position));
musicFolderStoppedHolder.playButton.setOnClickListener(new MyOnClickListener());
break;
case Constants.MEDIA_FILE.TYPE.MUSIC_FILE_PLAYING_STATE:
if(row == null) {
musicFilePlayingHolder = new MusicFilePlayingViewHolder();
row = inflater.inflate(R.layout.listview_music_file_playing_row, parent, false);
musicFilePlayingHolder.icon = (ImageView)row.findViewById(R.id.filetype_icon);
musicFilePlayingHolder.songName = (TextView)row.findViewById(R.id.row_title_tv);
musicFilePlayingHolder.playButton = (Button)row.findViewById(R.id.music_file_playing_row_play_button);
musicFilePlayingHolder.durationTV = (TextView)row.findViewById(R.id.row_duration_tv);
musicFilePlayingHolder.progressBar = (ProgressBar)row.findViewById(R.id.folder_progress_bar);
row.setTag(musicFilePlayingHolder);
}
else {
musicFilePlayingHolder = (MusicFilePlayingViewHolder)row.getTag();
}
musicFilePlayingHolder.icon.setImageDrawable(getItem(position).getDrawable());
musicFilePlayingHolder.songName.setText(getItem(position).getName());
musicFilePlayingHolder.songName.setSelected(true);
musicFilePlayingHolder.durationTV.setText(mActivity.formattedMillis(getItem(position).getDuration()));
musicFilePlayingHolder.progressBar.setMax(getItem(position).getDuration());
musicFilePlayingHolder.progressBar.setProgress(getItem(position).getProgress());
musicFilePlayingHolder.playButton.setTag(getItem(position));
musicFilePlayingHolder.playButton.setOnClickListener(new MyOnClickListener());
break;
case Constants.MEDIA_FILE.TYPE.MUSIC_FILE_STOPPED_STATE:
if(row == null) {
musicFileStoppedHolder = new MusicFileStoppedViewHolder();
row = inflater.inflate(R.layout.listview_music_file_stopped_row, parent, false);
musicFileStoppedHolder.icon = (ImageView)row.findViewById(R.id.filetype_icon);
musicFileStoppedHolder.songName = (TextView)row.findViewById(R.id.row_title_tv);
musicFileStoppedHolder.playButton = (Button)row.findViewById(R.id.music_file_stopped_row_play_button);
musicFileStoppedHolder.durationTV = (TextView)row.findViewById(R.id.row_duration_tv);
row.setTag(musicFileStoppedHolder);
}
else {
musicFileStoppedHolder = (MusicFileStoppedViewHolder)row.getTag();
}
musicFileStoppedHolder.icon.setImageDrawable(getItem(position).getDrawable());
musicFileStoppedHolder.songName.setText(getItem(position).getName());
musicFileStoppedHolder.songName.setSelected(true);
musicFileStoppedHolder.durationTV.setText(mActivity.formattedMillis(getItem(position).getDuration()));
musicFileStoppedHolder.playButton.setTag(getItem(position));
musicFileStoppedHolder.playButton.setOnClickListener(new MyOnClickListener());
break;
}
if(!getItem(position).wasAnimatedIn()) {
row.startAnimation(getItem(position).getGoingIn());
}
else if (!getItem(position).wasAnimatedOut()) {
Animation outAnim = getItem(position).getGoingOut();
outAnim.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
data.remove(getItem(position));
}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationStart(Animation animation) {}
});
row.startAnimation(outAnim);
}
Log.e("getView" + getItem(position).getName(), "pos: " + position);
return row;
}
public void insert(ListViewDataItem object, int index) {
data.set(index, object);
object.setAnimatedInFalse();
}
public void removeWithAnimation(String fileName) {
for(int i = 0 ; i < data.size(); i++) {
if(data.get(i).getName().compareToIgnoreCase(fileName) == 0) {
getItem(i).setAnimatedOutFalse();
notifyDataSetChanged();
selectItem(i);
return;
}
}
}
private void selectItem(int itemPosition) {
mainPagerAdapter.setSelectedItemInList(listPosition, itemPosition);
}
static class StandardFolderViewHolder {
ImageView icon;
TextView tempTV;
TextView tempTV2;
}
static class StandardFileViewHolder {
ImageView icon;
TextView tempTV;
TextView tempTV2;
}
static class MusicFileStoppedViewHolder {
ImageView icon;
TextView songName;
Button playButton;
TextView durationTV;
}
static class MusicFilePlayingViewHolder {
ImageView icon;
TextView songName;
Button playButton;
TextView durationTV;
ProgressBar progressBar;
}
static class MusicFolderStoppedViewHolder {
ImageView icon;
TextView songName;
Button playButton;
TextView durationTV;
}
static class MusicFolderPlayingViewHolder {
ImageView icon;
TextView songName;
Button playButton;
TextView durationTV;
ProgressBar progressBar;
}
void setSelectedPosition(String[] selection) {
this.selected=selection;
notifyDataSetChanged();
}
public String[] getSelectedPosition() {
return this.selected;
}
public String getDirName() {
return this.dirName;
}
@Override
public int getViewTypeCount() {
return MAX_COUNT;
}
@Override
public int getCount() {
return data.size();
}
@Override
public ListViewDataItem getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
/**
* must return 0 <= int < getCount()
*/
@Override
public int getItemViewType(int position) {
return getItem(position).getType();
}
public void notifyDataSetChanged() {
mDataSetObservable.notifyChanged();
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isEmpty() {
return getCount() == 0;
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
mDataSetObservable.registerObserver(observer);
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
mDataSetObservable.unregisterObserver(observer);
}
@Override
public boolean areAllItemsEnabled() {
return true;
}
@Override
public boolean isEnabled(int position) {
return true;
}
public void updateTypeAndDuration(int position, int type, int duration) {
ListViewDataItem lvDataItem = getItem(position);
lvDataItem.setType(type);
lvDataItem.setDuration(duration);
notifyDataSetChanged();
}
public void updateProgressInFile(int positionInPage, int maxProgress, int progress) {
if(positionInPage < getCount()) {
ListViewDataItem lvDataItem = getItem(positionInPage);
lvDataItem.setDuration(maxProgress);
lvDataItem.setProgress(progress);
notifyDataSetChanged();
}
}
public void activatePlayingState(int positionInPage) {
if(positionInPage < getCount()) {
ListViewDataItem lvDataItem = getItem(positionInPage);
if(lvDataItem.getType() == Constants.MEDIA_FILE.TYPE.MUSIC_DIRECTORY_STOPPED_STATE) {
lvDataItem.setType(Constants.MEDIA_FILE.TYPE.MUSIC_DIRECTORY_PLAYING_STATE);
notifyDataSetChanged();
}
else if(lvDataItem.getType() == Constants.MEDIA_FILE.TYPE.MUSIC_FILE_STOPPED_STATE) {
lvDataItem.setType(Constants.MEDIA_FILE.TYPE.MUSIC_FILE_PLAYING_STATE);
notifyDataSetChanged();
}
}
}
public void clearPlayState() {
boolean stateChanged = false;
for(ListViewDataItem lvDataItem : data) {
if(lvDataItem.getType() == Constants.MEDIA_FILE.TYPE.MUSIC_DIRECTORY_PLAYING_STATE) {
lvDataItem.setType(Constants.MEDIA_FILE.TYPE.MUSIC_DIRECTORY_STOPPED_STATE);
stateChanged = true;
}
else if(lvDataItem.getType() == Constants.MEDIA_FILE.TYPE.MUSIC_FILE_PLAYING_STATE) {
lvDataItem.setType(Constants.MEDIA_FILE.TYPE.MUSIC_FILE_STOPPED_STATE);
stateChanged = true;
}
}
if(stateChanged) {
notifyDataSetChanged();
}
}
private class MyOnClickListener implements OnClickListener {
@Override
public void onClick(View v) {
Log.e("Clicked", (String)((ListViewDataItem)v.getTag()).getName());
Bundle bun = new Bundle();
bun.putString(Constants.BUNDLE_KEYS.PLAY_FILES, (String)((ListViewDataItem)v.getTag()).getPath());
Message message = Message.obtain(null, Constants.OP_CODE.PLAY_FILES);
message.setData(bun);
try {
mActivity.mService.send(message);
}
catch (RemoteException re) {
re.printStackTrace();
}
}
}
}
Here is a LogCat dump of me spamming the button inside the view at position 1, filename being 02 Maniac.flac
10-24 11:39:06.929: E/Clicked(21489): 02 Maniac.flac
10-24 11:39:06.949: E/TRYING TO PLAY(21489): /mnt/sdcard/Music/Caravan Palace/Caravan Palace - Panic (2012) FLAC/02 Maniac.flac
10-24 11:39:06.949: E/getView 01 Queens.flac(21489): pos: 0
10-24 11:39:07.049: E/getView 02 Maniac.flac(21489): pos: 1
10-24 11:39:07.069: E/getView 03 The dirty side of the street.flac(21489): pos: 2
10-24 11:39:07.069: E/getView 04 12 June 3049.flac(21489): pos: 3
10-24 11:39:07.069: E/getView 05 Rock it for me.flac(21489): pos: 4
10-24 11:39:07.069: E/getView 06 Clash.flac(21489): pos: 5
10-24 11:39:07.169: E/getView 01 Queens.flac(21489): pos: 0
10-24 11:39:07.169: E/getView 02 Maniac.flac(21489): pos: 1
10-24 11:39:07.169: E/getView 03 The dirty side of the street.flac(21489): pos: 2
10-24 11:39:07.179: E/getView 04 12 June 3049.flac(21489): pos: 3
10-24 11:39:07.179: E/getView 05 Rock it for me.flac(21489): pos: 4
10-24 11:39:07.179: E/getView 06 Clash.flac(21489): pos: 5
10-24 11:39:07.239: E/Clicked(21489): 02 Maniac.flac
10-24 11:39:07.259: E/Clicked(21489): 02 Maniac.flac
10-24 11:39:07.269: E/getView 01 Queens.flac(21489): pos: 0
10-24 11:39:07.269: E/TRYING TO PLAY(21489): /mnt/sdcard/Music/Caravan Palace/Caravan Palace - Panic (2012) FLAC/02 Maniac.flac
10-24 11:39:07.289: E/getView 02 Maniac.flac(21489): pos: 1
10-24 11:39:07.299: E/getView 03 The dirty side of the street.flac(21489): pos: 2
10-24 11:39:07.329: E/getView 04 12 June 3049.flac(21489): pos: 3
10-24 11:39:07.339: E/getView 05 Rock it for me.flac(21489): pos: 4
10-24 11:39:07.339: E/getView 06 Clash.flac(21489): pos: 5
10-24 11:39:07.409: W/MediaPlayer(21489): mediaplayer went away with unhandled events
10-24 11:39:07.419: E/TRYING TO PLAY(21489): /mnt/sdcard/Music/Caravan Palace/Caravan Palace - Panic (2012) FLAC/02 Maniac.flac
10-24 11:39:07.489: E/getView 01 Queens.flac(21489): pos: 0
10-24 11:39:07.499: E/getView 02 Maniac.flac(21489): pos: 1
10-24 11:39:07.499: E/getView 03 The dirty side of the street.flac(21489): pos: 2
10-24 11:39:07.519: E/getView 04 12 June 3049.flac(21489): pos: 3
10-24 11:39:07.519: E/getView 05 Rock it for me.flac(21489): pos: 4
10-24 11:39:07.539: E/getView 06 Clash.flac(21489): pos: 5
10-24 11:39:07.599: E/Clicked(21489): 05 Rock it for me.flac
10-24 11:39:07.619: E/getView 01 Queens.flac(21489): pos: 0
10-24 11:39:07.629: E/getView 02 Maniac.flac(21489): pos: 1
10-24 11:39:07.629: E/getView 03 The dirty side of the street.flac(21489): pos: 2
10-24 11:39:07.639: E/getView 04 12 June 3049.flac(21489): pos: 3
10-24 11:39:07.639: E/getView 05 Rock it for me.flac(21489): pos: 4
10-24 11:39:07.639: E/getView 06 Clash.flac(21489): pos: 5
10-24 11:39:07.699: E/Clicked(21489): 06 Clash.flac
10-24 11:39:07.709: E/Clicked(21489): 02 Maniac.flac
10-24 11:39:07.789: E/getView 01 Queens.flac(21489): pos: 0
10-24 11:39:07.799: E/getView 02 Maniac.flac(21489): pos: 1
10-24 11:39:07.809: E/getView 03 The dirty side of the street.flac(21489): pos: 2
10-24 11:39:07.809: E/TRYING TO PLAY(21489): /mnt/sdcard/Music/Caravan Palace/Caravan Palace - Panic (2012) FLAC/05 Rock it for me.flac
10-24 11:39:07.829: E/getView 04 12 June 3049.flac(21489): pos: 3
10-24 11:39:07.859: E/getView 05 Rock it for me.flac(21489): pos: 4
10-24 11:39:07.869: E/getView 06 Clash.flac(21489): pos: 5
10-24 11:39:08.039: D/dalvikvm(21489): GC_CONCURRENT freed 185K, 45% free 3396K/6087K, external 327K/839K, paused 5ms+6ms
10-24 11:39:08.049: E/getView 01 Queens.flac(21489): pos: 0
10-24 11:39:08.049: E/getView 02 Maniac.flac(21489): pos: 1
10-24 11:39:08.059: E/getView 03 The dirty side of the street.flac(21489): pos: 2
10-24 11:39:08.059: E/getView 04 12 June 3049.flac(21489): pos: 3
10-24 11:39:08.069: E/getView 05 Rock it for me.flac(21489): pos: 4
10-24 11:39:08.069: E/getView 06 Clash.flac(21489): pos: 5
10-24 11:39:08.129: E/Clicked(21489): 06 Clash.flac
10-24 11:39:08.129: E/Clicked(21489): 06 Clash.flac
10-24 11:39:08.159: E/Clicked(21489): 02 Maniac.flac
10-24 11:39:08.239: E/getView 01 Queens.flac(21489): pos: 0
10-24 11:39:08.249: E/getView 02 Maniac.flac(21489): pos: 1
10-24 11:39:08.259: E/TRYING TO PLAY(21489): /mnt/sdcard/Music/Caravan Palace/Caravan Palace - Panic (2012) FLAC/06 Clash.flac
10-24 11:39:08.259: E/getView 03 The dirty side of the street.flac(21489): pos: 2
10-24 11:39:08.259: E/getView 04 12 June 3049.flac(21489): pos: 3
10-24 11:39:08.289: E/getView 05 Rock it for me.flac(21489): pos: 4
10-24 11:39:08.319: E/getView 06 Clash.flac(21489): pos: 5
10-24 11:39:08.409: E/getView 01 Queens.flac(21489): pos: 0
10-24 11:39:08.419: E/getView 02 Maniac.flac(21489): pos: 1
10-24 11:39:08.419: E/getView 03 The dirty side of the street.flac(21489): pos: 2
10-24 11:39:08.419: E/getView 04 12 June 3049.flac(21489): pos: 3
10-24 11:39:08.429: E/getView 05 Rock it for me.flac(21489): pos: 4
10-24 11:39:08.429: E/getView 06 Clash.flac(21489): pos: 5
You can see the getView mehod being correctly called with the right position for every item:
10-24 11:39:06.949: E/getView 01 Queens.flac(21489): pos: 0
10-24 11:39:07.049: E/getView 02 Maniac.flac(21489): pos: 1
10-24 11:39:07.069: E/getView 03 The dirty side of the street.flac(21489): pos: 2
10-24 11:39:07.069: E/getView 04 12 June 3049.flac(21489): pos: 3
10-24 11:39:07.069: E/getView 05 Rock it for me.flac(21489): pos: 4
10-24 11:39:07.069: E/getView 06 Clash.flac(21489): pos: 5
But then on the button clicks, the getItem method is returning wrong items sometime (recall im spamming 02 Maniac.flac)
10-24 11:39:07.699: E/Clicked(21489): 06 Clash.flac
10-24 11:39:07.709: E/Clicked(21489): 02 Maniac.flac
--
10-24 11:39:07.599: E/Clicked(21489): 05 Rock it for me.flac
--
10-24 11:39:08.129: E/Clicked(21489): 06 Clash.flac
10-24 11:39:08.129: E/Clicked(21489): 06 Clash.flac
10-24 11:39:08.159: E/Clicked(21489): 02 Maniac.flac
This may have something to do with recycling views...?
I have a similar problem in a listview, but I haven't found a good solution, I keep looking for it.
As my listview will never contain more than 15 rows i'm using a very unnefective solution, not to recycle my rows, while i'm researching how to fix the problem.
这篇关于ListAdapter getView与位置错误值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!