在Android FirebaseRecyclerView中实现搜索用户功能时遇到的问题。

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

Problems in Android FirebaseRecyclerView Implementing A Search Users Function

问题

我想要实现一个搜索功能运行时logcat 提示我

> E/RecyclerView: 未附加适配器跳过布局

我在 Stack Overflow 和网络上搜索了答案告诉我我需要设置适配器和线性布局管理器从我的代码中您会看到我已经都设置了Alex Mamo@AlexMamo在这里的工作似乎指引我朝正确的方向前进但我仍然遇到错误

我的 Activity 类

```java
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import com.MyApp.Objects.ParticipantsObject;
import com.MyApp.R;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;

public class ParticipantsActivity extends AppCompatActivity {

    // ... 这里省略了一些变量和方法 ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_neighbors);

        // ... 这里省略了一些初始化操作 ...

        mSearchBtn.setOnClickListener(view -> {

            String searchText = mSearchField.getText().toString();
            firebaseUserSearch(searchText);

        });
    }

    // ... 这里省略了一些方法 ...

    private void firebaseUserSearch(String searchText) {
        Toast.makeText(ParticipantsActivity.this, "开始搜索", Toast.LENGTH_LONG).show();
        Query firebaseSearchQuery = mUserDatabase.orderByChild("name").startAt(searchText);

        FirebaseRecyclerOptions<ParticipantsObject> firebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<ParticipantsObject>()
                .setQuery(firebaseSearchQuery, ParticipantsObject.class)
                .build();

        class UserHolder extends RecyclerView.ViewHolder {
            // ... 这里省略了一些成员变量 ...

            UserHolder(View itemView) {
                super(itemView);
                // ... 这里省略了一些初始化操作 ...
            }

            void setUsers(ParticipantsObject participantsObject) {
                // ... 这里省略了一些操作 ...
            }
        }

        FirebaseRecyclerAdapter<ParticipantsObject, UserHolder> firebaseRecyclerAdapter;

        firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<ParticipantsObject, UserHolder>(firebaseRecyclerOptions) {
            @Override
            protected void onBindViewHolder(@NonNull UserHolder userHolder, int position, @NonNull ParticipantsObject participantsObject) {
                userHolder.setUsers(participantsObject);
            }

            @Override
            public UserHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_layout, parent, false);
                return new UserHolder(view);
            }
        };
        mResultList.setAdapter(firebaseRecyclerAdapter);
        firebaseRecyclerAdapter.startListening();
    }
}

我的 Activity XML 文件:

<!-- ... 这里省略了一些布局内容 ... -->

我的列表布局文件:

<!-- ... 这里省略了一些布局内容 ... -->

希望这对您有所帮助。如果您有任何问题,请随时提问。


<details>
<summary>英文:</summary>
I&#39;m looking to implement a search function. When it runs, logcat is telling me:
&gt; E/RecyclerView: No adapter attached; skipping layout.
I have searched SO and the net and the answers tell me that I need to set the adapter and the linear layout manager. As you will see with my code, I set both. Alex Mamo&#39;s (@AlexMamo) work on here seems to point me in the right direction but I&#39;m still getting the error. 
My Activity

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import com.MyApp.Objects.ParticipantsObject;
import com.MyApp.R;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;

public class ParticipantsActivity extends AppCompatActivity {

private EditText mSearchField;
private ImageButton mSearchBtn;
private RecyclerView mResultList;
private DatabaseReference mUserDatabase;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_neighbors);
mUserDatabase = FirebaseDatabase.getInstance().getReference().child(&quot;Users&quot;).child(&quot;Participants&quot;);
mSearchField = (EditText) findViewById(R.id.search_field);
mSearchBtn = (ImageButton) findViewById(R.id.search_btn);
mResultList = (RecyclerView) findViewById(R.id.result_list);
mResultList.setHasFixedSize(true);
mResultList.setLayoutManager(new LinearLayoutManager(this));
mSearchBtn.setOnClickListener(view -&gt; {
String searchText = mSearchField.getText().toString();
firebaseUserSearch(searchText);
});
}
private void firebaseUserSearch(String searchText) {
Toast.makeText(ParticipantsActivity.this, &quot;Started Search&quot;, Toast.LENGTH_LONG).show();
Query firebaseSearchQuery = mUserDatabase.orderByChild(&quot;name&quot;).startAt(searchText);
FirebaseRecyclerOptions&lt;ParticipantsObject&gt; firebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder&lt;ParticipantsObject&gt;()
.setQuery(firebaseSearchQuery, ParticipantsObject.class)
.build();
class UserHolder extends RecyclerView.ViewHolder {
private TextView imageThumbTextView, nameTextView     
UserHolder(View itemView) {
super(itemView);
imageThumbTextView = itemView.findViewById(R.id.profile_image);
nameTextView = itemView.findViewById(R.id.name_text);
}
void setUsers(ParticipantsObject participantsObject) {
String imageThumb = driverObject.getThumb_image();
imageThumbTextView.setText(imageThumb);
String name = participantsObject.getName();
nameTextView.setText(name);
}
}
FirebaseRecyclerAdapter&lt;ParticipantsObject, UserHolder&gt; firebaseRecyclerAdapter;
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter&lt;ParticipantsObject, UserHolder&gt;(firebaseRecyclerOptions) {
@Override
protected void onBindViewHolder(@NonNull UserHolder userHolder, int position, @NonNull ParticipantsObject participantsObject) {
userHolder.setUsers(participantsObject);
}
@Override
public UserHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_layout, parent, false);
return new UserHolder(view);
}
};
mResultList.setAdapter(firebaseRecyclerAdapter);
firebaseRecyclerAdapter.startListening();
}

}

My Activity XML file

<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
tools:context="com.MyApp.ParticipantsActivity">

    &lt;TextView
android:id=&quot;@+id/heading_label&quot;
android:layout_width=&quot;wrap_content&quot;
android:layout_height=&quot;wrap_content&quot;
android:layout_alignParentStart=&quot;true&quot;
android:layout_alignParentTop=&quot;true&quot;
android:layout_marginLeft=&quot;30dp&quot;
android:layout_marginTop=&quot;30dp&quot;
android:text=&quot;Firebase Search&quot;
android:textColor=&quot;#555555&quot;
android:textSize=&quot;24sp&quot; /&gt;
&lt;EditText
android:id=&quot;@+id/search_field&quot;
android:layout_width=&quot;wrap_content&quot;
android:layout_height=&quot;wrap_content&quot;
android:layout_alignStart=&quot;@+id/heading_label&quot;
android:layout_below=&quot;@+id/heading_label&quot;
android:layout_marginRight=&quot;20dp&quot;
android:layout_marginTop=&quot;20dp&quot;
android:layout_toStartOf=&quot;@+id/search_btn&quot;
android:background=&quot;@drawable/search_layout&quot;
android:ems=&quot;10&quot;
android:hint=&quot;Search here&quot;
android:inputType=&quot;textPersonName&quot;
android:paddingBottom=&quot;10dp&quot;
android:paddingLeft=&quot;20dp&quot;
android:paddingRight=&quot;20dp&quot;
android:paddingTop=&quot;10dp&quot;
android:textColor=&quot;#999999&quot;
android:textSize=&quot;16sp&quot; /&gt;
&lt;ImageButton
android:id=&quot;@+id/search_btn&quot;
android:layout_width=&quot;wrap_content&quot;
android:layout_height=&quot;wrap_content&quot;
android:layout_alignBottom=&quot;@+id/search_field&quot;
android:layout_alignParentEnd=&quot;true&quot;
android:layout_alignTop=&quot;@+id/search_field&quot;
android:layout_marginRight=&quot;30dp&quot;
android:background=&quot;@android:color/background_light&quot;
app:srcCompat=&quot;@mipmap/search_button&quot; /&gt;
&lt;androidx.recyclerview.widget.RecyclerView
android:id=&quot;@+id/result_list&quot;
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;match_parent&quot;
android:layout_below=&quot;@+id/search_field&quot;
android:layout_marginTop=&quot;50dp&quot;&gt;
&lt;/androidx.recyclerview.widget.RecyclerView&gt;
&lt;/RelativeLayout&gt;
My list layout 

<?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">

&lt;ImageView
android:id=&quot;@+id/profile_image&quot;
android:layout_width=&quot;80dp&quot;
android:layout_height=&quot;80dp&quot;
android:layout_alignParentStart=&quot;true&quot;
android:layout_alignParentTop=&quot;true&quot;
android:layout_marginLeft=&quot;30dp&quot;
android:layout_marginTop=&quot;20dp&quot;
app:srcCompat=&quot;@mipmap/ic_default_user&quot; /&gt;
&lt;TextView
android:id=&quot;@+id/name_text&quot;
android:layout_width=&quot;wrap_content&quot;
android:layout_height=&quot;wrap_content&quot;
android:layout_alignParentTop=&quot;true&quot;
android:layout_alignParentEnd=&quot;true&quot;
android:layout_marginStart=&quot;14dp&quot;
android:layout_marginLeft=&quot;20dp&quot;
android:layout_marginTop=&quot;50dp&quot;
android:layout_marginEnd=&quot;213dp&quot;
android:layout_marginRight=&quot;20dp&quot;
android:layout_toEndOf=&quot;@+id/profile_image&quot;
android:text=&quot;Username&quot;
android:textColor=&quot;#555555&quot;
android:textSize=&quot;16sp&quot; /&gt;

</RelativeLayout>


Any ideas or advice would be much appreciated. 
</details>
# 答案1
**得分**: 1
你的代码是在按钮被点击后才设置适配器的。因为你没有在RecyclerView第一次需要在屏幕上渲染自身之前设置它,所以它会通过日志中的消息向你发出警告。在渲染时,RecyclerView必须附加一个适配器,以便显示任何内容。
<details>
<summary>英文:</summary>
Your code is setting the adapter only after a button is pushed.  Because you didn&#39;t set it **before** the first time the RecyclerView needed to render itself on screen, it&#39;s going to warn you about that with the message you see in the log.  The RecyclerView must have an adapter attached at the time of rendering in order for it to display anything.
</details>

huangapple
  • 本文由 发表于 2020年3月16日 06:16:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/60698217.html
匿名

发表评论

匿名网友

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

确定