如何在 RecyclerView 的选定项目上实现迷你均衡器?

huangapple go评论112阅读模式
英文:

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。

  1. public class StationViewAdapter extends RecyclerView.Adapter<StationViewAdapter.StationViewHolder> {
  2. List<Station> stations;
  3. final private ListItemClickListener mOnClickListener;
  4. public StationViewAdapter (List<Station> s, ListItemClickListener l)
  5. {
  6. stations = s;
  7. mOnClickListener = l;
  8. }
  9. @NonNull
  10. @Override
  11. public StationViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
  12. View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,parent,false);
  13. return new StationViewHolder(v);
  14. }
  15. @Override
  16. public void onBindViewHolder(@NonNull final StationViewHolder holder, int position) {
  17. Station station = stations.get(position);
  18. if(!station.getArtwork().isEmpty() && station.getArtwork() != null)
  19. {
  20. try{
  21. Picasso.get().load(Uri.parse(station.getArtwork()))
  22. // .placeholder(R.mipmap.ic_launcher)
  23. .into(holder.stationArtwork);
  24. } catch (Exception e) {
  25. e.printStackTrace();
  26. holder.stationArtwork.setImageResource(R.mipmap.ic_launcher);
  27. }
  28. }
  29. else
  30. holder.stationArtwork.setImageResource(R.mipmap.ic_launcher);
  31. holder.stationName.setText(station.getName());
  32. }
  33. @Override
  34. public int getItemCount() {
  35. return stations.size();
  36. }
  37. public class StationViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
  38. ImageView stationArtwork;
  39. TextView stationName;
  40. ImageButton stationPlayButton;
  41. EqualizerView equalizerView;
  42. int selectedItem;
  43. public StationViewHolder(@NonNull View itemView) {
  44. super(itemView);
  45. stationArtwork = itemView.findViewById(R.id.favicon);
  46. stationName = itemView.findViewById(R.id.text);
  47. stationPlayButton = itemView.findViewById(R.id.play_button);
  48. equalizerView = itemView.findViewById(R.id.equalizer_view);
  49. itemView.setOnClickListener(this);
  50. stationPlayButton.setOnClickListener(this);
  51. selectedItem = getAdapterPosition();
  52. }
  53. @Override
  54. public void onClick(View v) {
  55. int clickPosition = getAdapterPosition();
  56. Log.d(TAG, "onClick: " + getAdapterPosition());
  57. Log.d(TAG, "onClick: " + getLayoutPosition());
  58. Log.d(TAG, "onClick: " + getItemId());
  59. if(v == itemView) {
  60. mOnClickListener.onListItemClick(clickPosition);
  61. }else if(v == stationPlayButton)
  62. {
  63. mOnClickListener.onListItemPlay(clickPosition,stationPlayButton,equalizerView);
  64. }
  65. }
  66. }
  67. public interface ListItemClickListener {
  68. void onListItemClick(int clickedItemIndex);
  69. void onListItemPlay(int clickItemIndex,ImageButton i,EqualizerView eq);
  70. }
  71. }

这是主活动中的点击监听器:

  1. @Override
  2. public void onListItemClick(int clickedItemIndex) {
  3. if(mToast !=null)
  4. {
  5. mToast.cancel();
  6. }
  7. mToast = Toast.makeText(this,"Main Activity item clicked at position"+clickedItemIndex,Toast.LENGTH_SHORT);
  8. mToast.show();
  9. }
  10. @Override
  11. public void onListItemPlay(int clickItemIndex,ImageButton i , EqualizerView eq) {
  12. i.setVisibility(View.GONE);
  13. eq.setVisibility(View.VISIBLE);
  14. eq.animateBars();
  15. }
