[英]When I changed even position image in listView then images of all even listView become same in android Java. Same with odd position images
我想这样做如果 listView 上的图像单击然后播放音频并且图标更改。 我为两者都正确编写了代码,但在更改图像时遇到了一个问题。 If I clicked on the position one image then the position image changed successfully but somehow the images of an odd number of listview also change to position 1 When I click on the position 2 image the position image changed but with that, all even number positions changed .
我想要什么当我点击 position 一个图像时,只有列表视图的图像会发生变化,而另一个将保持不变。
public class AllAudioAdapter extends BaseAdapter {
private Context context;
private int layout;
private ArrayList<VerseData> arrayList;
private MediaPlayer mediaPlayer;
private Boolean flag = true;
int first =-1;
ImageView previous;
public AllAudioAdapter(Context context, int layout, ArrayList<VerseData> arrayList) {
this.context = context;
this.layout = layout;
this.arrayList = arrayList;
}
@Override
public int getCount() {
return arrayList.size();
}
@Override
public Object getItem(int i) {
return i;
}
@Override
public long getItemId(int i) {
return i;
}
public static class ViewHolder {
public TextView number, eng_text, arabic_text;
public ImageView ivPlay;
public RelativeLayout relativeLayout;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView == null){
viewHolder = new ViewHolder();
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(layout, null);
viewHolder.number = (TextView) convertView.findViewById(R.id.number);
viewHolder.arabic_text = (TextView) convertView.findViewById(R.id.arabic_text);
viewHolder.eng_text = (TextView) convertView.findViewById(R.id.eng_text);
viewHolder.ivPlay = (ImageView) convertView.findViewById(R.id.play_pic);
viewHolder.relativeLayout =(RelativeLayout) convertView.findViewById(R.id.relative);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
VerseData verseData = arrayList.get(position);
viewHolder.number.setText(verseData.getNumber());
viewHolder.arabic_text.setText(verseData.getArabic());
viewHolder.eng_text.setText(verseData.getEnglish());
// play music
viewHolder.ivPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(flag ){
mediaPlayer = MediaPlayer.create(context, verseData.getAudio());
flag = false;
}
if(mediaPlayer.isPlaying()) {
if(first== position)
flag= true;
mediaPlayer.stop();
viewHolder.ivPlay.setImageResource(R.drawable.stop);
} else {
mediaPlayer.start();
viewHolder.ivPlay.setImageResource(R.drawable.play);
}
if(first!= position)
{
if(first!=-1)
{
differentPosition();
}
mediaPlayer.stop();
mediaPlayer = MediaPlayer.create(context, verseData.getAudio());
mediaPlayer.start();
viewHolder.ivPlay.setImageResource(R.drawable.play);
}
previous = viewHolder.ivPlay;
first = position;
}
});
return convertView;
}
public void showToaster(String s) {
Toast.makeText(context,s,Toast.LENGTH_SHORT).show();
}
public void differentPosition()
{
previous.setImageResource(R.drawable.stop);
}
}
您正在使用ViewHolder模式,而不是列表中的每个项目都有自己的View
,而是有一小部分可以重复使用。 当一个项目滚动出视图时,它的ViewHolder
可用于显示另一个正在滚动到视图中的项目。
所以这个新项目得到一个旧的ViewHolder
,它用于显示其他项目,并显示其所有数据 - 文本、图像等。 您需要更新所有这些,因此它显示新项目的正确数据 - 这是您在getView
中所做的,如果池需要另一个,则在创建新ViewHolder
的if
部分之后。
听起来您的游泳池有2 个ViewHolder
, A和B 。 因此,列表中的第一项使用 VH A ,第二项使用B ,第三项再次使用A ,第四项B ,依此类推。
当您单击ViewHolder A中显示的第一个项目时,单击侦听器会触发并执行此操作(其他内容已删除):
if(mediaPlayer.isPlaying()) {
viewHolder.ivPlay.setImageResource(R.drawable.stop);
} else {
viewHolder.ivPlay.setImageResource(R.drawable.play);
}
因此ViewHolder A 在您单击时会更新其图像。 但请记住, ViewHolder 会被重用,因此使用A 的每个项目都会显示该图像! 结果是图像取决于项目碰巧显示在哪个 ViewHolder 中,而不是项目本身。
因此,您需要为该项目存储一些正在播放/停止的state ,并让点击监听器更新该项目。 当您设置ViewHolder
以显示项目的详细信息、文本等时,您可以根据需要设置播放/停止图像。
假设一次只能播放一个项目,您可以只保留一个“正在播放”值:
// store the playing item (if any) in the top level of your adapter
VerseData nowPlaying = null;
在getView()
中,使用nowPlaying
来决定显示哪个图标
VerseData verseData = arrayList.get(position);
viewHolder.number.setText(verseData.getNumber());
...
if (verseData.equals(nowPlaying)) {
viewHolder.ivPlay.setImageResource(R.drawable.play);
} else {
// you -always- have to explicitly set the data -either way-,
// so it always shows the correct image - if it was play before, this will fix it
viewHolder.ivPlay.setImageResource(R.drawable.stop);
}
然后在你的点击监听器中更新正在播放的项目
if(mediaPlayer.isPlaying()) {
// stopping the playing item - clear the "now playing" value
nowPlaying = null
} else {
// otherwise set it to this item - this means any old "now playing" value
// will be replaced
nowPlaying = verseData
}
// since something's changed, items will need to refresh (so they can update their
// displays with the code in getView(), including displaying the correct image)
notifyDataSetChanged()
这是基础知识,您必须将其与代码的 rest 相匹配,但希望它有意义! 播放 state 是您数据的一部分,它与您的物品相关联。 ViewHolder
是临时的,您不应尝试将项目 state 存储在其中(例如设置图标),因为它们被重复用于不同的项目,因此它们要么被擦干净,要么显示旧的 state 对于它显示的项目不正确。
顺便说一句, RecyclerView
是执行此ViewHolder 模式的现代方式,并且使用起来更容易 - 您有单独的方法来创建新的 VH,并为项目设置其数据。 以防万一您将来需要这样做!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.