RecyclerView 使用连续数据更新最后位置

RecyclerView update last position with continuous data

首先,当我拿到我的电脑时,我会 post 编码。

我正在尝试从语音识别数据中添加和更新 RecyclerView。 对于 SpeechRecognition,我使用 Google Cloud Speech 每次 Speech 完成时,我都会做一个 "Chat - view" 并将结果添加到 RecyclerView。我想通过在识别 onVoice() 时添加新项目来修改它,并在识别语音时更新它(结果仍然不是最终的)

我的方法是:由于 SpeechRecognition 是由语音触发的,因此添加了新项目 (onVoiceStart) 作为识别器 onVoice 回调被触发(新语音数据块被识别)我将删除 RecyclerViews 最后一项并添加 "chunk" 到最后一个位置,然后调用 adapter.notifyItemChanged(speechResults.size()-1)

解决方案一:

     // Step 1: find the holder 
 RecyclerView.ViewHolder holder = recyclerView.findViewHolderForAdapterPosition(speechResults.size() - 1);

     //   Step 2: Check if the holder is not null and if has itemView .
    if (holder != null) {

        if (holder.itemView != null) {
            // from itemview find the TextView  and set the desired text :
            if (holder.getAdapterPosition() == speechResults.size() - 1) {
                ((TextView) holder.itemView.findViewById(R.id.speech_sent_textView))
                        .setText(text);
            }
        }
 // Now update the adapter item also but do not notify the adapter change.

解决方案二:使用库 LastAdapter

  1. 添加依赖->跟随this

  2. 在布局中添加新的根标签"<布局"

                //Delte the space after "<"
      < layout xmlns:android="http://schemas.android.com/apk/res/android">
    
    <data>
        <variable name="item" type="com.github.nitrico.lastadapterproject.item.Header"/>
    </data>
    
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
    
        // you use  like thius "@{youritem.speecSent"
        android:text="@{item.text}"/>
        //Delte the space after "< "
     < /layout>
    

    注意:要使用多个布局,数据标签必须具有相同的变量名称。

       <data>   
           // this name has to be same in every xml layout types.
        <variable name="item" type="com.github.nitrico.lastadapterproject.item.Header"/>
        </data>
    
  3. Java部分: 注意:listOfItems 必须是 Observable ArrayList

      speechResults = new ObservableArrayList<>();
         ...
        new LastAdapter(speechResults , BR.item)
       .map(SpeechResult.class, R.layout.speech_sent)
       .map(SpeechResult.class, R.layout.speech_received)
       .into(recyclerView);
    

BR.item -> 您必须在构建 Gradle 中启用数据绑定。 .item - > 是数据布局中给出的名称(必须相同)

如果您想使用相同的项目类型处理 LayoutType (Class)

            new LastAdapter(speechResults, BR.item )
            .map(SpeechResult.class, R.layout.speech_sent_content)
            .map(SpeechResult.class, R.layout.speech_received_content)
              .handler(new TypeHandler() {
                  @Nullable
                  @Override
                  public BaseType getItemType(Object o, int i) {
                      if(((SpeechResult) o).getSpeechType()==SpeechResult.SPEECH_TYPE_SENT){
                          return new BaseType(R.layout.speech_sent_content);
                      }
                      return new BaseType(R.layout.speech_received_content);
                  }
              })

            .into(recyclerView);

在 recyclerView 中添加新项目 只需将项目添加到您的项目列表中。 LastAdapter 将处理数据的刷新。