有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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) 个答案

  1. # 1 楼答案

    在完成对数据库的查询后,填充用户列表。但是,从它在另一个线程中完成的那一刻起,主UI线程就一直在运行,所以基本上你在适配器中传递了一个空的arrayList,因为当用户列表被填充时,你已经显示了你的UI。 要解决这个问题,应该将db请求包装在一个新线程中,一旦请求完成,就转到UI线程来填充布局

    这里有一个非常基本的例子:

    new Thread(() -> {
    
        //Make the request to your DB, but NOT by using any type of asynchronous method, 
        //as you are already in a separate and secure thread, so you don't need it.
    
    
        //Just and example. When you query your DB, is always better to get the most out of a single transaction, 
        //so that you don't have to query it multiple times for very little informations.
        ArrayList<UserItem> userList = getUserItemList();
    
        //Now that you have all the data that you need, you can move to the UIThread
    
        runOnUiThread(() -> {
            //I just copied your code for setting up the ScrollView
            adapter = new UsersAdapter(this, usersList);
            usersListView.setAdapter(adapter);
        });
    
    
    }).start();