2016-04-18 11 views
8

私はParallaxで遊んで、奇妙なバグを手に入れようとしています。私が視差を効果的に実装するのを見た唯一のアプリはサウンドクラウドです。それは非常に微妙ですが、各項目には画像の背景があり、スクロールする際に視差効果があります。リサイクラービューの各項目に視差効果がありますか?

私はこれを処理するためのカスタムRecyclerViewを作成しました

は、ここで私がこれまで持っているものです。

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(); 
     } 
    } 
} 

RecyclerViewアダプタのonBindView私だけでなく、次があります。最後に

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

onViewRecycled方法の中で私は以下を持っています:

@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

視差は機能しますが、RecyclerViewのビューも同様に動きます。私はイメージの下にCardViewを持っていて、それは動いて、各アイテムの間に大きなギャップを作ります。スクロールが原因で、スクロールが上下するほどスクロールが大きくなり、視差が小さくなるにつれて画像が小さくなります。

私はOnScrollListenerのscrollSpeedのような数字を使いこなそうとしましたが、バグを減らしながら視差も減らしています。

誰も私のRecyclerViewの各項目にバグのない視差効果をどのように達成できるかについてのアイデアはありますか?私はこれでどこかになっているように感じますが、それはまだ非常にバギーであり、次のステップが何か分かりません。

P.s私はサードパーティのライブラリを見てみましたが、それらはすべてCoordinatorLayoutのようなヘッダーの視差だけを使用しているようですが、リスト内の各項目にそのようなことはありません。

私はこの問題が解決できない場合でも、ParallaxはAndroidで十分に活用されていないようだと思っています。

お時間をいただき、ありがとうございました。

+0

すべてのビューで視差が同じになるイメージはありますか?あるいは、あなたは 'onBindVH'の各項目のためにそれを設定できるようにしたい/したいですか? –

+0

イメージが異なるので、毎回設定する必要があります。私はそれを行うライブラリを見つけ、すぐに私の答えを投稿します。 –

答えて

4

私は視差がこのライブラリでの作業を取得するために管理:これ自体をやって誰のためのhttps://github.com/yayaa/ParallaxRecyclerView

を、それが動作し、それがどのように動作するか見ることは、まだまだ良いことです。

私のコードと似た概念ですが、実際には機能します!ハハ。

1

あなたは正しい方向にあります。 ScrollListenerを使用する必要があります。さらに、RecyclerViews LayoutManagerにアクセスし、表示されているすべてのアイテムを反復処理し、スクロールされるピクセルの量に応じてtranslateYを設定する必要があります。

recyclerView.getChildAt(pos)を使用することができないため、物事は少し複雑になります。なぜなら、LayoutManagerはレイアウト要素を担当し、それらはgetChildAt(pos)よりもLayoutManagerの順序が異なる可能性があるからです。

ので、アルゴリズムは基本的に(LinearLayoutManagerが使用されていると仮定すると、擬似コード)を次のようになります。

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

返信いただきありがとうございます。これは私がすでに持っているものではありませんか?スクロールリスナーでは、LinearLayoutManagerを使用してビューを計算しています。 setTranslationYを使用しても何もしないようです。 postTranslateは視差を作成し、動作しますが、私はまだ私の質問で概説されたバグを持っています。 –

+0

あなたは正しいです、私はそれを見落としました。私の悪い。だからあなたの質問は基本的には 'computedParalaxOffset'値を計算する方法ですね。 – sockeqwe

+0

私は最終的にすべてを並べ替えることができたライブラリを見つけました。彼らはおそらく私の問題の一部である私が使用していないカスタムイメージビューを必要としているようだ。 –

関連する問題