繁体   English   中英

当我在 listView 中更改 position 图像时,所有甚至 listView 的图像在 android Java 中都变得相同。 与奇数 position 图像相同

[英]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中所做的,如果池需要另一个,则在创建新ViewHolderif部分之后。


听起来您的游泳池有2 个ViewHolderAB 因此,列表中的第一项使用 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM