英文:
How to implement mini equalizer on selected item of RecyclerView?
问题
我有一个RecyclerView
,其listitem
的设计如下:
LinearLayout
(水平布局)- 图像视图(
ImageView
) - 文本视图(
TextView
) - 图像按钮(播放按钮)(
ImageButton
) - 均衡器视图(不可见)(
EqualizerView
)
- 图像视图(
现在,当我点击播放按钮时,应该隐藏播放按钮,并显示均衡器,如果我滚动列表,均衡器应该始终停留在所选项目上。
然而,我面临的问题是均衡器视图以每隔 10 个项目的间隔显示。也就是说,如果我点击第 3 个项目,那么均衡器将显示在第 3、13 等位置...
我正在使用这个库来实现迷你均衡器:https://github.com/claucookie/mini-equalizer-library-android。
public class StationViewAdapter extends RecyclerView.Adapter<StationViewAdapter.StationViewHolder> {
List<Station> stations;
final private ListItemClickListener mOnClickListener;
public StationViewAdapter (List<Station> s, ListItemClickListener l)
{
stations = s;
mOnClickListener = l;
}
@NonNull
@Override
public StationViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,parent,false);
return new StationViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull final StationViewHolder holder, int position) {
Station station = stations.get(position);
if(!station.getArtwork().isEmpty() && station.getArtwork() != null)
{
try{
Picasso.get().load(Uri.parse(station.getArtwork()))
// .placeholder(R.mipmap.ic_launcher)
.into(holder.stationArtwork);
} catch (Exception e) {
e.printStackTrace();
holder.stationArtwork.setImageResource(R.mipmap.ic_launcher);
}
}
else
holder.stationArtwork.setImageResource(R.mipmap.ic_launcher);
holder.stationName.setText(station.getName());
}
@Override
public int getItemCount() {
return stations.size();
}
public class StationViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView stationArtwork;
TextView stationName;
ImageButton stationPlayButton;
EqualizerView equalizerView;
int selectedItem;
public StationViewHolder(@NonNull View itemView) {
super(itemView);
stationArtwork = itemView.findViewById(R.id.favicon);
stationName = itemView.findViewById(R.id.text);
stationPlayButton = itemView.findViewById(R.id.play_button);
equalizerView = itemView.findViewById(R.id.equalizer_view);
itemView.setOnClickListener(this);
stationPlayButton.setOnClickListener(this);
selectedItem = getAdapterPosition();
}
@Override
public void onClick(View v) {
int clickPosition = getAdapterPosition();
Log.d(TAG, "onClick: " + getAdapterPosition());
Log.d(TAG, "onClick: " + getLayoutPosition());
Log.d(TAG, "onClick: " + getItemId());
if(v == itemView) {
mOnClickListener.onListItemClick(clickPosition);
}else if(v == stationPlayButton)
{
mOnClickListener.onListItemPlay(clickPosition,stationPlayButton,equalizerView);
}
}
}
public interface ListItemClickListener {
void onListItemClick(int clickedItemIndex);
void onListItemPlay(int clickItemIndex,ImageButton i,EqualizerView eq);
}
}
这是主活动中的点击监听器:
@Override
public void onListItemClick(int clickedItemIndex) {
if(mToast !=null)
{
mToast.cancel();
}
mToast = Toast.makeText(this,"Main Activity item clicked at position"+clickedItemIndex,Toast.LENGTH_SHORT);
mToast.show();
}
@Override
public void onListItemPlay(int clickItemIndex,ImageButton i , EqualizerView eq) {
i.setVisibility(View.GONE);
eq.setVisibility(View.VISIBLE);
eq.animateBars();
}
英文:
I have a recyclerview whose listitem is designed as follows
- LinearLayout(Horizontal)
- ImageView
- TextView
- ImageButton(PlayButton)
- EqualizerView(Invisible)
Now when I click on PlayButton, it should hide and equalizer show be displayed and if I scroll the list, equalizer should stay on selected item only.
However, I am facing problem that EqualizerView is being displayed at interval of 10 items. That is if I click on 3rd item then equalizer will be displayed on 3rd,13th and so on..
I am using this https://github.com/claucookie/mini-equalizer-library-android library for implementing mini equalizer.
public class StationViewAdapter extends RecyclerView.Adapter<StationViewAdapter.StationViewHolder> {
List<Station> statons;
final private ListItemClickListener mOnClickListener;
public StationViewAdapter (List<Station> s, ListItemClickListener l)
{
statons = s;
mOnClickListener = l;
}
@NonNull
@Override
public StationViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,parent,false);
return new StationViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull final StationViewHolder holder, int position) {
Station station = statons.get(position);
if(!station.getArtwork().isEmpty() && station.getArtwork() != null)
{
try{
Picasso.get().load(Uri.parse(station.getArtwork()))
// .placeholder(R.mipmap.ic_launcher)
.into(holder.stationArtwork);
} catch (Exception e) {
e.printStackTrace();
holder.stationArtwork.setImageResource(R.mipmap.ic_launcher);
}
}
else
holder.stationArtwork.setImageResource(R.mipmap.ic_launcher);
holder.stationName.setText(station.getName());
}
@Override
public int getItemCount() {
return statons.size();
}
public class StationViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView stationArtwork;
TextView stationName;
ImageButton stationPlayButton;
EqualizerView equalizerView;
int selectedItem;
public StationViewHolder(@NonNull View itemView) {
super(itemView);
stationArtwork = itemView.findViewById(R.id.favicon);
stationName = itemView.findViewById(R.id.text);
stationPlayButton = itemView.findViewById(R.id.play_button);
equalizerView = itemView.findViewById(R.id.equalizer_view);
itemView.setOnClickListener(this);
stationPlayButton.setOnClickListener(this);
selectedItem = getAdapterPosition();
}
@Override
public void onClick(View v) {
int clickPosition = getAdapterPosition();
Log.d(TAG, "onClick: "+getAdapterPosition());
Log.d(TAG, "onClick: "+getLayoutPosition());
Log.d(TAG, "onClick: "+getItemId());
if(v == itemView) {
mOnClickListener.onListItemClick(clickPosition);
}else if(v == stationPlayButton)
{
mOnClickListener.onListItemPlay(clickPosition,stationPlayButton,equalizerView);
}
}
}
public interface ListItemClickListener {
void onListItemClick(int clickedItemIndex);
void onListItemPlay(int clickItemIndex,ImageButton i,EqualizerView eq);
}
}
These are ClickListeners in Main Activity
@Override
public void onListItemClick(int clickedItemIndex) {
if(mToast !=null)
{
mToast.cancel();
}
mToast = Toast.makeText(this,"Main Activity item clicked at position"+clickedItemIndex,Toast.LENGTH_SHORT);
mToast.show();
}
@Override
public void onListItemPlay(int clickItemIndex,ImageButton i , EqualizerView eq) {
i.setVisibility(View.GONE);
eq.setVisibility(View.VISIBLE);
eq.animateBars();
}
答案1
得分: 0
RecyclerView会重复使用ViewHolder实例。您需要在onBindViewHolder内部使ViewHolder的状态无效。在您的情况下,您至少应该隐藏EqualizerView:
@Override
public void onBindViewHolder(@NonNull final StationViewHolder holder, int position) {
equalizerView.setVisibility(View.INVISIBLE);
// 其他操作
}
此外,您还应该保存正在播放的歌曲,以便稍后初始化ViewHolder的状态。
更多信息请参见:https://developer.android.com/guide/topics/ui/layout/recyclerview#structure
英文:
RecyclerView reuses ViewHolder instances. You need to invalidate ViewHolder state inside onBindViewHolder. In your case you should hide EqulizerView at least:
@Override
public void onBindViewHolder(@NonNull final StationViewHolder holder, int position) {
equalizerView.setVisibility(View.INVISIBLE);
....
}
Also, you should save which songs are playing to initialize ViewHolder state later.
More info at: https://developer.android.com/guide/topics/ui/layout/recyclerview#structure
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论