2015-10-22 36 views
11

Załaduję obrazy 400x200 w RecyclerView, ale przewijanie jest opóźnione w przypadku urządzeń 2k. Używam Picassa do ładowania obrazów z zasobu.RecyclerView laggy scrolling

Jak widać na zdjęciach demonstracyjnych są zamazane na ekranie 2k, ale jeśli załaduję obrazy o wyższej rozdzielczości sytuacja pogorszy się. Jak to naprawić, nie ładuję nawet dużego obrazu, jego 400x200?

Demo

Oto mój kod Card_view.xml

<?xml version="1.0" encoding="utf-8"?> 
 
<android.support.v7.widget.CardView 
 
    xmlns:android="http://schemas.android.com/apk/res/android" 
 
    xmlns:card_view="http://schemas.android.com/apk/res-auto" 
 
    android:id="@+id/card_view" 
 
    card_view:cardPreventCornerOverlap="false" 
 
    android:layout_width="fill_parent" 
 
    android:layout_height="wrap_content" 
 
    android:layout_margin="8dp" 
 
    card_view:cardCornerRadius="2dp" 
 
    > 
 

 
    <LinearLayout 
 

 
     android:layout_width="fill_parent" 
 
     android:layout_height="wrap_content" 
 
     android:orientation="vertical" 
 

 
     android:id="@+id/rel" 
 
     > 
 
     <ImageView 
 
      android:id="@+id/cardimage" 
 
      android:layout_width="match_parent" 
 
      android:layout_height="wrap_content" 
 
      android:scaleType="fitXY" 
 
      android:src="@drawable/p7" 
 
      /> 
 

 
     <TextView 
 
      android:layout_width="wrap_content" 
 
      android:layout_height="wrap_content" 
 
      android:text="title" 
 
      android:paddingLeft="16dp" 
 
      android:paddingRight="16dp" 
 
      android:paddingTop="16dp" 
 

 
      android:paddingBottom="24dp" 
 
      android:textStyle="bold" 
 
      android:textSize="24sp" 
 
      android:id="@+id/cardtitle" 
 
      android:layout_gravity="center_vertical" 
 
      /> 
 

 
    </LinearLayout> 
 

 
</android.support.v7.widget.CardView>

Myadapter Kod

public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> { 

private Context mContext; 
List<Flower> list = new ArrayList<>(); 

public CardAdapter(Context mContext, List<Flower> list) { 
    this.mContext = mContext; 
    this.list = list; 

} 

@Override 
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 

    View itemView = LayoutInflater.from(parent.getContext()) 
      .inflate(R.layout.card_view, parent, false); 
    return new ViewHolder(itemView); 
} 

@Override 
public void onBindViewHolder(ViewHolder holder, int position) { 

    holder.Flower=getItem(position); 
    holder.cardtitle.setText(list.get(position).name); 

    Picasso.with(mContext) 
      .load(list.get(position).id) 
      .placeholder(R.drawable.ic_launcher) 
      .into(holder.cardimage); 
} 

@Override 
public void onAttachedToRecyclerView(RecyclerView recyclerView) { 
    super.onAttachedToRecyclerView(recyclerView); 
} 

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

public Flower getItem(int i) { 
    return list.get(i); 
} 

public class ViewHolder extends RecyclerView.ViewHolder { 

    ImageView cardimage; 
    TextView cardtitle; 
    Flower Flower; 

    public ViewHolder(View itemView) { 
     super(itemView); 

     cardimage = (ImageView) itemView.findViewById(R.id.cardimage); 
     cardtitle = (TextView) itemView.findViewById(R.id.cardtitle); 
    } 
} 
} 

UPDATE: wczytuję obrazów z zasobu, nie jestem ściąganie nic

Oto moja tablica

private void initializeData() { 
    flowers = new ArrayList<>(); 
    flowers.add(new Flower("Flower 1", R.drawable.p8)); 
    flowers.add(new Flower("Flower 2", R.drawable.p10)); 
    flowers.add(new Flower("Flower 3", R.drawable.p11)); 
    flowers.add(new Flower("Flower 4", R.drawable.p8)); 
    flowers.add(new Flower("Flower 5", R.drawable.photo2)); 
    flowers.add(new Flower("Flower 6", R.drawable.photo6)); 
    flowers.add(new Flower("Flower 7", R.drawable.p12)); 
    flowers.add(new Flower("Flower 8", R.drawable.p9)); 
    flowers.add(new Flower("Flower 9", R.drawable.p8)); 
    flowers.add(new Flower("Flower 10", R.drawable.p8)); 
    flowers.add(new Flower("Flower 11", R.drawable.p8)); 
    flowers.add(new Flower("Flower 12", R.drawable.p10)); 
} 

UPDATE 2: Chłopaki Poprawiłem większość lag ustawiając adapter.setHasStableIds (true), ale aplikacja jest nadal laggy na pierwszym zwoju, gdy obraz nie jest jeszcze załadowany , jak to naprawić?

AKTUALIZACJA 3: Próbowałem tylko ładować obrazy z sieci i wszystko wydaje się gładkie, prawdopodobnie wystąpił problem z ładowaniem obrazów z zasobu.

OK, dziękuję wam, załaduję moje obrazy z sieci.

+0

czy opóźnia się tylko podczas przewijania w dół? lub czy opóźnia się zarówno przewijanie w górę, jak i w dół? –

+0

@LucasCrawford jego opóźnienie tylko podczas przewijania w dół. EDYCJA: Jego opóźnienie w górę iw dół, raz, gdy obrazy są ładowane, jest mniej opóźnień, ale wciąż tam jest. –

