8

Próbuję grać z Parallaxem i robić dziwne błędy, zastanawiając się, czy ktoś może dodać do niego jakiś sygnał wejściowy. Jedyną aplikacją, którą widziałem skutecznie wdrażającą paralaksę, jest soundcloud. Jest dość subtelny, ale każdy element ma tło obrazu i ma efekt paralaksy podczas przewijania.Efekt paralaksy na każdy element w widoku recyklera?

I utworzeniu niestandardowego RecyclerView obsłużyć to, tutaj jest to, co mam tak daleko:

public class ParallaxScrollListener extends RecyclerView.OnScrollListener { 

private float scrollSpeed = 0.5f; 

@Override 
public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
    super.onScrolled(recyclerView, dx, dy); 
    LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); 

    int firstVisible = layoutManager.findFirstVisibleItemPosition(); 
    int visibleCount = Math.abs(firstVisible - layoutManager.findLastVisibleItemPosition()); 

    Matrix imageMatrix; 
    float tempSpeed = -100; 

    if (dy > 0) { 
     tempSpeed = scrollSpeed; 
    } else if (dy < 0) { 
     tempSpeed = -scrollSpeed; 
    } 

    for (int i = firstVisible; i < (firstVisible + visibleCount); i++) { 
     ImageView imageView = ((MyClass.MyAdapter.MyViewHolder) recyclerView.getLayoutManager().findViewByPosition(i).getTag()).image; 
     if (imageView != null) { 
      imageMatrix = imageView.getImageMatrix(); 
      imageMatrix.postTranslate(0, tempSpeed); 
      imageView.setImageMatrix(imageMatrix); 
      imageView.invalidate(); 
     } 
    } 
} 

W moim RecyclerView adaptera onBindView Mam następujący także:

Matrix matrix = viewHolder.image.getImageMatrix(); 
matrix.postTranslate(0, 0); 
viewHolder.image.setImageMatrix(matrix); 
viewHolder.itemView.setTag(viewHolder); 

Wreszcie wewnątrz metody onViewRecycled mam następujące:

@Override 
    public void onViewRecycled(MyViewHolder viewHolder) { 
     super.onViewRecycled(viewHolder); 
     if (viewHolder.image != null) { 
      viewHolder.image.setScaleType(ImageView.ScaleType.MATRIX); 
      Matrix matrix = viewHolder.image.getImageMatrix(); 
      // this is set manually to show to the center 
      matrix.reset(); 
      viewHolder.image.setImageMatrix(matrix); 
     } 
} 

I been working with this code on Github to get the idea

Tak działa paralaksa, ale również widoki z mojego okna RecyclerView. Mam CardView pod obrazem i porusza się, tworząc duże odstępy między poszczególnymi elementami. Powoduje to przewijanie, im bardziej przewijanie w górę iw dół, tym większe stają się luki, a obrazy stają się mniejsze, gdy paralaksa usuwa je z ich granic.

Próbowałem się bawić z liczbami takimi jak scrollSpeed ​​w OnScrollListener, ale jednocześnie redukując błąd, redukuje on również paralaksę.

Czy ktoś ma jakieś pomysły na temat tego, w jaki sposób mogę uzyskać wolny od błędów efekt paralaksy na każdym produkcie w moim RecyclerView? Czuję, że mam gdzieś to osiągnąć, ale nadal jest bardzo błędny i nie wiem, jaki jest następny krok.

P.s Próbowałem już patrzeć na bibliotekach stron trzecich, ale wszystkie wydają się używać tylko paralaksy nagłówka, takich jak CoordinatorLayout, nie znalazłem, że robią to tylko na każdej pozycji na liście.

Mam nadzieję, że to pytanie będzie miało dobrą dyskusję, nawet jeśli nie rozwiążę problemu, ponieważ Parallax wydaje się być niedostatecznie wykorzystany w Androidzie i jest bardzo mało w tej sprawie.

Dzięki za poświęcony czas, doceń każdą pomoc.

+0

Czy obraz, który powinien być paralaksy taki sam w każdym widoku? Czy chcesz/musisz móc ustawić dla każdej pozycji w 'onBindVH'? –

+0

Różne obrazy, więc tak, muszą być ustawione za każdym razem. Znalazłem bibliotekę, która to robi, wkrótce opublikuje moją odpowiedź. –

Odpowiedz

4

udało mi się dostać Parallax pracy z tej biblioteki: https://github.com/yayaa/ParallaxRecyclerView

Dla każdego, kto robi to samodzielnie, nadal dobrze jest grać i zobaczyć, jak to działa.

Podobny koncept do mojego kodu, ale tak naprawdę działa! ha ha.

1

Jesteś na dobrej drodze. Musisz użyć ScrollListener. Co więcej, musisz uzyskać dostęp do RecyclerViews LayoutManager i powtórzyć wszystkie elementy, które są widoczne i ustawić translateY w zależności od ilości przesuwanych pikseli.

Rzeczy stają się nieco bardziej skomplikowane, ponieważ nie można użyć recyclerView.getChildAt(pos), ponieważ LayoutManager jest odpowiedzialny za elementy układu i mogą być w innej kolejności w LayoutManager niż getChildAt(pos).

Więc algorytm zasadzie powinien wyglądać tak (pseudo kod, zakładając LinearLayoutManager jest używany):

for (int i = layoutManager.findFirstVisibleItemPosition(); i <= layoutmanager.findLastVisibleItemPosition; i++){ 

    // i is the adapter position 

    ViewHolder vh = recyclerView.findViewHolderForAdapterPosition(i); 
    vh.imageView.setTranslationY(computedParalaxOffset); // assuming ViewHolder has a imageView field on which you want to apply the parallax effect 
} 
+0

Dzięki za odpowiedź. Czy to nie jest to, co już mam? W moim odbiorniku przewijania używam LinearLayoutManager do obliczania widoków. Używanie setTranslationY również nie działa. postTranslate tworzy paralaksę i działa, ale nadal mam błąd opisany w moim pytaniu. –

+0

Masz rację, przeoczyłem to. mój błąd. Więc twoje pytanie w zasadzie jest jak obliczyć wartość 'computedParalaxOffset', prawda? – sockeqwe

+0

Znalazłem w końcu bibliotekę, która była w stanie wszystko uporządkować. Wygląda na to, że wymagały niestandardowego widoku obrazu, którego nie używałem, co prawdopodobnie jest częścią mojego problemu. –

Powiązane problemy