【问题标题】:how to show and hide imageview inside recyclerView如何在recyclerView中显示和隐藏imageview
【发布时间】:2019-04-01 10:33:10
【问题描述】:

我正在使用 for 循环,并且我在回收站视图中显示了大约 20 个项目!现在我如何在 for 循环运行时隐藏/显示图像视图...这里 tts 工作正常,但是当我尝试使用它显示/隐藏时它没有发生..

目前使用下面的代码,一旦 for 循环结束整个 imageview 正在影响,我想要它一行 wis(显示当前(image1)和隐藏上一个 imageview(image))

我正在从主 Activity 类调用此方法,但图像视图显示或隐藏没有发生

活动

 ......
 ...... 
private void ConvertTextToSpeech() {
    // TODO Auto-generated method stub
   //items.forEach( Multiples obj ->  System.out.println());
    int z=0;
    View holder=null; ImageView imageView=null;ImageView imageView1=null;
    for (Multiples p : items) {

        if(z>0){

            holder = recyclerView.findViewHolderForAdapterPosition(z).itemView;
            holder.findViewById(R.id.image).setVisibility(View.VISIBLE);
            holder.findViewById(R.id.image1).setVisibility(View.INVISIBLE);
        }
        if(z < items.size()) {
              holder = recyclerView.findViewHolderForAdapterPosition(z).itemView;
              holder.findViewById(R.id.image).setVisibility(View.INVISIBLE);
            holder.findViewById(R.id.image1).setVisibility(View.VISIBLE);

        }
        text = p.first + "  " + p.getSecond() + " Za "+p.getResult()+".";
        tts.speak(text, TextToSpeech.QUEUE_ADD, null);
    z++;
    }

}

xml

  <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">


    <com.balysv.materialripple.MaterialRippleLayout
        android:id="@+id/lyt_parent"
        style="@style/RippleStyleBlack"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:focusable="true">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <View
                android:layout_width="match_parent"
                android:layout_height="1px"
                android:background="@color/grey_10" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center_vertical"
                android:orientation="horizontal"
                android:textAlignment="gravity" >

                <View
                    android:layout_width="@dimen/spacing_large"
                    android:layout_height="wrap_content" />

                <ImageView
                    android:id="@+id/image"
                    android:layout_width="35dp"
                    android:layout_height="35dp"
                    android:background="@android:color/transparent"
                    android:src="@drawable/ic_arrow_right" />

                <ImageView
                    android:id="@+id/image1"
                    android:layout_width="51dp"
                    android:layout_height="35dp"
                    android:background="@android:color/transparent"
                    android:src="@drawable/ic_arrow_right"
                    android:visibility="invisible" />

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:paddingBottom="@dimen/spacing_middle"
                    android:paddingTop="@dimen/spacing_middle">

                    <TextView
                        android:id="@+id/name"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginEnd="@dimen/spacing_middle"
                        android:layout_marginRight="@dimen/spacing_middle"
                        android:fontFamily="sans-serif-condensed"
                        android:gravity="center|left"
                        android:text="36"
                        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
                        android:textColor="@color/grey_80"
                        android:textSize="30sp"

                        />



                </LinearLayout>





                <View
                    android:layout_width="@dimen/spacing_large"
                    android:layout_height="match_parent" />


            </LinearLayout>

            <View
                android:layout_width="match_parent"
                android:layout_height="1px"
                android:background="@color/grey_10" />

        </LinearLayout>

    </com.balysv.materialripple.MaterialRippleLayout>

</RelativeLayout>

适配器

public class AdapterListAnimation extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<Multiples> items = new ArrayList<>();

    private Context ctx;
    private OnItemClickListener mOnItemClickListener;
    private int animation_type = 0;
    .........
    ......... 

