2016-04-18 27 views
8

Tôi đang cố gắng để chơi với Parallax và nhận được một số lỗi lạ, tự hỏi nếu có ai có thể thêm một số đầu vào cho nó. Ứng dụng duy nhất tôi đã nhìn thấy thực hiện thị sai hiệu quả là soundcloud. Nó khá tinh tế, nhưng mỗi mục có một nền hình ảnh và nó có hiệu ứng thị sai khi bạn di chuyển.Hiệu ứng thị sai trên mỗi mục trong chế độ xem của người tái chế?

Tôi đã tạo một RecyclerView tùy chỉnh để xử lý việc này, đây là những gì tôi có cho đến nay:

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

Trong tôi RecyclerView Adaptor của onBindView Tôi có sau đây cũng như:

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

Cuối cùng bên trong phương pháp onViewRecycled Tôi có những điều sau đây:

@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

Vì vậy, các công trình thị sai, nhưng các chế độ xem trong di chuyển RecyclerView của tôi là tốt. Tôi có một CardView bên dưới hình ảnh và nó di chuyển, tạo ra những khoảng trống lớn giữa mỗi mục. Di chuyển là nguyên nhân gây ra điều này, càng di chuyển lên và xuống càng lớn thì khoảng trống càng lớn và hình ảnh sẽ nhỏ hơn khi thị sai di chuyển chúng ra khỏi giới hạn của chúng.

Tôi đã thử làm rối tung các con số như scrollSpeed ​​trong OnScrollListener nhưng trong khi nó làm giảm lỗi, nó cũng làm giảm thị sai.

Có ai có ý tưởng nào về cách tôi có thể đạt được hiệu ứng thị sai lỗi miễn phí trên mỗi mục trong số RecyclerView của mình không? Tôi cảm thấy như tôi đang nhận được một nơi nào đó với điều này nhưng nó vẫn còn rất buggy và tôi không biết bước tiếp theo là gì.

P. Tôi đã thử xem các thư viện của bên thứ ba nhưng tất cả dường như chỉ sử dụng sai số đầu trang như CoordinatorLayout, tôi không tìm thấy bất kỳ thư nào làm điều đó trên mỗi mục trong danh sách.

Tôi hy vọng câu hỏi này sẽ được thảo luận tốt ngay cả khi tôi không giải quyết được vấn đề của mình vì Parallax dường như không được sử dụng trong Android và có rất ít thông tin về nó.

Cảm ơn bạn đã dành thời gian, đánh giá cao mọi trợ giúp.

+0

Hình ảnh có nên được xem là giống nhau trên mỗi chế độ xem không? Hay bạn muốn/cần có thể thiết lập nó cho mỗi mục trong 'onBindVH'? –

+0

Hình ảnh khác nhau, vì vậy, chúng cần phải được đặt mỗi lần. Tôi tìm thấy một thư viện thực hiện nó, sẽ sớm đăng câu trả lời của tôi. –

Trả lời

4

tôi quản lý để có được Parallax làm việc với thư viện này: https://github.com/yayaa/ParallaxRecyclerView

Đối với bất cứ ai làm điều này bản thân, nó vẫn là một điều tốt để chơi và xem nó hoạt động như thế nào.

khái niệm tương tự như mã của tôi nhưng nó thực sự hoạt động! haha.

1

Bạn đang đi đúng hướng. Bạn phải sử dụng một ScrollListener. Hơn nữa, bạn phải truy cập RecyclerViews LayoutManager và lặp qua tất cả các mục được hiển thị và đặt translateY theo số lượng pixel được cuộn.

Mọi thứ trở nên phức tạp hơn một chút, vì bạn không thể sử dụng recyclerView.getChildAt(pos) vì LayoutManager chịu trách nhiệm bố cục các yếu tố và chúng có thể theo thứ tự khác nhau trong LayoutManager hơn getChildAt(pos).

Vì vậy, các thuật toán cơ bản sẽ giống như thế này (pseudo code, giả sử LinearLayoutManager được sử dụng):

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

Cảm ơn bạn đã trả lời. Đó không phải là những gì tôi đã có mặc dù? Trong trình xử lý cuộn của tôi, tôi đang sử dụng LinearLayoutManager để tính toán các khung nhìn. Sử dụng setTranslationY dường như không làm gì cả. postTranslate tạo ra thị sai và hoạt động nhưng tôi vẫn có lỗi được nêu trong câu hỏi của tôi. –

+0

Bạn nói đúng, tôi đã bỏ qua điều đó. lỗi của tôi. Vì vậy, câu hỏi của bạn về cơ bản là làm thế nào để tính toán 'computedParalaxOffset' giá trị, phải không? – sockeqwe

+0

Tôi tìm thấy một thư viện cuối cùng đã có thể sắp xếp mọi thứ. Có vẻ như họ yêu cầu một số lần xem hình ảnh tùy chỉnh mà tôi không sử dụng mà có lẽ là một phần của vấn đề của tôi. –

Các vấn đề liên quan