После обновления синтаксиса FirebaseUI не может работать без метода onPopulateViewHolder. Я прочитал документ FirebaseUI и сделал то же самое. После запуска приложения RecycleView работает без ошибок, но пусто. Данные моей Firebase не появились. Я читал, что распространенная ошибка в том, что RecycleView использовал параметр wrap content или setHasFixedSize(true). Я сделал все так же, но RecycleView все еще пустой. Что не так?
1.Грейд:
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.example.eugene.lafinalproduction"
minSdkVersion 15
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//noinspection GradleCompatible
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
implementation 'com.google.firebase:firebase-database:15.0.0'
implementation 'com.google.firebase:firebase-storage:15.0.0'
implementation 'com.google.firebase:firebase-auth:15.0.0'
implementation 'com.firebaseui:firebase-ui-database:3.2.2'
implementation 'com.android.support:recyclerview-v7:27.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-
core:3.0.1'
//Glide library
implementation 'com.github.bumptech.glide:glide:4.7.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
}
apply plugin: 'com.google.gms.google-services'
2.Recycle_activity.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"
xmlns:tools = "http://schemas.android.com/tools"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
tools:context = ".Recycle_activity">
<android.support.v7.widget.RecyclerView
android:id = "@+id/list_result"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
android:layout_centerInParent = "true"
android:scrollbars = "vertical"/>
</RelativeLayout>
Item_list.xml - каждая моя строка в RV.
<?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 = "match_parent">
<ImageView
android:id = "@+id/image_id"
android:layout_width = "330dp"
android:layout_height = "200dp"
android:layout_alignParentTop = "true"
android:layout_centerHorizontal = "true"
app:srcCompat = "@drawable/img_2" />
<TextView
android:id = "@+id/text_image_id"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentTop = "true"
android:layout_centerHorizontal = "true"
android:layout_marginTop = "24dp"
android:textColor = "@color/myTextColor"
android:textSize = "85sp" />
Recycle_activity.java, с onCreate, RecycleViewAdapter, ViewHolder
public class Recycle_activity extends AppCompatActivity {
private RecyclerView mResultList;
private DatabaseReference mPlaceDatabase;
private Query query;
private FirebaseRecyclerAdapter<Places, PlaceViewHolder> firebaseRecyclerAdapter;
private DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
private DatabaseReference usersRef = rootRef.child("Users");
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycle_activity);
mResultList = findViewById(R.id.list_result);
mPlaceDatabase = FirebaseDatabase.getInstance().getReference();
query = mPlaceDatabase.child("Users");
//mResultList.setHasFixedSize(true);
mResultList.setLayoutManager(new LinearLayoutManager(this));
//mLinearLayouManager = new LinearLayoutManager(this);
FirebaseRecyclerOptions<Places> options =
new FirebaseRecyclerOptions.Builder<Places>()
.setQuery(query, Places.class)
.build();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Places, PlaceViewHolder>(options) {
@Override
protected void onBindViewHolder(PlaceViewHolder holder, int position, Places model) {
holder.setDetails(getApplicationContext(), model.getName(), model.getImage());
Toast.makeText(getApplicationContext(), model.getName(), Toast.LENGTH_SHORT).show();
}
@Override
public PlaceViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_layout, parent, false);
return new PlaceViewHolder(view);
}
};
mResultList.setAdapter(firebaseRecyclerAdapter);
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String name = ds.child("name").getValue(String.class);
Log.d("TAG", name);
Toast.makeText(getApplicationContext(), name, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
};
usersRef.addListenerForSingleValueEvent(valueEventListener);
}
@Override
protected void onStart() {
super.onStart();
firebaseRecyclerAdapter.startListening();
}
class PlaceViewHolder extends RecyclerView.ViewHolder {
View mView;
public PlaceViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setDetails(Context context, String placeName, String placeImage) {
TextView place_Name = mView.findViewById(R.id.image_id);
ImageView place_Image = mView.findViewById(R.id.text_image_id);
place_Name.setText(placeName);
Glide.with(context).load(placeImage).into(place_Image);
}
}
@Override
protected void onStop() {
super.onStop();
if (firebaseRecyclerAdapter != null) {
firebaseRecyclerAdapter.stopListening();
}
}
}
Places.java с getters, setters:
public class Places {
public String name_place, image_place;
public Places() {
}
public String getName_place() {
return name_place;
}
public void setName_place(String name_place) {
this.name_place = name_place;
}
public String getImage_place() {
return image_place;
}
public void setImage_place(String image_place) {
this.image_place = image_place;
}
public Places(String name_place, String image_place) {
this.name_place = name_place;
this.image_place = image_place;
}
}
И моя база данных Firebase: База данных экранов
p.s. Проверены все правила .write .read.
Обновлять:
public class Recycle_activity extends AppCompatActivity {
private RecyclerView mResultList;
private DatabaseReference mPlaceDatabase;
private Query query;
private FirebaseRecyclerAdapter<Places, PlaceViewHolder> firebaseRecyclerAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycle_activity);
mResultList = findViewById(R.id.list_result);
mPlaceDatabase = FirebaseDatabase.getInstance().getReference();
query = mPlaceDatabase.child("Users");
//mResultList.setHasFixedSize(true);
mResultList.setLayoutManager(new LinearLayoutManager(this));
//mLinearLayouManager = new LinearLayoutManager(this);
FirebaseRecyclerOptions<Places> options =
new FirebaseRecyclerOptions.Builder<Places>()
.setQuery(query, Places.class)
.build();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Places, PlaceViewHolder>(options) {
@Override
protected void onBindViewHolder(PlaceViewHolder holder, int position, Places model) {
holder.setDetails(getApplicationContext(), model.getName(), model.getImage());
}
@Override
public PlaceViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_layout, parent, false);
return new PlaceViewHolder(view);
}
};
mResultList.setAdapter(firebaseRecyclerAdapter);
}
@Override
protected void onStart() {
super.onStart();
firebaseRecyclerAdapter.startListening();
}
class PlaceViewHolder extends RecyclerView.ViewHolder {
View mView;
public PlaceViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setDetails(Context context, String placeName, String placeImage) {
TextView place_Name = mView.findViewById(R.id.image_id);
ImageView place_Image = mView.findViewById(R.id.text_image_id);
place_Name.setText(placeName);
Glide.with(context).load(placeImage).into(place_Image);
}
}
@Override
protected void onStop() {
super.onStop();
if (firebaseRecyclerAdapter != null) {
firebaseRecyclerAdapter.stopListening();
}
}
}
Обновленная база данных и хранилище:
Firebase Database,
Database Rules,
Firebase Storage,
Storage Rules.
Журналы после запуска:
04-24 01:17:41.304 7093-7093/? I/art: Late-enabling -Xcheck:jni
04-24 01:17:41.345 7093-7093/com.example.eugene.lafinalproduction W/ResourceType: Found multiple library tables, ignoring...
04-24 01:17:41.353 7093-7093/com.example.eugene.lafinalproduction W/System: ClassLoader referenced unknown path: /data/app/com.example.eugene.lafinalproduction-2/lib/arm64
04-24 01:17:41.396 7093-7093/com.example.eugene.lafinalproduction W/ComponentDiscovery: Application info not found.
Could not retrieve metadata, returning empty list of registrars.
04-24 01:17:41.439 7093-7093/com.example.eugene.lafinalproduction I/FirebaseInitProvider: FirebaseApp initialization successful
04-24 01:17:41.477 7093-7093/com.example.eugene.lafinalproduction W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
04-24 01:17:41.524 7093-7110/com.example.eugene.lafinalproduction I/FA: App measurement is starting up, version: 12451
To enable debug logging run: adb shell setprop log.tag.FA VERBOSE
To enable faster debug mode event logging run:
adb shell setprop debug.firebase.analytics.app com.example.eugene.lafinalproduction
04-24 01:17:41.589 7093-7112/com.example.eugene.lafinalproduction I/DynamiteModule: Considering local module com.google.android.gms.firebase_database:4 and remote module com.google.android.gms.firebase_database:6
Selected remote version of com.google.android.gms.firebase_database, version >= 6
04-24 01:17:41.606 7093-7112/com.example.eugene.lafinalproduction W/ResourceType: Found multiple library tables, ignoring...
04-24 01:17:41.607 7093-7110/com.example.eugene.lafinalproduction I/FA: Tag Manager is not found and thus will not be used
04-24 01:17:41.613 7093-7093/com.example.eugene.lafinalproduction I/[MALI][Gralloc]: [+]r_hnd(0x7f9d259920), client(37), share_fd(34)
04-24 01:17:41.627 7093-7112/com.example.eugene.lafinalproduction W/System: ClassLoader referenced unknown path: /data/data/com.google.android.gms/app_chimera/m/00000018/n/arm64-v8a
04-24 01:17:41.642 7093-7112/com.example.eugene.lafinalproduction W/ResourceType: Found multiple library tables, ignoring...
04-24 01:17:41.685 7093-7102/com.example.eugene.lafinalproduction I/System: FinalizerDaemon: finalize objects = 1
04-24 01:17:41.689 7093-7113/com.example.eugene.lafinalproduction E/GED: Failed to get GED Log Buf, err(0)
04-24 01:17:41.689 7093-7113/com.example.eugene.lafinalproduction I/OpenGLRenderer: Initialized EGL, version 1.4
04-24 01:17:41.699 7093-7113/com.example.eugene.lafinalproduction I/OpenGLRenderer: Get enable program binary service property (1)
Initializing program atlas...
04-24 01:17:41.700 7093-7113/com.example.eugene.lafinalproduction I/OpenGLRenderer: Program binary detail: Binary length is 146348, program map length is 128.
Succeeded to mmap program binaries. File descriptor is 42, and path is /dev/ashmem�.
No need to use file discriptor anymore, close fd(42).
04-24 01:17:41.709 7093-7113/com.example.eugene.lafinalproduction W/libEGL: [ANDROID_RECORDABLE] format: 1
04-24 01:17:41.710 7093-7113/com.example.eugene.lafinalproduction I/PerfService: PerfServiceNative api init
04-24 01:17:41.716 7093-7113/com.example.eugene.lafinalproduction I/[MALI][Gralloc]: [+]r_hnd(0x7fa7631fa0), client(37), share_fd(44)
04-24 01:17:41.738 7093-7113/com.example.eugene.lafinalproduction I/[MALI][Gralloc]: [+]r_hnd(0x7fa7631aa0), client(37), share_fd(47)
04-24 01:17:41.741 7093-7131/com.example.eugene.lafinalproduction I/System.out: [CDS][DNS] getAllByNameImpl netId = 0
04-24 01:17:41.741 7093-7131/com.example.eugene.lafinalproduction D/libc-netbsd: [getaddrinfo]: netid=0; mark=0
04-24 01:17:41.742 7093-7131/com.example.eugene.lafinalproduction D/libc-netbsd: [getaddrinfo]: ai_addrlen=0; ai_canonname=(null); ai_flags=4; ai_family=0
[getaddrinfo]: netid=0; mark=0
[getaddrinfo]: ai_addrlen=0; ai_canonname=(null); ai_flags=1024; ai_family=0
04-24 01:17:41.743 7093-7093/com.example.eugene.lafinalproduction I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@5d4e48d time:222822867
04-24 01:17:41.746 7093-7131/com.example.eugene.lafinalproduction D/libc-netbsd: getaddrinfo: get result from proxy gai_error = 7
04-24 01:17:41.746 7093-7131/com.example.eugene.lafinalproduction I/System.out: [CDS][DNS]Unable to resolve host "lafinalproduction.firebaseio.com": No address associated with hostname
04-24 01:17:42.574 7093-7135/com.example.eugene.lafinalproduction I/System.out: [CDS][DNS] getAllByNameImpl netId = 0
04-24 01:17:42.574 7093-7135/com.example.eugene.lafinalproduction D/libc-netbsd: [getaddrinfo]: netid=0; mark=0
[getaddrinfo]: ai_addrlen=0; ai_canonname=(null); ai_flags=4; ai_family=0
04-24 01:17:43.242 7093-7113/com.example.eugene.lafinalproduction I/[MALI][Gralloc]: [+]r_hnd(0x7fa7632180), client(37), share_fd(49)
04-24 01:17:43.256 7093-7113/com.example.eugene.lafinalproduction I/[MALI][Gralloc]: [+]r_hnd(0x7fa76322c0), client(37), share_fd(51)
04-24 01:17:43.767 7093-7136/com.example.eugene.lafinalproduction I/System.out: [CDS][DNS] getAllByNameImpl netId = 0
04-24 01:17:43.767 7093-7136/com.example.eugene.lafinalproduction D/libc-netbsd: [getaddrinfo]: netid=0; mark=0
04-24 01:17:43.768 7093-7136/com.example.eugene.lafinalproduction D/libc-netbsd: [getaddrinfo]: ai_addrlen=0; ai_canonname=(null); ai_flags=4; ai_family=0
[getaddrinfo]: netid=0; mark=0
[getaddrinfo]: ai_addrlen=0; ai_canonname=(null); ai_flags=1024; ai_family=0
Чтобы решить эту проблему, выполните следующие действия:
измените свою модель, чтобы она выглядела так:
public class Places {
private String image, name;
public Places() { }
public Places(String image, String name) {
this.image = image;
this.name = name;
}
public String getImage() { return image; }
public String getName() { return name; }
}
Поля из вашего модельного класса должны выглядеть точно так же, как и из вашей базы данных. В вашем коде все по-другому. См. Сравнение name_place и name.
Сделайте свой firebaseRecyclerAdapter универсальным:
private FirebaseRecyclerAdapter<Places, PlaceViewHolder> firebaseRecyclerAdapter;
Удалите FirebaseRecyclerAdapter<Places, PlaceViewHolder> из метода onCreate().
Добавьте следующие строки кода в методы onStart() и onStop().
@Override
protected void onStart() {
super.onStart();
firebaseRecyclerAdapter.startListening();
}
@Override
protected void onStop() {
super.onStop();
if (firebaseRecyclerAdapter != null) {
firebaseRecyclerAdapter.stopListening();
}
}
Этот - это полный пример того, как вы можете извлекать данные из базы данных Firebase Realtime и отображать их в RecyclerView с помощью FirebaseRecyclerAdapter.
Редактировать:
Чтобы просто отобразить эти имена в logcat, используйте следующий код:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("Users");
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String name = ds.child("name").getValue(String.class);
Log.d("TAG", name);
Toast.makeText(getApplicationContext(), name, Toast.LENGTH_SHORT).show());
}
}
@Override
public void onCancelled(DatabaseError databaseError) {}
};
usersRef.addListenerForSingleValueEvent(valueEventListener);
Спасибо за помощь @Alex Mamo. но я не совсем понял, где я должен объявить метод onStart, onStop в коде. В любом месте, кроме onCreate? И, сделав firebaseRecycleAdapter глобальным, я сделал его основным и удалил свой метод firebasePlaceSearch() из onCreate, но как правильно объявить мой адаптер после него? Когда я сделал все, что вы сказали, возникла ошибка: «Попытка вызвать виртуальный метод void com.firebase.ui.database.FirebaseRecyclerAdapter.startListen ing ()» для ссылки на нулевой объект «Что-то пошло не так ..
Вам необходимо переопределить оба метода onStart и onStop в вашем классе активности. Должен выглядеть ваш метод onCreate. Вы получаете эту ошибку, потому что ваш адаптер не был инициализирован. Поэтому переместите переменную options в метод onCreate, а также весь этот код в методе firebasePlaceSearch сразу после объявления переменной options.
Хорошо, я сделал все, что ты мне рассказываешь @Alex Mamo. Но снова RecycleView пуст, я пытаюсь воссоздать базу данных, когда приложение было запущено, но оно все еще пустое. Я редактирую код в своем вопросе, как вы сказали, вы можете его посмотреть?
Я не вижу вашу отредактированную запись. Удалите все данные и добавьте данные freash. Это работает?
Почему ты не можешь @Alex Mamo? Я обновляю его в своем текстовом вопросе в пункте «4». Я запускаю приложение, затем удаляю все данные в консоли Firebase и добавляю некоторые - ничего, RecycleView все еще пуст ..
Пожалуйста, поделитесь всем своим классом, чтобы более четко видеть код.
ОК. я сделал это, внизу моего вопроса в поле обновления @Alex Mamo
Ваш код правильный. Не могли бы вы снова поделиться своей базой данных, содержащей новые данные?
Конечно, получилось. Внизу снова @Alex Mamo
Попробуйте добавить эту строку кода Log.d("TAG", model.getName()); в свой метод onBindViewHolder. Регистрирует ли он все имена?
Неа. Нет ничего подобного @Alex Mamo. Может ли это решить удаление проекта в консоли Firebase и создание нового, чем подключение к Android Studio?
Нет, это не имеет отношения к воссозданию проекта. Вы проверили свой логарифм, и при добавлении этой строки он пуст: Log.d("TAG", model.getName());? Ищите логат после TAG.
Ага, ничего. Я разместил логи, о которых идет речь, @Alex Mamo
Попробуйте изменить эту строку с помощью: Toast.makeText(getApplicationContext(), model.getName(), Toast.LENGTH_SHORT).show());. Что происходит?
Попробуйте, но ничего, никаких тостов .. @ Alex Mamo
Используя код из моего обновленного ответа, он регистрирует / всплывает имена?
Yeeeeeesss !!!! Проблема была примитивной, в моем методе setDetails для TextView был найден идентификатор для ImageView, а в обратном - для ImageView. Это так глупо! Большое спасибо за то, что проводил со мной столько времени. Я очень благодарен вам!
проверьте эту ссылку: stackoverflow.com/questions/47228262/…