【问题讨论】:

  • 如果我没记错的话,你早上问了同样的问题
  • 你需要存储你想要隐藏的位置,然后调用yourAdapter.notifyDataSetChanged(),然后在适配器的onBindViewHolder中根据你存储的数据更新可见性
  • @AshutoshSingh ha lekin pehele waala thoda alag thha,, yeah comment hatta do aap 我不认为这是英文,而且该网站只有英文
  • @VladyslavMatviienko 我无法理解你的建议,听起来不错。你能回答我吗,我是android的新手。逻辑代码对我有帮助
  • 没有。简而言之 - 你需要告诉适配器 数据模型中发生了一些变化,并且一旦你需要在那里改变一些东西,你需要重新绘制 RecyclerView。因此,当您需要隐藏某些内容时,只需将其存储在需要更改的项目的某些列表位置,然后致电adapter.notifyDataSetChanged()。而在onBindViewHolder 方法中的适配器内部,您需要显示与您保存的数据相对应的项目。如果不清楚,那么你需要一个关于listView和RecyclerView如何工作的教程,而StackOverflow不是找教程的地方。

标签: android android-recyclerview


【解决方案1】:

您只需在适配器中添加字段即可保存当前活动项目。然后拨打notifyDataSetChanged。 你也应该像这样更新你的onBindViewHolder:

private int currentPosition = -1;

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
    holder.textView.setText(items.get(position));
    if (currentPosition == position) {
        holder.img1.setVisibility(View.INVISIBLE);
        holder.img2.setVisibility(View.VISIBLE);
    } else {
        holder.img1.setVisibility(View.VISIBLE);
        holder.img2.setVisibility(View.INVISIBLE);
    }
}

public void setCurrentPosition(int currentPosition) {
    this.currentPosition = currentPosition;
}

我创建了一个测试项目来展示如何实现它。 Here 你可以看到它是如何工作的。 Here 是我的 github 仓库。

