我有一個ListView,它從Firestore獲取資料,將其全部放入UserItem型別的ArrayList中,然后將其放入配接器中進行顯示。
問題是,由于某些原因,它拒絕顯示任何東西。
我嘗試了一些方法,例如實作.notifyOnSetChanged(),但無濟于事(更確定的是我沒有正確操作,下面的代碼中已經洗掉)。
我怎樣才能解決這個問題呢?
UserItem(ListView中每個專案的類):
package com.example.create4me;
public class UserItem {
字串 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()/span>{
return this.username。
}
public String getTimestamp(){
return this.timestamp。
}
public String getOfferID(){
return this.offerID。
}
public String getIsComplete()/span>{
return this.isComplete。
}
UserAdapter (ListView的配接器):
package com.example.create4me;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.ArrayList;
public class UsersAdapter extends ArrayAdapter<UserItem> {
public UsersAdapter(Context context, ArrayList< UserItem> users) {
super(context, 0, users)。
}
@Override(context); }
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 androidx.annotation.NonNull。
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent。
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View。
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.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影像,profilepic。
TextView madeBy, title, desc, price;
字串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用戶。
按鈕backToHome。
String madeByUsername = ";
ListView usersListView;
ArrayList<UserItem> usersList;
UsersAdapter配接器。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(s savedInstanceState)。
setContentView(R.layout.activity_my_created_offer)。
getSupportActionBar().hide()。
user = auth.getCurrentUser();
Intent data = getIntent()。
offerid = data.getExtras().getString("offerID"/span>)。
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>()。
//這里我們從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() {
public void onClick(View v) {
Intent intent = new Intent(MyCreatedOfferActivity. this, HomeActivity.class)。)
startActivity(intent)。
}
});
loadData()。
}
public void getData(){
db.collection("being")
.whereEqualTo("creatorID", user.getUid()
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot> () {
public void onComplete( Task<QuerySnapshot> task) {
if(task.isSuccessful()){
for(QueryDocumentSnapshot doc : task.getResult() ){
usersList.add(new UserItem(doc.getData().get("buyerUsername").toString(),
doc.getData().get("timestamp"/span>).toString()。
doc.getData().get("offerID").toString()。
doc.getData().get("isComplete").toString())。
}
}
}
});
}
public void loadData{
db.collection("offer")
.whereEqualTo("offerID", offerid.toString()
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot> () {
public void onComplete( Task<QuerySnapshot> task) {
if(task.isSuccessful()){
for(QueryDocumentSnapshot doc : task.getResult() ){
title.setText(doc.getData().get("title"/span>).toString())。
desc.setText(doc.getData().get("description").toString())。
price.setText(doc.getData().get("price").toString())。
madeBy.setText(doc.getData().get("madeByName"/span>).toString())。
madyByUuid = doc.getData().get("madeByID"/span>).toString()。
StorageReference imageref = ref.child(doc.getData().get("image").toString())。
imageref.getBytes(ONE_MB).addOnSuccessListener(new OnSuccessListener<byte[]> (){
public void onSuccess(byte[] bytes) {
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length) 。
image.setImageBitmap(bitmap)。
}
}).addOnFailureListener(new OnFailureListener() {
public void onFailure( Exception exception) {
//處理任何錯誤。
}
});
}
}
}
});
db.collection("user")
.whereEqualTo("uuid", madyByUuid)
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot> () {
public void onComplete( Task<QuerySnapshot> task) {
for (QueryDocumentSnapshot doc : task.getResult() ) {
StorageReference imageref = ref.child(doc.getData().get("profilePic"/span>).toString())。
imageref.getBytes(ONE_MB).addOnSuccessListener(new OnSuccessListener<byte[]> (){
public void onSuccess(byte[] bytes) {
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length) 。
profilepic.setImageBitmap(bitmap)。
}
}).addOnFailureListener(new OnFailureListener() {
public void onFailure( Exception exception) {
//處理任何錯誤。
}
});
}
}
});
}
}
編輯:有人問我要XML檔案,所以在這里(是的,它很難看,但現在還能用):
<?xml version="1.0"/span> encoding="utf-8"/span>?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"?
xmlns:app="http://schemas.android.com/apk/res-auto"/span>
xmlns:tools="http://schemas.android.com/tools"/span>
android:layout_width="match_parent"/span>
android:layout_height="match_parent"/span>
tools:context=".MyCreatedOfferActivity">
<ScrollView
android:layout_width="match_parent"。
android:layout_height="match_parent"/span>
app:layout_constraintBottom_toBottomOf="parent"。
tools:layout_editor_absoluteX="0dp">
<LinearLayout
android:layout_width="match_parent"/span>
android:layout_height="wrap_content"/span>
android:orientation="垂直">
<按鈕
android:id="@ id/backToHomeButton"/span>
android:layout_width="wrap_content"/span>
android:layout_height="wrap_content"/span>
android:text="回傳主頁"
android:textSize="10dp" />
<ImageView
android:id="@ id/OfferActivityImage"/span>
android:layout_width="match_parent"。
android:layout_height="200dp"/span>
android:layout_marginTop="25dp"/>
<LinearLayout
android:layout_width="match_parent"/span>
android:layout_height="wrap_content"/span>
android:orientation="horizontal">
<TextView
android:id="@ id/OfferActivityTitle"/span>
android:layout_width="wrap_content"/span>
android:layout_height="wrap_content"/span>
android:layout_marginLeft="15dp"/span>
android:layout_marginTop="25dp"/span>
android:text="Title"/span>
android:textColor="@color/black"/span>
android:textSize="30dp"/span>
android:layout_weight="1"/>
<TextView
android:id="@ id/OfferActivityPrice"/span>
android:layout_width="wrap_content"/span>
android:layout_height="wrap_content"/span>
android:text="價格"/span>
android:layout_marginRight="15dp"/span>
android:layout_marginTop="25dp"/span>
android:textColor="@color/black"/span>
android:textSize="20dp"/span>
app:layout_constraintBottom_toBottomOf="parent"。
app:layout_constraintEnd_toEndOf="father" />
</LinearLayout>
<LinearLayout
android:id="@ id/linearLayout2"/span>
android:layout_width="wrap_content"/span>
android:layout_height="wrap_content"。
android:layout_marginTop="8dp"/span>
android:orientation="horizontal"
android:layout_marginLeft="15dp">
<ImageView
android:id="@ id/OfferActivityProfileImage"/span>
android:layout_width="50dp"/span>
android:layout_height="50dp" />
<LinearLayout
android:layout_width="wrap_content"/span>
android:layout_height="match_parent"/span>
android:layout_gravity="center"/span>
android:gravity="center"/span>
android:orientation="垂直">
<TextView
android:layout_width="wrap_content"/span>
android:layout_height="wrap_content"/span>
android:text="Made By:"/span>
android:textColor="@color/black" />
<TextView
android:id="@ id/OfferActivityCreatorName"/span>
android:layout_width="wrap_content"/span>
android:layout_height="wrap_content"/span>
android:text="name"/span>
android:textColor="@color/black"/span>
android:textSize="17dp" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@ id/OfferActivityDescription"/span>
android:layout_width="wrap_content"。
android:layout_height="wrap_content"/span>
android:layout_marginTop="50dp"/span>
android:text="說明"
android:textColor="@color/black"/span>
android:textSize="20dp" />
<ListView
android:layout_width="match_parent"/span>
android:layout_height="wrap_content"/span>
android:id="@ id/listcontainer"。
app:layout_constraintBottom_toBottomOf="@ id/OfferActivityDescription" />
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
uj5u.com熱心網友回復:
在完成對資料庫的查詢后,你將填充userList。但是,從它在另一個執行緒中完成的那一刻起,主UI執行緒就一直在進行,所以你基本上在你的配接器中傳遞一個空的arrayList,因為當userList被填充時,你已經顯示了你的UI。 為了解決這個問題,你應該在一個新的執行緒中包裹資料庫請求,一旦請求完成,就轉移到UI執行緒中來填充布局。
下面是一個非常基本的例子:
new Thread(() -> {
//Make the request to your DB, but not by using any type of asynchronous method,
//因為你已經在一個獨立的安全執行緒中,所以你不需要它。
//Just and example. 當你查詢你的資料庫時,最好是在單個事務中獲得最大的收益, //Just and example.
///這樣你就不必為很少的資訊多次查詢。
ArrayList<UserItem> userList = getUserItemList()。
/Now that you have all the data that you need, you can move to the UIThread
runOnUiThread(() -> {
//我只是復制了你的代碼來設定ScrollView。
adapter = new UsersAdapter(this, usersList) 。
usersListView.setAdapter(adapter);
});
}).start()。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/315697.html
標籤:
