2016-03-15 14 views
11

Với phiên bản 23.2, chúng tôi hiện có thể sử dụng WRAP_CONTENT cho chiều cao recyclerView, điều này thật tuyệt. Tôi đang làm điều này, tuy nhiên tôi muốn tính toán lại chiều cao sau khi một mục được thêm vào (hoặc gỡ bỏ) vào bộ điều hợp (do đó tăng hoặc giảm chiều cao).RecyclerView tính toán lại WRAP_CONTENT

Cụ thể RecyclerView của tôi bắt đầu bằng 1 mục và sau đó thêm các mục khi người dùng lựa chọn. Vì vậy, tôi cần bố cục RecyclerView để tăng chiều cao, tối đa một điểm. Lý tưởng nhất điều này sẽ xảy ra với một hình ảnh động trơn tru khi danh sách tăng hoặc giảm.

Làm thế nào chúng ta có thể làm cho nó WRAP_CONTENT sau khi nó đã được đặt ra?

Cố gắng:

recyclerview.requestLayout(); 

recyclerview.invalidate(); 
+0

Bạn có thể giải thích những gì bạn đang cố gắng đạt được với nhiều chi tiết hơn không? thêm xml bố trí và một số mã sẽ rất tuyệt ... – crazyPixel

+1

Đảm bảo bạn không gọi 'setHasFixedSize' trên chế độ xem của người tái chế. – Wukash

+0

Tôi gặp sự cố này. Bạn sẽ cần phải gọi số đo, nhưng có một lỗi trong Android M nếu bạn sử dụng nhiều bố cục con. Để làm được điều này, hãy thêm GlobalLayoutListener và thiết lập chiều cao trong onGlobalLayout – zafrani

Trả lời

5

Tôi mong chờ nó để làm việc với View.invalidate().

Nếu điều đó không có tác dụng, hãy thử gọi requestLayout hoặc invalidate trên chế độ xem gốc.

+0

Gọi vô hiệu hóa trên quan điểm cha mẹ đã làm các trick. Tất nhiên nó không animate sự phát triển hoặc thu hẹp lại. Hoạt hình là vấn đề khó khăn hơn nhiều, nhưng đây là giải pháp gần nhất cho vấn đề của tôi. – Patrick

1

Cách thứ I

Bạn có thấy answer này?

Nó không sử dụng recyclerView WRAP_CONTENT, nhưng nó có thể hoạt động.

Bạn cũng có thể tạo recyclerView tùy chỉnh của riêng mình (mở rộng RecyclerView) và ghi đè phương thức onMeasure() ở đó thay vì sử dụng layoutManager trong liên kết.

Lựa chọn II

Cố gắng thiết lập các params bố trí trước khi rút ra xem. Tôi đã không kiểm tra nếu nó được gọi là khi recyclerView thay đổi bố trí, nhưng nếu có, sau đó nó sẽ làm việc. Một cái gì đó như thế này (trong hoạt động của bạn/Fragment onCreate()/onCreateView() phương pháp:

recyclerView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
      @Override 
      public boolean onPreDraw() { 
       recyclerView.getViewTreeObserver().removeOnPreDrawListener(this); 

       YourParentLayoutType.LayoutParams params = (YourParentLayoutType.LayoutParams) recyclerView.getLayoutParams(); 
       params.height = YourParentLayoutType.LayoutParams.WRAP_CONTENT; 
       recyclerView.setLayoutParams(params); 

       return true; 
      } 
     }); 

Sử dụng layout mẹ recyclerView của bạn gõ thay vì YourParentLayoutType trong mã Tôi không chắc chắn điều này sẽ làm việc khi bố trí làm mới, nhưng có lẽ có giá trị. thử

0

sử dụng lớp này:.

Vui lòng sử dụng 23.2.1 là 23,2 là cách buggy

Cũng có bạn đã cố gắng để gọi. 0 trên adapter recyclerview, như xa như tôi nghĩ rằng nó nên mở rộng mà không vấn đề nếu bạn đã cho wrap_content như chiều cao của recyclerview

khác u có thể sử dụng lớp này:

import android.content.Context; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 
import android.view.View; 
import android.view.ViewGroup; 

public class MyLinearLayoutManager extends LinearLayoutManager { 