+0

znalazłeś rozwiązanie tego? –

Odpowiedz

2

Musisz otrzymywać obrazy asynchronicznie. Tak jak obecnie, zatrzymuje się, aby pobrać obraz.

Pozostaw puste miejsce obrazu po utworzeniu, ale wybierz słuchacza, aby ustawić obraz po jego pobraniu.

+1

Nie pobieram obrazów, ustawiam obraz z zasobu. –

-2

Myślę, że powodem jest to, że Picasso buforuje twoje obrazy, ale ponieważ masz listę zestawów, które pakujesz razem z aplikacją, teoretycznie nie musisz buforować obrazów. Buforowanie jest przydatne tylko wtedy, gdy pobierasz obraz z Internetu i nie chcesz, aby aplikacja ponownie pobierzeła obrazy za każdym razem, gdy przesuniesz w górę lub w dół widok z recyklingu.

Chciałbym dostosować prace sposób Picasso zmieniając memorypolicy więc spróbuj to zamiast:

Picasso.with(getContext()).load(data.get(pos).getFeed_thumb_image()).memoryPolicy(MemoryPolicy.NO_CACHE).into(image); 
+0

Dziękuję, ale bez buforowania sytuacja jest jeszcze gorsza. Zauważyłem, że przy korzystaniu z opcji zmiany rozmiaru sytucja staje się lepsza tylko raz, gdy wszystkie obrazy są załadowane, ale wciąż pozostaje w tyle podczas przewijania za pierwszym razem. Jednak ustawienie rozmiaru poprawek nie działa w moim przypadku ponieważ chcę, aby obraz wypełniał kartę. –

+0

Jeśli dołączone są rysunki w pamięci lub nie, to pytanie. Ładowanie ładunków podczas procesu RecyclerView powodowałoby zaczepianie. Rysunki należy załadować do pamięci przed uruchomieniem RecyclerView. Wszystkie niewłączone ciągnięcia mogą wymagać buforowania przed uruchomieniem RecyclerView. Nie jestem pewien, czy RecyclerView (lub inna część, z której korzystasz) używa wątku UI lub wątku BG. Jeśli już używasz wątku BG, być może trzeba się upewnić, że nie konkurują z nim – CmosBattery

+2

Oto prezentacja projektu https://drive.google.com/file/d/0BypaioeS7MXPNHY3ZUFiNVBtcTg/view?usp=sharing. Ładuję rysunki z picasso, jak mogę je załadować przed recycleView? Próbowałem wywoływać metodę initializeData() po utworzeniu, ale w pierwszym przewinięciu występuje opóźnienie. Pamiętaj, że dzieje się to tylko w rozdzielczości 2k. Na pełnym hd wszystko jest gładkie. –

8

Czy RecyclerView.setHasFixedSize() wartość true? Nie jestem w stanie odtworzyć tego opóźnienia ... czy możesz opublikować cały projekt na GIT? To sprawdzić, może to pomóc: http://antonioleiva.com/recyclerview/

+0

Tak, to prawda. Oto projekt studio Android. https://drive.google.com/file/d/0BypaioeS7MXPNHY3ZUFiNVBtcTg/view?usp=sharing –

+1

Używam genomotion vm i nie mogę odtworzyć opóźnienia. Mam 3 możliwe ulepszenia: 1. w activity_main.xml, zmień RecyclerView.layout_height na "match_parent" 2. Spróbuj użyć tylko pngs w folderze do rysowania, ponieważ dekompresują się szybciej 3. Ustaw adapter.setHasStableIds (true); oraz w CardAdapter dodaj: '@Override public long getItemId (pozycja int) { pozycja powrotna; } ' –

+0

Dziękuję bardzo, że naprawiono większość opóźnień. Teraz aplikacja jest opóźniona tylko przy pierwszym przewijaniu, gdy obrazy nie są jeszcze załadowane. Raz, gdy obrazy są ładowane, wszystko jest gładkie. Jakieś przemyślenia na ten temat? Czy używasz emulatora w rozdzielczości 2k, spróbuj uruchomić n6 lub n6p. Jego opóźnienie dotyczy tylko rozdzielczości 2k. –

2

jeśli używasz Recyclerview w trybie pionowym i swoją aktywność zawiera inny element, który trzeba ScrollView następnie należy użyć NestedScrollView zamiast ScrollView.

zgodnie z opisem w dokumentacji google NestedScrollView jest podobny do ScrollView, ale obsługuje zarówno zagnieżdżone przewijane elementy nadrzędne i potomne w nowych i starszych wersjach Androida. Zagnieżdżone przewijanie jest domyślnie włączone.

+1

Co zrobić, jeśli wiele widoków Recyklera znajduje się wewnątrz ScrollView? –

+0

dla wielu widoków Recyklera należy również użyć "NestedScrollView" do obsługi przewijania – MSH

11

jeśli używasz dwóch lub więcej widoków Recycler podobne (RecyclerView i NestedView) spróbować tej

recyclerView.setNestedScrollingEnabled(false);

Źródło: Recyclerview inside Nested Scrollview scroll but does not fast scroll like normal Recyclerview or Nested Scrollview

+1

Nie jestem pewien, czy mój problem był taki sam jak oryginalny plakat, ale ten tutaj właśnie naprawiłem. – Larpus

+0

To było to samo dla mnie, a poszukiwania doprowadziły mnie do tego, więc kiedy znalazłem odpowiedź, lubiłem to opublikować tutaj –

1

miałem laggy problem recyclerView gdy jeden z TextView obrębie recyclerView odbierał wartości null. Naprawię to i mój recyclerView przestał być opóźniony.