如何在使用 Firestore 时清除 GridView?
How to clear GridView while working with Firestore?
问题是我无法刷新我的 gridView
,当我在 Firestore 中进行更改时,我的 gridView 不清除,只是从 Firestore 添加新值(图像)。我尝试了很多可以在 "Whosebug" 上找到的方法,但都没有成功。也许问题出在 ImageAdapter
或我如何调用 addSnapshotListener
,我真的不知道。现在我只想在 Firestore
上的数据更改时刷新我的 gridView,但在最好的情况下我希望,当我从 Firestore
获取新值时,它只更新 gridView 的那一部分是图像,而不是整个 gridView
.
public class MainActivity extends AppCompatActivity {
private FirebaseFirestore db;
private ArrayList<Items> arrayList;
private ImageAdapter imageAdapter;
private GridView gridView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView = findViewById(R.id.gridViewList);
db = FirebaseFirestore.getInstance();
arrayList = new ArrayList<>();
//arrayList.clear();
getUrls();
imageAdapter = new ImageAdapter(MainActivity.this, arrayList);
gridView.setAdapter(imageAdapter);
}
private void getUrls(){
gridView.setAdapter(null);
db.collection("images").addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(QuerySnapshot value, FirebaseFirestoreException e) {
if (e != null){
Toast.makeText(getApplicationContext(), "No images returned", Toast.LENGTH_SHORT).show();
return;
}
for (DocumentSnapshot document : value){
refresh();
if (document.get("imageUrl") != null){
arrayList.add(new Items(document.get("imageUrl").toString()));
refresh();
}
}
}
});
}
public void refresh() {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
imageAdapter.notifyDataSetChanged();
gridView.invalidate();
}
});
}
public class ImageAdapter extends BaseAdapter {
private ImageView imageView;
private Context context;
private LayoutInflater inflater;
private ArrayList<Items> list;
public ImageAdapter(Context context, ArrayList<Items> list){
this.context = context;
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null){
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.image_layout, parent, false);
imageView = convertView.findViewById(R.id.singleImageView);
}
/** https://futurestud.io/tutorials/glide-caching-basics */
Glide.with(context).load(list.get(position).getImageUrl()).apply(RequestOptions.skipMemoryCacheOf(true).centerCrop()).into(imageView);
return convertView;
}
FirebaseUI-Android/Firestore project has an adapter that does what you want. This does the heavy lifting of managing a RecyclerView
for you. In order to have a layout like in GridView
, you can create an instance of GridLayoutManager
in onCreate
and pass that to RecyclerView.setLayoutManager
如果您想自己破解它,QuerySnapshot
有一个 属性 documentChanges
,您可以检查 REMOVED
- cf. View changes between snapshots. To get an idea of how it would be implemented with a GridView
you can look at the source code of RecyclerView.Adatper
- 特别是 notifyItemXXX
方法。
问题是我无法刷新我的 gridView
,当我在 Firestore 中进行更改时,我的 gridView 不清除,只是从 Firestore 添加新值(图像)。我尝试了很多可以在 "Whosebug" 上找到的方法,但都没有成功。也许问题出在 ImageAdapter
或我如何调用 addSnapshotListener
,我真的不知道。现在我只想在 Firestore
上的数据更改时刷新我的 gridView,但在最好的情况下我希望,当我从 Firestore
获取新值时,它只更新 gridView 的那一部分是图像,而不是整个 gridView
.
public class MainActivity extends AppCompatActivity {
private FirebaseFirestore db;
private ArrayList<Items> arrayList;
private ImageAdapter imageAdapter;
private GridView gridView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView = findViewById(R.id.gridViewList);
db = FirebaseFirestore.getInstance();
arrayList = new ArrayList<>();
//arrayList.clear();
getUrls();
imageAdapter = new ImageAdapter(MainActivity.this, arrayList);
gridView.setAdapter(imageAdapter);
}
private void getUrls(){
gridView.setAdapter(null);
db.collection("images").addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(QuerySnapshot value, FirebaseFirestoreException e) {
if (e != null){
Toast.makeText(getApplicationContext(), "No images returned", Toast.LENGTH_SHORT).show();
return;
}
for (DocumentSnapshot document : value){
refresh();
if (document.get("imageUrl") != null){
arrayList.add(new Items(document.get("imageUrl").toString()));
refresh();
}
}
}
});
}
public void refresh() {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
imageAdapter.notifyDataSetChanged();
gridView.invalidate();
}
});
}
public class ImageAdapter extends BaseAdapter {
private ImageView imageView;
private Context context;
private LayoutInflater inflater;
private ArrayList<Items> list;
public ImageAdapter(Context context, ArrayList<Items> list){
this.context = context;
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null){
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.image_layout, parent, false);
imageView = convertView.findViewById(R.id.singleImageView);
}
/** https://futurestud.io/tutorials/glide-caching-basics */
Glide.with(context).load(list.get(position).getImageUrl()).apply(RequestOptions.skipMemoryCacheOf(true).centerCrop()).into(imageView);
return convertView;
}
FirebaseUI-Android/Firestore project has an adapter that does what you want. This does the heavy lifting of managing a RecyclerView
for you. In order to have a layout like in GridView
, you can create an instance of GridLayoutManager
in onCreate
and pass that to RecyclerView.setLayoutManager
如果您想自己破解它,QuerySnapshot
有一个 属性 documentChanges
,您可以检查 REMOVED
- cf. View changes between snapshots. To get an idea of how it would be implemented with a GridView
you can look at the source code of RecyclerView.Adatper
- 特别是 notifyItemXXX
方法。