java ScrollView不会填充
我有一个ListView,它从Firestore获取数据,将所有数据放入UserItem类型的ArrayList中,然后将其放入要显示的适配器中
问题是出于某种原因,它拒绝展示任何东西
我试过几件事,比如实施。notifyOnSetChanged(),但没有用(更确切地说,我没有正确执行,它已在下面的代码中删除)
我该怎么解决这个问题
UserItem(ListView中每个项的类):
package com.example.create4me;
public class UserItem {
String username, timestamp, offerID, isComplete;
public UserItem(String username, String timestamp, String offerID, String isComplete){
this.username = username;
this.timestamp = timestamp;
this.offerID = offerID;
this.isComplete = isComplete;
}
public String getUsername(){
return this.username;
}
public String getTimestamp(){
return this.timestamp;
}
public String getOfferID(){
return this.offerID;
}
public String getIsComplete(){
return this.isComplete;
}
}
UserAdapter(ListView的适配器):
package com.example.create4me;
import 安卓.content.Context;
import 安卓.view.LayoutInflater;
import 安卓.view.View;
import 安卓.view.ViewGroup;
import 安卓.widget.ArrayAdapter;
import 安卓.widget.TextView;
import java.util.ArrayList;
public class UsersAdapter extends ArrayAdapter<UserItem> {
public UsersAdapter(Context context, ArrayList<UserItem> users) {
super(context, 0, users);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
UserItem user = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.userlayout, parent, false);
}
TextView username = (TextView) convertView.findViewById(R.id.userlayoutUsername);
TextView timestamp = (TextView) convertView.findViewById(R.id.userlayoutTimestamp);
TextView isComplete = (TextView) convertView.findViewById(R.id.isComplete);
username.setText(user.getUsername());
timestamp.setText(user.getTimestamp());
isComplete.setText(user.getIsComplete());
return convertView;
}
}
负责向用户显示项目的活动:
package com.example.create4me;
import 安卓x.annotation.NonNull;
import 安卓x.appcompat.app.AppCompatActivity;
import 安卓x.recyclerview.widget.LinearLayoutManager;
import 安卓x.recyclerview.widget.RecyclerView;
import 安卓.content.Intent;
import 安卓.graphics.Bitmap;
import 安卓.graphics.BitmapFactory;
import 安卓.os.Bundle;
import 安卓.view.View;
import 安卓.widget.Button;
import 安卓.widget.ImageView;
import 安卓.widget.ListView;
import 安卓.widget.TextView;
import com.google.安卓.gms.tasks.OnCompleteListener;
import com.google.安卓.gms.tasks.OnFailureListener;
import com.google.安卓.gms.tasks.OnSuccessListener;
import com.google.安卓.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import java.util.ArrayList;
public class MyCreatedOfferActivity extends AppCompatActivity {
ImageView image, profilepic;
TextView madeBy, title, desc, price;
String offerid, madyByUuid;
FirebaseAuth auth = FirebaseAuth.getInstance();
private static final long ONE_MB = 1024 * 1024;
FirebaseStorage storage = FirebaseStorage.getInstance();
FirebaseFirestore db = FirebaseFirestore.getInstance();
StorageReference ref = storage.getReference();
FirebaseUser user;
Button backToHome;
String madeByUsername = "";
ListView usersListView;
ArrayList<UserItem> usersList;
UsersAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_created_offer);
getSupportActionBar().hide();
user = auth.getCurrentUser();
Intent data = getIntent();
offerid = data.getExtras().getString("offerID");
image = findViewById(R.id.OfferActivityImage);
backToHome = findViewById(R.id.backToHomeButton);
//profilepic = findViewById(R.id.OfferActivityProfileImage);
title = findViewById(R.id.OfferActivityTitle);
desc = findViewById(R.id.OfferActivityDescription);
price = findViewById(R.id.OfferActivityPrice);
madeBy = findViewById(R.id.OfferActivityCreatorName);
//Over here, we create the List and also get the container for the ListView
usersListView = findViewById(R.id.listcontainer);
usersList = new ArrayList<UserItem>();
//Here we get the data from Firestore
getData();
//Here we put the data into the adapter so it could be populated, but isn't
adapter = new UsersAdapter(this, usersList);
usersListView.setAdapter(adapter);
backToHome.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MyCreatedOfferActivity.this, HomeActivity.class);
startActivity(intent);
}
});
loadData();
}
public void getData(){
db.collection("ongoing")
.whereEqualTo("creatorID", user.getUid())
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if(task.isSuccessful()){
for(QueryDocumentSnapshot doc : task.getResult()){
usersList.add(new UserItem(doc.getData().get("buyerUsername").toString(),
doc.getData().get("timestamp").toString(),
doc.getData().get("offerID").toString(),
doc.getData().get("isComplete").toString()));
}
}
}
});
}
public void loadData(){
db.collection("offers")
.whereEqualTo("offerID", offerid.toString())
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if(task.isSuccessful()){
for(QueryDocumentSnapshot doc : task.getResult()){
title.setText(doc.getData().get("title").toString());
desc.setText(doc.getData().get("description").toString());
price.setText(doc.getData().get("price").toString());
madeBy.setText(doc.getData().get("madeByName").toString());
madyByUuid = doc.getData().get("madeByID").toString();
StorageReference imageref = ref.child(doc.getData().get("image").toString());
imageref.getBytes(ONE_MB).addOnSuccessListener(new OnSuccessListener<byte[]>() {
@Override
public void onSuccess(byte[] bytes) {
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
image.setImageBitmap(bitmap);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle any errors
}
});
}
}
}
});
db.collection("users")
.whereEqualTo("uuid", madyByUuid)
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
for (QueryDocumentSnapshot doc : task.getResult()) {
StorageReference imageref = ref.child(doc.getData().get("profilePic").toString());
imageref.getBytes(ONE_MB).addOnSuccessListener(new OnSuccessListener<byte[]>() {
@Override
public void onSuccess(byte[] bytes) {
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
profilepic.setImageBitmap(bitmap);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle any errors
}
});
}
}
});
}
}
编辑:有人要XML文件,所以它在这里(是的,它很难看,但现在可以使用):
<?xml version="1.0" encoding="utf-8"?>
<安卓x.constraintlayout.widget.ConstraintLayout xmlns:安卓="http://schemas.安卓.com/apk/res/安卓"
xmlns:app="http://schemas.安卓.com/apk/res-auto"
xmlns:tools="http://schemas.安卓.com/tools"
安卓:layout_width="match_parent"
安卓:layout_height="match_parent"
tools:context=".MyCreatedOfferActivity">
<ScrollView
安卓:layout_width="match_parent"
安卓:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:layout_editor_absoluteX="0dp">
<LinearLayout
安卓:layout_width="match_parent"
安卓:layout_height="wrap_content"
安卓:orientation="vertical">
<Button
安卓:id="@+id/backToHomeButton"
安卓:layout_width="wrap_content"
安卓:layout_height="wrap_content"
安卓:text="Back to home"
安卓:textSize="10dp" />
<ImageView
安卓:id="@+id/OfferActivityImage"
安卓:layout_width="match_parent"
安卓:layout_height="200dp"
安卓:layout_marginTop="25dp"/>
<LinearLayout
安卓:layout_width="match_parent"
安卓:layout_height="wrap_content"
安卓:orientation="horizontal">
<TextView
安卓:id="@+id/OfferActivityTitle"
安卓:layout_width="wrap_content"
安卓:layout_height="wrap_content"
安卓:layout_marginLeft="15dp"
安卓:layout_marginTop="25dp"
安卓:text="Title"
安卓:textColor="@color/black"
安卓:textSize="30dp"
安卓:layout_weight="1"/>
<TextView
安卓:id="@+id/OfferActivityPrice"
安卓:layout_width="wrap_content"
安卓:layout_height="wrap_content"
安卓:text="price"
安卓:layout_marginRight="15dp"
安卓:layout_marginTop="25dp"
安卓:textColor="@color/black"
安卓:textSize="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</LinearLayout>
<LinearLayout
安卓:id="@+id/linearLayout2"
安卓:layout_width="wrap_content"
安卓:layout_height="wrap_content"
安卓:layout_marginTop="8dp"
安卓:orientation="horizontal"
安卓:layout_marginLeft="15dp">
<ImageView
安卓:id="@+id/OfferActivityProfileImage"
安卓:layout_width="50dp"
安卓:layout_height="50dp" />
<LinearLayout
安卓:layout_width="wrap_content"
安卓:layout_height="match_parent"
安卓:layout_gravity="center"
安卓:gravity="center"
安卓:orientation="vertical">
<TextView
安卓:layout_width="wrap_content"
安卓:layout_height="wrap_content"
安卓:text="Made By:"
安卓:textColor="@color/black" />
<TextView
安卓:id="@+id/OfferActivityCreatorName"
安卓:layout_width="wrap_content"
安卓:layout_height="wrap_content"
安卓:text="name"
安卓:textColor="@color/black"
安卓:textSize="17dp" />
</LinearLayout>
</LinearLayout>
<TextView
安卓:id="@+id/OfferActivityDescription"
安卓:layout_width="wrap_content"
安卓:layout_height="wrap_content"
安卓:layout_marginTop="50dp"
安卓:text="Description"
安卓:textColor="@color/black"
安卓:textSize="20dp" />
<ListView
安卓:layout_width="match_parent"
安卓:layout_height="wrap_content"
安卓:id="@+id/listcontainer"
app:layout_constraintBottom_toBottomOf="@+id/OfferActivityDescription"/>
</LinearLayout>
</ScrollView>
</安卓x.constraintlayout.widget.ConstraintLayout>
# 1 楼答案
在完成对数据库的查询后,填充用户列表。但是,从它在另一个线程中完成的那一刻起,主UI线程就一直在运行,所以基本上你在适配器中传递了一个空的arrayList,因为当用户列表被填充时,你已经显示了你的UI。 要解决这个问题,应该将db请求包装在一个新线程中,一旦请求完成,就转到UI线程来填充布局
这里有一个非常基本的例子: