尝试更改列表项中 imageButton 的背景

trying to change background of imageButton in List item

Objective

我想在单击带有显示播放暂停(2 个图像)资源的 ImageButton(最初隐藏,单击时可见)的列表项时播放声音。 ImageButton只是为了向用户显示声音状态。

问题

当我滚动列表时,imageButton 再次消失。

代码

基础适配器

    private class ListAdapter extends BaseAdapter {
    private Context mContext;
    private LayoutInflater mInflater;
    ViewHolder holder;

    ListAdapter(Context context) {
        mContext = context;
        this.mInflater = LayoutInflater.from(mContext);

    }

    @Override
    public int getCount() {
        return indexTitles.size();
    }

    @Override
    public Object getItem(int position) {
        return indexTitles.get(position);
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.dua_row, null);
            holder.mainBg = (RelativeLayout) convertView.findViewById(R.id.duaBG);
            holder.title_text = (TextView) convertView.findViewById(R.id.title_text);
            holder.buttonPlayPause = (ImageButton) convertView.findViewById(R.id.imageButton);
            holder.buttonPlayPause.setFocusable(false);
            holder.buttonPlayPause.setFocusableInTouchMode(false);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        String leftRemoved = indexTitles.get(position).trim();
        holder.title_text.setText(leftRemoved);
        // /player selection
        if (playPos == position) {
            holder.buttonPlayPause.setBackgroundResource(R.drawable.buttonpause);
            holder.mainBg.setBackgroundColor(Color.parseColor("#000000"));
            holder.title_text.setTextColor(Color.parseColor("#D59D52"));
        } else {
            holder.buttonPlayPause.setVisibility(View.GONE);
            holder.title_text.setTextColor(Color.parseColor("#000000"));
            holder.mainBg.setBackgroundColor(Color.parseColor("#D59D52"));
        }
        return convertView;
    }

列表行

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
android:id="@+id/duaBG"
android:background="#D59D52">

<TextView
    android:layout_width="match_parent"
    android:layout_height="32dp"
    android:text=""
    android:textSize="18dp"
    android:id="@+id/title_text"
    android:ellipsize="end"
    android:maxLines="1"

    android:layout_alignParentTop="true"
    android:layout_marginLeft="@dimen/activity_horizontal_margin"
    android:layout_marginTop="@dimen/activity_horizontal_margin"
    android:layout_marginBottom="@dimen/activity_horizontal_margin"
    android:layout_toLeftOf="@+id/imageButton"
    android:layout_toStartOf="@+id/imageButton" />

<ImageButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/imageButton"
    android:focusable="false"
    android:visibility="gone"
    android:background="@drawable/buttonpause"
    android:layout_centerVertical="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true" />

<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="5dp"
    android:background="#000000"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"></LinearLayout>

OnItemClickListener

// indexTitles is ArrayList<String>
    indexTitles = getIndexTitles();
    final ListAdapter adapter = new ListAdapter(this);
    listView.setAdapter(adapter);
    listView.setOnItemClickListener(new OnItemClickListener() {


        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            final View v = view.findViewById(R.id.imageButton);
            v.setVisibility(View.VISIBLE);

            if (mediaPlayer.isPlaying() && playPos == position) {
                // pause mediaplayer
                mediaPlayer.pause();
                MEDIA_PAUSED = true;
                v.setBackgroundResource(R.drawable.buttonplay);

            } else if (MEDIA_PAUSED && !mediaPlayer.isPlaying() && playPos == position) {
                MEDIA_PAUSED = false;
                mediaPlayer.start();
                v.setBackgroundResource(R.drawable.buttonpause);
            } else if (!mediaPlayer.isPlaying() || mediaPlayer.isPlaying() && playPos != position) {
                // release and start from this position
                mediaPlayer.reset();
                v.setVisibility(View.VISIBLE);
                v.setBackgroundResource(R.drawable.buttonpause);
                String s = String.format("%03d", position + 2);
                String Path = SDCARD_PATH + "/DoaData/DD_" + s + ".mp3";
                playPos = position;
                adapter.notifyDataSetChanged();
                File file = new File(Path);
                Uri uri = Uri.fromFile(file);
                try {
                    mediaPlayer.setDataSource(context, uri);
                    mediaPlayer.prepare();
                    mediaPlayer.start();
                    mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mp) {
                            v.setBackgroundResource(R.drawable.buttonplay);
                        }
                    });
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    });

需要什么 我想让 imageButton 保持其播放或暂停状态。

谢谢

只需在 IF 语句中设置可见性,如下所示:

   if (playPos == position) {           
         holder.buttonPlayPause.setVisibility(View.VISIBLE);
         // further implementation
    } else {
        holder.buttonPlayPause.setVisibility(View.GONE);
        // further implementation
    }

出现问题,因为列表适配器回收旧视图。当一个视图不可见并且列表正在使用旧视图创建新视图时,您必须再次设置每个不同的 属性,否则前一个视图对象的所有属性都是 recycled/reused.

在@Thomas 和@shayan 的帮助下,我已经做到了

这就是我更改代码以获得所需内容的方式

        @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.dua_row, null);
            holder.mainBg = (RelativeLayout) convertView.findViewById(R.id.duaBG);
            holder.title_text = (TextView) convertView.findViewById(R.id.title_text);
            holder.buttonPlayPause = (ImageButton) convertView.findViewById(R.id.imageButton);
            holder.buttonPlayPause.setFocusable(false);
            holder.buttonPlayPause.setFocusableInTouchMode(false);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        String leftRemoved = indexTitles.get(position).trim();
        holder.title_text.setText(leftRemoved);
        // /player selection
        if (playPos == position) {
            if(MEDIA_PAUSED){
                holder.buttonPlayPause.setBackgroundResource(R.drawable.buttonplay);
            } else if(!MEDIA_PAUSED)  {
                holder.buttonPlayPause.setBackgroundResource(R.drawable.buttonpause);
            }

            holder.mainBg.setBackgroundColor(Color.parseColor("#000000"));
            holder.title_text.setTextColor(Color.parseColor("#D59D52"));
            holder.buttonPlayPause.setVisibility(View.VISIBLE);
        } else {
            holder.buttonPlayPause.setVisibility(View.GONE);
            holder.title_text.setTextColor(Color.parseColor("#000000"));
            holder.mainBg.setBackgroundColor(Color.parseColor("#D59D52"));
        }
        return convertView;
    }

并像这样更改了 onItemClick()

try {
                    mediaPlayer.setDataSource(context, uri);
                    mediaPlayer.prepare();
                    mediaPlayer.start();
                    MEDIA_PAUSED = false;

                    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

                    mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mp) {
                            v.setBackgroundResource(R.drawable.buttonplay);
                            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

                        }
                    });