2015-04-05 33 views
7

Tworzę prosty widok z recyklingu z elementami filmu. Kiedy próbuję dodawać nowe elementy, nie będą one wyświetlane od razu w widoku recyklingu. Z jakiegoś powodu muszę przewinąć w dół, aby pierwszy element zniknął, a następnie ponownie w górę, aby nowy element był wyświetlany (jest dodawany w indeksie 0).RecyclerView odświeża elementy tylko podczas przewijania w dół iw górę

Adapter:

public class MovieCardAdapter extends RecyclerView.Adapter<MovieCardAdapter.MovieViewHolder> { 
List<Movie> movieList; 

public MovieCardAdapter(final List<Movie> movieList) { 
    this.movieList = movieList; 
} 

public void addItem(int position, final Movie movie){ 
    movieList.add(position,movie); 
    notifyItemInserted(position); 
} 

public void removeItem(final Movie movie){ 
    final int indexOf = movieList.indexOf(movie); 
    movieList.remove(movie); 
    notifyItemRemoved(indexOf); 
} 

public void updateItems(final List<Movie> items){ 
    movieList = items; 
    notifyDataSetChanged(); 
} 

@Override 
public MovieViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 
    View itemView = LayoutInflater. 
      from(viewGroup.getContext()). 
      inflate(R.layout.movie_row, viewGroup, false); 

    return new MovieViewHolder(itemView); 
} 

@Override 
public long getItemId(int position) { 
    return super.getItemId(position); 
} 

@Override 
public void onBindViewHolder(final MovieViewHolder movieViewHolder, final int i) { 
    final Movie movie = movieList.get(i); 

    String posterUrl = ""; 
    final int posterHeight = 240; 
    if (!isEmpty(movie.getImdb_id())) { 
     posterUrl = "http://img.omdbapi.com/?i=" + movie.getImdb_id() + "&apikey="+apiKey+"&h=" + posterHeight; 
    } else if (!isEmpty(movie.getPoster())) { 
     posterUrl = movie.getPoster(); 
    } 
    if (!isEmpty(posterUrl)) { 
     Picasso.with(movieViewHolder.context) 
       .load(posterUrl) 
       .resize(220, 354) 
       .centerCrop() 
       .into(movieViewHolder.poster); 
    } 

    movieViewHolder.title.setText(movie.getTittel()); 
    movieViewHolder.format.setText(movie.getFormat()); 

    if (movie.getRuntime().isEmpty() || movie.getRuntime().equalsIgnoreCase("0")){ 
     movieViewHolder.runtime.setText(""); 
    }else{ 
     movieViewHolder.runtime.setText(movie.getRuntime()+" mins"); 
    } 

    if (!movie.getTagline().isEmpty()) { 
     movieViewHolder.tagline.setText(movie.getTagline()); 
    } else if (!movie.getPlot().isEmpty()) { 
     movieViewHolder.tagline.setText(movie.getPlot()); 
    } 
} 

@Override 
public int getItemCount() { 
    return movieList.size(); 
} 

public static class MovieViewHolder extends RecyclerView.ViewHolder { 
    protected Context context; 
    protected LinearLayout movieRowLinearLayout; 
    protected ImageView poster; 
    protected TextView title; 
    protected TextView runtime; 
    protected TextView tagline; 
    protected TextView format; 

    public MovieViewHolder(View v) { 
     super(v); 
     context = v.getContext(); 
     movieRowLinearLayout = (LinearLayout) v.findViewById(R.id.movieRowLinearLayout); 
     poster = (ImageView) v.findViewById(R.id.poster); 
     title = (TextView) v.findViewById(R.id.title); 
     runtime = (TextView) v.findViewById(R.id.runtime); 
     tagline = (TextView) v.findViewById(R.id.tagline); 
     format = (TextView) v.findViewById(R.id.format); 
    } 
} 

}

Inicjowanie adaptera:

adapter = new MovieCardAdapter(MovieList.movies); 
recyclerView.setAdapter(adapter); 

Dodawanie film przykładowy:

if (id == R.id.add_movie) { 
     final Movie movie = new Movie(); 
     movie.setTittel("0TEST"); 
     movie.setFormat("HD-DVD"); 

     MovieList.sortMoviesByTitle(); 
     adapter.addItem(MovieList.movies.indexOf(movie), movie); 
     return true; 
    } else if (id == R.id.action_logOut) { 
     logOut(this); 
    } 

SRY zły angielski, nadzieję, że ktoś rozumie i wiedzieć, co t może być problem. Próbowałem już dodawanie z runOnUiThread ([...]), ale ten sam wynik.

Odpowiedz

2

To się dzieje, ponieważ pozycja 0 znajduje się powyżej bieżącego widocznego ekranu. Do czasu użycia trybu transkrypcji, podczas dodawania pozycji do pozycji N, spróbuj zadzwonić pod numer scrollToPosition(N), jeśli LinearLayoutManager#findFirstCompletelyVisibleItemPosition zwróci N.

Nie należy również ustawiać parametru pozycji final w swojej metodzie onBindViewHolder. Zamiast tego użyj ViewHolder.getPosition(), jeśli potrzebujesz tego w wywołaniu zwrotnym. Gdy pozycja pozycji ulegnie zmianie, nie otrzymasz połączenia onBind, dopóki sam przedmiot nie zostanie unieważniony.

Aktualizacja

także logika zmiana nie jest prawidłowe, ponieważ nie jesteś wyczyszczenie wartości w widokach.

if (!movie.getTagline().isEmpty()) { 
    movieViewHolder.tagline.setText(movie.getTagline()); 
} else if (!movie.getPlot().isEmpty()) { 
    movieViewHolder.tagline.setText(movie.getPlot()); 
} else { 
    movieViewHolder.tagline.setText(null); 
} 

To samo dotyczy adresu URL plakatu.

+0

próbowałem, ale dodana pozycja nie jest „na wierzchu” w recyclerView. Jest to pierwsze, gdy pierwsze elementy są "poddane recyklingowi", które stają się widoczne. Próbowałem debugowania i widzę, że element jest dodany do listy w adapterze. –

+0

Hmm, zaktualizowano odpowiedź w/jeszcze jeden problem w kodzie. Jeśli nadal jest uszkodzony, możesz wysłać do mnie aplikację lub utworzyć raport o błędzie na b.android.com z przykładową aplikacją. – yigit

+0

Mam projektu otwarte av https://github.com/olavbg/MyMoovs Ale to w toku, z wieloma rzeczami, które mogą/powinny być lepsze. –

0

Dodawanie ten rozwiązał problem do mnie

layoutManager.scrollToPosition