【讨论】:

    【解决方案2】:

    您不应使用以下内容直接更改适配器内的项目视图状态:

    holder = recyclerView.findViewHolderForAdapterPosition(z).itemView;
    holder.findViewById(R.id.image).setVisibility(View.VISIBLE);
    holder.findViewById(R.id.image1).setVisibility(View.INVISIBLE);
    

    相反,您需要使用特定方法告诉 RecyclerView 适配器您需要更改项目视图的状态。

    请注意,当需要绘制另一个项目时,RecylerView 自然地(以编程方式)将回收它的前一个项目。因此,无论是在模型中使用特定变量还是使用变量来保存每个项目的状态,您都需要保持每个项目的状态。

    如果您不想更改模型,可以使用 SparseBooleanArray 来保存状态。您可以在适配器中执行以下操作:

    public class YourAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    
        private List<Multiples> mItems;
    
        // We use this to hold the image state.
        private SparseBooleanArray mImageStates;
    
        public YourAdapter(List<Multiples> items) {
          this.mItems = items;
          mImageStates = new SparseBooleanArray();
    
          ...
        }
    
        @Override
        public YourAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
           ...
           return viewHolder;
        }
    
    
        @Override
        public void onBindViewHolder(ContactsAdapter.ViewHolder viewHolder, int position) {
    
          int itemPosition = viewHolder.getAdapterPosition();
          Multiples item = mItems.get(itemPosition);
    
          // Load the state by the previous saved state
          // default value is false.
          if(mImageStates.get(itemPosition)) {
            // show the images or something.
          } else {
            // hide the images or something.
          }
    
        }
    
        public void setState(int position, boolean isVisible) {
          mImageStates.put(position, isVisible);
    
        }
    
    }
    

    现在您可以通过以下方式更改状态项的可见性:

    yourAdapter.setState(yourItemPosition, true);
    

    然后将更改通知适配器:

    yourAdapter.notifyItemChanged(yourItemPosition);
    

    如果您更改了许多项目,则全部重置:

    yourAdapter.notifyDataSetChanged();
    

    【讨论】:

      【解决方案3】:

      你必须在 onbindholder 上写一个逻辑。

      onBindHolder(ViewHolder holder, int position){
       if(position %2==0)
        imageview.setVisibility(View.Visible);
       else 
        imageview.setVisibility(View.InVisible);
      }
      

      【讨论】:

      • 谢谢,但我无法理解您的回答!请帮我清楚
      • 我理解您的要求,即在偶数位置上显示图像,因此请为此编写逻辑。如果这不符合你离开它。
      • @AshutoshSingh 看看关于 RecyclerView 的文档,你就会明白。或者只是记住。如果它有“if”,它必须需要“else”。
      • 是的,我们可以应用你为什么在 Activity 类上编写适配器代码?他们有什么必要吗
      • 不要在活动上编写逻辑,只在适配器级别编写所有逻辑
      【解决方案4】:

      终于找到解决方案了

      我在您的倍数中添加了两个参数。在您的循环中,当条件为真时,我正在根据您对图像视图所做的设置变量。在我通知RecyclerView 之后。因此,onBindViewHolder 将出现回调。在那里我添加了显示/隐藏图像视图的条件。

      假设左箭头是image,右箭头是image1

      注意: Android 默认 TextToSpeech 不提供任何用于完成的事件侦听器。因此,我尝试了一个维护良好并提供Speech recognition 和Text to speech 功能的新库。

      Gradle:

      implementation 'net.gotev:speech:1.4.0'
      

      初始化:

      要开始使用该库,您必须在 Activity 中对其进行初始化。

      public class YourActivity extends Activity {
      
      private count = 0;
      private maxCount = 0;
      
          Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.your_layout);
      
              Speech.init(this, getPackageName());
              maxCount = items.size();
      
          }
      
          @Override
          protected void onDestroy() {
              // prevent memory leaks when activity is destroyed
              Speech.getInstance().shutdown();
          }
      }
      
      public class Multiples implements Serializable {
      
              private Boolean isShowimage = false;
              private Boolean isShowimage1 = false;
      
              public Boolean getShowimage() {
                  return isShowimage;
              }
      
              public void setShowimage(Boolean showimage) {
                  isShowimage = showimage;
              }
      
              public Boolean getShowimage1() {
                  return isShowimage1;
              }
      
              public void setShowimage1(Boolean showimage1) {
                  isShowimage1 = showimage1;
              }
          }
      
      private void ConvertTextToSpeech() {
      
          if (count < maxCount) {
      
              reset();
              String text = items.get(count).first + "  " + items.get(count).getSecond() + " Za " + items.get(count).getResult() + ".";
      
              Speech.getInstance().say(text, new TextToSpeechCallback() {
                  @Override
                  public void onStart() {
                      Log.i("speech", "speech started");
                      items.get(count).setShowimage(false);
                      items.get(count).setShowimage1(true);
      
                      adapter.notifyDataSetChanged();
                  }
      
                  @Override
                  public void onCompleted() {
                      Log.i("speech", "speech completed");
                      ConvertTextToSpeech();
                      count++;
                  }
      
                  @Override
                  public void onError() {
                      Log.i("speech", "speech error");
                  }
              });
          }
      }
      
      private void reset() {
          for (Multiples p : items) {
              p.setShowimage(true);
              p.setShowimage1(false);
          }
      }
      @Override
          public void onBindViewHolder(ViewHolder holder, int position) {
      
              final Multiples item = items.get(position);
      
              if (item.getShowimage()) {
                  holder.image.setVisibility(View.VISIBLE);
              } else {
                  holder.image.setVisibility(View.INVISIBLE);
              }
      
              if (item.getShowimage1()) {
                  holder.image1.setVisibility(View.VISIBLE);
              } else {
                  holder.image1.setVisibility(View.INVISIBLE);
              }
      
          }
      
      public static class ViewHolder extends RecyclerView.ViewHolder {
              private ImageView imageView,imageView1;
      
              public ViewHolder(View view) {
                  super(view);
                  this.imageView = (ImageView) view.findViewById(R.id.imageView);
                  this.imageView1 = (ImageView) view.findViewById(R.id.imageView1);
      
              }
          }
      

      【讨论】:

      • 在您的代码适配器上,“holder.findViewById..”无效。 findViewById 在持有人中没有任何方法。 .. 同样的问题我在这里提出了更多解释>>:stackoverflow.com/questions/55516858/…,请尝试帮助我
      • 不工作!我已经添加了您的代码,但它只是更新了第一行,请参阅您的代码输出的屏幕截图:my.jetscreenshot.com/demo/20190406-wszs-117kb.jpg 并根据文档Note that unlike ListView, RecyclerView will not call onBindViewHolder method again if the position of the item changes in the data set unless the item itself is invalidated or the new position cannot be determined.
      • 你能解释一下你在 ConvertTextToSpeech() 函数中的逻辑吗?
      • 你的意思是你想知道我期待什么输出?
      • 是的,我不明白你为什么要两个 if 条件?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多