微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

单击行中的按钮突出显示 ListView 中的一行

如何解决单击行中的按钮突出显示 ListView 中的一行

我是 Android 开发新手,正在创建音乐播放器应用。我已经完成了逻辑部分。现在我专注于应用程序的外观。我想要做的一件事是在单击行中相应的“播放”按钮时突出显示一行。

预期效果当点击一行的播放按钮时,该行会突出显示(背景颜色发生变化),同时最后点击的行的背景会重置。

尝试:我尝试存储之前选择的视图并在当前和之前的视图中进行必要的更改。

以下是我在自定义适配器中为 ListView 编写的代码

(相关代码写在按钮的onClickListener()中)

package com.example.mediaplayer;

import android.app.Activity;
import android.content.ContentUris;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.ArrayList;

public class MusicAdapter extends ArrayAdapter<Music> {

    private MediaPlayer mp;
    private ArrayList<Integer> Lengths = new ArrayList<>();
    private int mCurrentPosition = 0;
    private LinearLayout mprevIoUsView = null;
    private LinearLayout mitemView = null;
    private IAdapterToFragment listener;

    private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            releaseMediaPlayer();
            Lengths.set(mCurrentPosition,0);
            mitemView.setBackgroundColor(Color.parseColor("#fdbCA8"));
        }
    };

    public interface IAdapterToFragment {
        void onSuccess(String songName);
    }

    public MusicAdapter(Activity context,ArrayList<Music> songs,IAdapterToFragment listener) {

        super(context,songs);
        for(int i = 0; i < songs.size(); i ++) {
            Lengths.add(0);
        }

        this.listener = listener;
    }

    @Override
    public View getView(int position,View convertView,ViewGroup parent) {

        mprevIoUsView = mitemView;

        View musicItemView = convertView;

        if(musicItemView == null) {
            musicItemView = LayoutInflater.from(getContext()).inflate(
                    R.layout.music_item,parent,false);
        }

        Music currentSong = getItem(position);

        LinearLayout itemView = musicItemView.findViewById(R.id.item);
        mitemView = itemView;

        TextView songnameView = musicItemView.findViewById(R.id.song_name);
        songnameView.setText(currentSong.getMusicName());

        Button stop = (Button) musicItemView.findViewById(R.id.stop_button);
        Button pause = (Button) musicItemView.findViewById(R.id.pause_button);
        Button play = (Button) musicItemView.findViewById(R.id.play_button);

        play.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                releaseMediaPlayer();

                if(listener != null)
                    listener.onSuccess(currentSong.getMusicName());

                mCurrentPosition = position;

                itemView.setBackgroundColor(Color.parseColor("#FAA185"));

                long songID = currentSong.getMusicResourceId();
                Uri uri = ContentUris.withAppendedId(
                        android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,songID);
                mp = MediaPlayer.create(getContext(),uri);

                mp.start();
                mp.seekTo(Lengths.get(position));

                mp.setonCompletionListener(mCompletionListener);
            }
        });

        stop.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(listener != null)
                    listener.onSuccess("Play another song!");

                releaseMediaPlayer();
                itemView.setBackgroundColor(Color.parseColor("#fdbCA8"));
                Lengths.set(position,0);
            }
        });

        pause.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int currentPosition = 0;
                if(mp != null) {
                    currentPosition = mp.getCurrentPosition();
                    mp.stop();
                    Lengths.set(position,currentPosition);
                    releaseMediaPlayer();
//                    mp.setonCompletionListener(mCompletionListener);
                }
            }
        });

        return musicItemView;
    }

    private void releaseMediaPlayer() {
        if (mp != null) {
            mp.release();
            mp = null;

            if(mprevIoUsView != null)
                mprevIoUsView.setBackgroundColor(Color.parseColor("#fdbCA8"));

//            mp.abandonAudioFocus(mOnAudioFocuschangelistener);
        }
    }
}

但是这不起作用,因为 ListView 会回收视图。因此,我没有访问不同的行,而是同时对多行进行更改。

问题:

  1. 有没有一种方法可以在适配器类本身中唯一地访问 ListView 中的一行?

  2. 有没有更简单的方法来达到预期的效果

谢谢。

编辑:

经过大量研究,从相关问题中尝试了几种方法,我仍然没有想出一种方法来达到预期的效果。我尝试过的所有方法都会导致多行在单击一个按钮时突出显示,这又是由于视图的回收。如果您正在寻找替代解决方案,您可以:

  1. (非最优)用一些不回收视图的布局替换 ListView。这样,即使您滚动过去,也可以突出显示一个项目并保持突出显示

  2. 从列表中移除所有类型的按钮,创建一个列表项选择器并将其设置为你的list_item 的背景。按照此处提到的步骤操作:Reset background color in a ListView。这是我现在用于我的应用程序的一个