英文:

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.

  1. public class StationViewAdapter extends RecyclerView.Adapter&lt;StationViewAdapter.StationViewHolder&gt; {
  2. List&lt;Station&gt; statons;
  3. final private ListItemClickListener mOnClickListener;
  4. public StationViewAdapter (List&lt;Station&gt; s, ListItemClickListener l)
  5. {
  6. statons = s;
  7. mOnClickListener = l;
  8. }
  9. @NonNull
  10. @Override
  11. public StationViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
  12. View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,parent,false);
  13. return new StationViewHolder(v);
  14. }
  15. @Override
  16. public void onBindViewHolder(@NonNull final StationViewHolder holder, int position) {
  17. Station station = statons.get(position);
  18. if(!station.getArtwork().isEmpty() &amp;&amp; station.getArtwork() != null)
  19. {
  20. try{
  21. Picasso.get().load(Uri.parse(station.getArtwork()))
  22. // .placeholder(R.mipmap.ic_launcher)
  23. .into(holder.stationArtwork);
  24. } catch (Exception e) {
  25. e.printStackTrace();
  26. holder.stationArtwork.setImageResource(R.mipmap.ic_launcher);
  27. }
  28. }
  29. else
  30. holder.stationArtwork.setImageResource(R.mipmap.ic_launcher);
  31. holder.stationName.setText(station.getName());
  32. }
  33. @Override
  34. public int getItemCount() {
  35. return statons.size();
  36. }
  37. public class StationViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
  38. ImageView stationArtwork;
  39. TextView stationName;
  40. ImageButton stationPlayButton;
  41. EqualizerView equalizerView;
  42. int selectedItem;
  43. public StationViewHolder(@NonNull View itemView) {
  44. super(itemView);
  45. stationArtwork = itemView.findViewById(R.id.favicon);
  46. stationName = itemView.findViewById(R.id.text);
  47. stationPlayButton = itemView.findViewById(R.id.play_button);
  48. equalizerView = itemView.findViewById(R.id.equalizer_view);
  49. itemView.setOnClickListener(this);
  50. stationPlayButton.setOnClickListener(this);
  51. selectedItem = getAdapterPosition();
  52. }
  53. @Override
  54. public void onClick(View v) {
  55. int clickPosition = getAdapterPosition();
  56. Log.d(TAG, &quot;onClick: &quot;+getAdapterPosition());
  57. Log.d(TAG, &quot;onClick: &quot;+getLayoutPosition());
  58. Log.d(TAG, &quot;onClick: &quot;+getItemId());
  59. if(v == itemView) {
  60. mOnClickListener.onListItemClick(clickPosition);
  61. }else if(v == stationPlayButton)
  62. {
  63. mOnClickListener.onListItemPlay(clickPosition,stationPlayButton,equalizerView);
  64. }
  65. }
  66. }
  67. public interface ListItemClickListener {
  68. void onListItemClick(int clickedItemIndex);
  69. void onListItemPlay(int clickItemIndex,ImageButton i,EqualizerView eq);
  70. }
  71. }

These are ClickListeners in Main Activity

  1. @Override
  2. public void onListItemClick(int clickedItemIndex) {
  3. if(mToast !=null)
  4. {
  5. mToast.cancel();
  6. }
  7. mToast = Toast.makeText(this,&quot;Main Activity item clicked at position&quot;+clickedItemIndex,Toast.LENGTH_SHORT);
  8. mToast.show();
  9. }
  10. @Override
  11. public void onListItemPlay(int clickItemIndex,ImageButton i , EqualizerView eq) {
  12. i.setVisibility(View.GONE);
  13. eq.setVisibility(View.VISIBLE);
  14. eq.animateBars();
  15. }

答案1

得分: 0

RecyclerView会重复使用ViewHolder实例。您需要在onBindViewHolder内部使ViewHolder的状态无效。在您的情况下,您至少应该隐藏EqualizerView:

  1. @Override
  2. public void onBindViewHolder(@NonNull final StationViewHolder holder, int position) {
  3. equalizerView.setVisibility(View.INVISIBLE);
  4. // 其他操作
  5. }

此外,您还应该保存正在播放的歌曲,以便稍后初始化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:

  1. @Override
  2. public void onBindViewHolder(@NonNull final StationViewHolder holder, int position) {
  3. equalizerView.setVisibility(View.INVISIBLE);
  4. ....
  5. }

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

huangapple
  • 本文由 发表于 2020年5月4日 18:59:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/61590654.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定