    public MyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) { 
     super(context, orientation, reverseLayout); 

    } 



    private int[] mMeasuredDimension = new int[2]; 


    @Override 
    public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, 
          int widthSpec, int heightSpec) { 
     final int widthMode = View.MeasureSpec.getMode(widthSpec); 
     final int heightMode = View.MeasureSpec.getMode(heightSpec); 
     final int widthSize = View.MeasureSpec.getSize(widthSpec); 
     final int heightSize = View.MeasureSpec.getSize(heightSpec); 



     int width = 0; 
     int height = 0; 
     for (int i = 0; i < getItemCount(); i++) { 
      if (getOrientation() == HORIZONTAL) { 
       measureScrapChild(recycler, i, 
         View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), 
         heightSpec, 
         mMeasuredDimension); 

       width = width + mMeasuredDimension[0]; 
       if (i == 0) { 
        height = mMeasuredDimension[1]; 
       } 
      } else { 
       measureScrapChild(recycler, i, 
         widthSpec, 
         View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), 
         mMeasuredDimension); 

       height = height + mMeasuredDimension[1]; 
       if (i == 0) { 
        width = mMeasuredDimension[0]; 
       } 
      } 
     } 


     switch (widthMode) { 
      case View.MeasureSpec.EXACTLY: 
       width = widthSize; 
      case View.MeasureSpec.AT_MOST: 
      case View.MeasureSpec.UNSPECIFIED: 
     } 

     switch (heightMode) { 
      case View.MeasureSpec.EXACTLY: 
       height = heightSize; 
      case View.MeasureSpec.AT_MOST: 
      case View.MeasureSpec.UNSPECIFIED: 
     } 

     int widthDesired = Math.min(widthSize,width); 
     setMeasuredDimension(widthDesired, height); 
    } 

    private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, 
            int heightSpec, int[] measuredDimension) { 
     View view = recycler.getViewForPosition(position); 
     // For adding Item Decor Insets to view 
     super.measureChildWithMargins(view, 0, 0); 
     RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams(); 
     int childWidthSpec = ViewGroup.getChildMeasureSpec(
       widthSpec, 
       getPaddingLeft() + getPaddingRight() + getDecoratedLeft(view) + getDecoratedRight(view), 
       p.width); 
     int childHeightSpec = ViewGroup.getChildMeasureSpec(
       heightSpec, 
       getPaddingTop() + getPaddingBottom() + getDecoratedTop(view) + getDecoratedBottom(view) , 
       p.height); 
     view.measure(childWidthSpec, childHeightSpec); 

     // Get decorated measurements 
     measuredDimension[0] = getDecoratedMeasuredWidth(view) + p.leftMargin + p.rightMargin; 
     measuredDimension[1] = getDecoratedMeasuredHeight(view) + p.bottomMargin + p.topMargin; 
     recycler.recycleView(view); 
     } 
    } 
+1

Bạn nên kiểm tra bộ đếm vòng lặp đối với itemCount 'i

3

Làm thế nào RecyclerView Resize bản thân dựa trên với LayoutManger mới

Tiện ích RecyclerView cung cấp cơ sở nâng cao và linh hoạt để tạo danh sách và lưới cũng như hình động hỗ trợ. Bản phát hành này mang đến một tính năng mới thú vị cho API LayoutManager: tự động đo lường!Điều này cho phép RecyclerView tự kích thước dựa trên kích thước nội dung của nó. Điều này có nghĩa là các kịch bản trước đó không có sẵn, chẳng hạn như sử dụng WRAP_CONTENT cho một chiều của RecyclerView, bây giờ là có thể. Bạn sẽ tìm thấy tất cả các LayoutManager được tích hợp sẵn, giờ đây hỗ trợ đo lường tự động.

Do thay đổi này, hãy đảm bảo kiểm tra kỹ thông số bố cục của chế độ xem mục của bạn: thông số bố cục bị bỏ qua trước đây (chẳng hạn như MATCH_PARENT theo hướng cuộn) giờ đây sẽ được tôn trọng hoàn toàn.

Nếu bạn có Trình quản lý bố cục tùy chỉnh không mở rộng một trong các Trình quản lý bố cục tích hợp, đây là API chọn tham gia - bạn sẽ được yêu cầu gọi setAutoMeasureEnabled (true) cũng như thực hiện một số thay đổi nhỏ như được nêu chi tiết Javadoc của phương pháp.

Lưu ý rằng mặc dù RecyclerView làm động các con của nó nhưng nó không sinh động các thay đổi giới hạn của chính nó. Nếu bạn muốn tạo hiệu ứng cho các giới hạn RecyclerView khi chúng thay đổi, bạn có thể sử dụng các API chuyển tiếp.

Vui lòng đọc this

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