Ich habe eine RecyclerView
mit einer Liste von Karten drin, und jeder hat einen Platz für ein Bild. Wenn ich anfänglich nach unten scrolle, werden die Karten, die nicht auf dem Bildschirm erschienen sind, geladen, sobald sie auf dem Bildschirm erscheinen, aber die Karten, die auf dem Bildschirm gestartet wurden, werden erst geladen, wenn sie auf dem Bildschirm aus- und wieder eingeschaltet werden.Bilder in RecyclerView erscheinen nicht beim Start
Es scheint auch etwas zufällig zu sein. Gif für den Kontext: https://gfycat.com/gifs/detail/accurateeducatedbaiji
Das allerletzte Beispiel in der gif (wo die ersten 3 Restaurant Bilder nicht laden) ist die häufigste.
ViewHolder:
public class LocationsViewHolder extends RecyclerView.ViewHolder{
private ImageView locationImage;
private TextView locationName;
private TextView locationAddress;
public LocationsViewHolder(View itemView) {
super(itemView);
locationName = (TextView)itemView.findViewById(R.id.location_name);
locationAddress = (TextView)itemView.findViewById(R.id.location_address);
locationImage = (ImageView) itemView.findViewById(R.id.location_image);
}
public void updateUI(Place place){
locationName.setText(place.getName());
if(place.getPhotoID() != null){
// Log.v("IMAGE", "photoID for " + place.getName() + ": " + place.getPhotoID());
locationImage.setImageBitmap(place.getImage());
} else {
locationImage.setImageResource(R.drawable.no_image);
}
}
}
Adapter:
public class LocationsAdapter extends RecyclerView.Adapter<LocationsViewHolder>{
ArrayList<Place> locations;
Context context;
GetNearbyPlacesData data;
public LocationsAdapter(ArrayList<Place> locations, Context context) {
this.locations = locations;
this.context = context;
data = GetNearbyPlacesData.getInstance(context);
}
@Override
public LocationsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View card = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_location, parent, false);
return new LocationsViewHolder(card);
}
@Override
public void onBindViewHolder(LocationsViewHolder holder, int position) {
Place location = locations.get(position);
holder.updateUI(location);
}
@Override
public int getItemCount() {
return locations.size();
}
}
downloadPlaceImage:
Bitmap bitmap;
public void downloadPlaceImage(String imageKey, final Place place){
String url = buildImgURL(imageKey);
ImageRequest imageRequest = new ImageRequest(url, new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
bitmap = response;
place.setImage(bitmap);
Log.v("IMG", "downloaded image");
}
}, 0, 0, null, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(imageRequest);
}
}
Wie Schalt sein Tween Restaurants und Apotheken erfolgt: Der onNavigationItemSelected Zuhörer:
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Log.v("NAV", "Navigation item selected");
URLInfo = new Bundle();
URLInfo.putString("radius", MAP_RADIUS);
URLInfo.putString("location", userMarker.getPosition().latitude + "," + userMarker.getPosition().longitude);
mMap.clear();
switch (item.getItemId()){
case R.id.nav_restaurant: {
URLInfo.putString("type", "restaurant");
placeList = data.downloadPlacesData(URLInfo);
break;
}
case R.id.nav_pharmacy: {
URLInfo.putString("type", "pharmacy");
placeList = data.downloadPlacesData(URLInfo);
break;
}
case R.id.nav_bank: {
URLInfo.putString("type", "bank");
placeList = data.downloadPlacesData(URLInfo);
break;
}
}
mDrawerLayout.closeDrawer(GravityCompat.START);
return true;
}
die downloadPlacesData()
Funktion:
ArrayList<Place> placesList;
public ArrayList<Place> downloadPlacesData(Bundle bundle){
String url = buildPlaceURL(bundle);
placesList = new ArrayList<>();
//TODO make more requests for the next pages of results since each page is limited to 20 places
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
JSONArray results = response.getJSONArray("results");
for(int i = 0; i < results.length(); i++){
JSONObject main = results.getJSONObject(i);
JSONObject geo = main.getJSONObject("geometry");
JSONObject loc = geo.getJSONObject("location");
String placeID = main.getString("place_id");
String name = main.getString("name");
String lat = loc.getString("lat");
String lng = loc.getString("lng");
String photoID = null;
try {
if (main.getJSONArray("photos") != null) {
JSONArray photos = main.getJSONArray("photos");
photoID = photos.getJSONObject(0).getString("photo_reference");
}
}catch (JSONException e){
Log.v("JSON4", e.getLocalizedMessage());
}
Place place = new Place(photoID, name, placeID, Double.parseDouble(lat), Double.parseDouble(lng), context);
Log.v("NAME", name);
placesList.add(place);
}
onPlacesLoadedListener.placesLoaded(placesList);
}catch (JSONException e){
Log.v("JSON", e.getLocalizedMessage());
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(jsonObjectRequest);
return placesList;
}
Der placesLoaded Rückruf und die Schaffung der LocationsListFragment
:
@Override
public void placesLoaded(ArrayList<Place> list) {
Log.v("PLACES", "adding places");
MarkerOptions markerOptions = new MarkerOptions();
// build a resource path using the type of place
String type = URLInfo.getString("type");
String resourcePath = "drawable/pin_" + type;
// create a resource path out of the String created
int resource = getResources().getIdentifier(resourcePath, null, this.getPackageName());
// set the marker icon according to the place type
markerOptions.icon(BitmapDescriptorFactory.fromResource(resource));
for(int i = 0; i < list.size(); i++){
// get the latitude and longitude
double lat = list.get(i).getLat();
double lng = list.get(i).getLng();
// set the marker position and title
markerOptions.position(new LatLng(lat, lng));
markerOptions.title(list.get(i).getName());
mMap.addMarker(markerOptions);
}
createLocationsListFragment();
}
private void createLocationsListFragment() {
FragmentManager fm = getSupportFragmentManager();
LocationsListFragment fragment = LocationsListFragment.newInstance();
fm.beginTransaction().add(R.id.container_locations, fragment).commit();
}
ein schließlich d, die tatsächliche Fragment (onCreate und onCreateView):
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getLocationsData = (GetLocationsData) getContext();
mParam1 = getLocationsData.getList();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_locations_list, container, false);
adapter = new LocationsAdapter(mParam1, getContext());
RecyclerView recyclerView = (RecyclerView)v.findViewById(R.id.recycler_locations);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
return v;
}
welcher Code ausgeführt wird, wenn (in Ihrem Beispiel Video) Sie zwischen Restaurants und Apotheken wechseln? D. h. Wie werden die Daten Ihres Adapters aktualisiert? –
Wenn eines der Elemente ausgewählt ist, lädt es ähnliche Daten in der Nähe des Bild-Downloads herunter (JSON und Volley): ich füge das dem Hauptbeitrag hinzu –