解决方法

将其设置为所有 ListView 项目的 Layout 具有相应的边界或具有透明颜色的任何内容。访问该特定项目后,只需将该小部件的颜色更改为其他颜色即可。一旦任务完成,不要忘记将颜色改回透明。您可以设置多个边界/随心所欲提供它是一个 ListView 项目而不是多个。还有其他方法可以解决这个问题,但在大多数情况下,这不是一个好的设计模式。

,

停止检查 convertView 是否为 null 将停止 ListView 的回收项视图,因此更改:

    View musicItemView = convertView;

    if(musicItemView == null) {
        musicItemView = LayoutInflater.from(getContext()).inflate(
                R.layout.music_item,parent,false);
    }

    View musicItemView = LayoutInflater.from(getContext()).inflate(R.layout.music_item,false);

然后用新视图创建每一行。

试试这个适配器代码:

public class MusicAdapter extends ArrayAdapter<Music> {

private MediaPlayer mp;
private ArrayList<Integer> Lengths = new ArrayList<>();
private int mCurrentPosition = -1; //Changed
//private LinearLayout mpreviousView = null;
private LinearLayout mitemView = null;
private IAdapterToFragment listener;

private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
    @Override
    public void onCompletion(MediaPlayer mp) {
        releaseMediaPlayer();
        Lengths.set(mCurrentPosition,0);
        mitemView.setBackgroundColor(Color.parseColor("#FDBCA8"));
        mitemView = null; //Added
        mCurrentPosition = -1; //Added
    }
};

public interface IAdapterToFragment {
    void onSuccess(String songName);
}

public MusicAdapter(Activity context,ArrayList<Music> songs,IAdapterToFragment listener) {

    super(context,songs);
    for(int i = 0; i < songs.size(); i ++) {
        Lengths.add(0);
    }

    this.listener = listener;
}

@Override
public View getView(int position,View convertView,ViewGroup parent) {

    //mpreviousView = mitemView;

    //View musicItemView = convertView;

    //if(musicItemView == null) {
        View musicItemView = LayoutInflater.from(getContext()).inflate(R.layout.music_item,false);
    //}

    Music currentSong = getItem(position);

    LinearLayout itemView = musicItemView.findViewById(R.id.item);
    mitemView = itemView;

    TextView songnameView = musicItemView.findViewById(R.id.song_name);
    songnameView.setText(currentSong.getMusicName());
    if (mCurrentPosition == position) itemView.setBackgroundColor(Color.parseColor("#FAA185")); //Added

    Button stop = (Button) musicItemView.findViewById(R.id.stop_button);
    Button pause = (Button) musicItemView.findViewById(R.id.pause_button);
    Button play = (Button) musicItemView.findViewById(R.id.play_button);

    play.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            releaseMediaPlayer();

            if(listener != null)
                listener.onSuccess(currentSong.getMusicName());

            mCurrentPosition = position;

            itemView.setBackgroundColor(Color.parseColor("#FAA185"));
            mitemView = itemView; //Added

            long songID = currentSong.getMusicResourceId();
            Uri uri = ContentUris.withAppendedId(
                    android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,songID);
            mp = MediaPlayer.create(getContext(),uri);

            mp.start();
            mp.seekTo(Lengths.get(position));

            mp.setOnCompletionListener(mCompletionListener);
        }
    });

    stop.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(listener != null)
                listener.onSuccess("Play another song!");

            releaseMediaPlayer();
            itemView.setBackgroundColor(Color.parseColor("#FDBCA8"));
            Lengths.set(position,0);
            mitemView = null; //Added
        }
    });

    pause.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int currentPosition = 0;
            if(mp != null) {
                currentPosition = mp.getCurrentPosition();
                mp.stop();
                Lengths.set(position,currentPosition);
                releaseMediaPlayer();
//                    mp.setOnCompletionListener(mCompletionListener);
            }
        }
    });

    return musicItemView;
}

private void releaseMediaPlayer() {
    if (mp != null) {
        mp.release();
        mp = null;

        if (mitemView != null) //Changed
            mitemView.setBackgroundColor(Color.parseColor("#FDBCA8")); //Changed

//            mp.abandonAudioFocus(mOnAudioFocusChangeListener);
    }
}
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?