2

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; 
} 
+0

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? –

+0

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 –

Antwort

0

, wenn Sie URL oder Bitmap des Bildes haben, dann gleiten verwenden Sie, bis Ihr Bild machen Netzwerk Aufruf zwischengespeichert werden, wenn Sie URL senden und laden Sie es for more about glide

Glide.with(mContext) 
    .load(imageUrl) 
    .diskCacheStrategy(DiskCacheStrategy.ALL) 
    .centerCrop() 
    .into(mImageView_photo) 
; 

0

In RecyclerView müssen Sie sicherstellen, dass Sie entweder eine eindeutige Kennung Rückkehr für jeden Artikel oder bei Nicht Stable Id sollten Sie zurückkommen RecyclerView.NO_ID (-1). Bitte unterlassen es, Werte zurückzugeben, die nicht stabil sind. (Ein Stabiler Wert wäre ein eindeutiger Wert, der sich nicht ändert, selbst wenn sich die Position des Datasets ändert)

Fügen Sie in Ihrem RecyclerView-Adapter den getItemId-Callback hinzu.

zB:

@Override 
public long getItemId(int position) { 
    return Long.parseLong(programList.get(position).getLmsId()); 
} 
Verwandte Themen