0

同樣的問題,不知道這是否算作重複。StaggeredGridLayoutManager錯位(2)

我有一個Android的問題StaggeredGridLayoutManager。這個問題的描述與StaggeredGridLayoutManager dislocation非常相似。

這裏的截圖(遺憾的審查,這些都是CardViews):

enter image description here

和適配器:

public class ProductItemStaggeredAdapter extends RecyclerView.Adapter<ViewHolderRVProductItem> { 
    public ProductItemStaggeredAdapter(RealmResults<ProductItem> items, int theme) { 
     mItems = items; 
     this.theme = theme; 
     setHasStableIds(true); 
    } 

    @Override 
    public ViewHolderRVProductItem onCreateViewHolder(final ViewGroup parent, final int viewType) { 
     Context context = parent.getContext(); 
     int blackGrey1 = ContextCompat.getColor(context, R.color.black_grey1); 
     int white = ContextCompat.getColor(context, R.color.white); 
     LayoutInflater inflater = LayoutInflater.from(context); 
     View view; 

     ViewHolderRVProductItem vh = null; 
     switch (viewType) { 
      case 100: 
       /** Error **/ 
       view = inflater.inflate(R.layout.item_retry, parent, false); 
       StaggeredGridLayoutManager.LayoutParams lp3 = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams(); 
       lp3.setFullSpan(true); 
       view.setLayoutParams(lp3); 
       view.setOnClickListener(retryClickListener); 
       vh = new ViewHolderRVProductItem(view); 
       break; 
      case 101: 
       /** Loading **/ 
       view = inflater.inflate(R.layout.item_loading, parent, false); 
       StaggeredGridLayoutManager.LayoutParams lp4 = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams(); 
       lp4.setFullSpan(true); 
       view.setLayoutParams(lp4); 
       vh = new ViewHolderRVProductItem(view); 
       break; 
      case Banner.ONE: 
       /** 
       * This banner occupies 1 column of the screen 
       * The height is set programmatically based on screen width 
       * 
       * Product image ratio is 32 x 15 
       */ 
       view = inflater.inflate(R.layout.item_banner_big, parent, false); 
       view.setOnClickListener(productClickListener); 
       StaggeredGridLayoutManager.LayoutParams lp = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams(); 
       lp.setFullSpan(true); 
       view.setLayoutParams(lp); 

       view.setOnClickListener(productClickListener); 

       vh = new ViewHolderRVProductItem(view); 
       break; 
      case Banner.TWO: 
       /** 
       * This banner occupies 1 column of the screen 
       * The height is smaller than BANNER_ONE 
       * The height is set programmatically based on screen width 
       */ 
       view = inflater.inflate(R.layout.item_banner_big, parent, false); 
       view.setOnClickListener(productClickListener); 
       StaggeredGridLayoutManager.LayoutParams lp2 = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams(); 
       lp2.setFullSpan(true); 
       view.setLayoutParams(lp2); 

       view.setOnClickListener(productClickListener); 

       vh = new ViewHolderRVProductItem(view); 
       break; 
      case Banner.THREE: 
       /** 
       * This banner occupies 3 column of the screen 
       * The height is set programmatically based on screen width 
       */ 
       view = inflater.inflate(R.layout.item_banner_long_rect, parent, false); 
       view.setOnClickListener(productClickListener); 
       vh = new ViewHolderRVProductItem(view); 
       break; 
      case Banner.FOUR: 
       /** 
       * This banner occupies 3 column of the screen 
       * The height is smaller than BANNER_THREE 
       * The height is set programmatically based on screen width 
       */ 
       view = inflater.inflate(R.layout.item_banner_long_rect, parent, false); 
       view.setOnClickListener(productClickListener); 
       vh = new ViewHolderRVProductItem(view); 
       break; 
      default: /** ProductItem.BANNER_FIVE **/ 
       /** 
       * This banner occupies 2 column of the screen 
       * The height is set programmatically based on screen width 
       */ 
       view = inflater.inflate(R.layout.item_banner_recommended, parent, false); 
       view.setOnClickListener(productClickListener); 
       vh = new ViewHolderRVProductItem(view); 
       break; 
     } 

     /** Set image ratio **/ 
     if (vh.productImage != null) { 
      final ViewHolderRVProductItem finalVh = vh; 
      vh.itemView.post(new Runnable() { 
       @Override 
       public void run() { 
        setImageRatio(finalVh.productImage, viewType, finalVh.productImage.getWidth()); 
       } 
      }); 
     } 

     return vh; 
    } 

    @Override 
    public void onBindViewHolder(final ViewHolderRVProductItem holder, final int position) { 
     if (holder == null) return; 

     final Context context = holder.itemView.getContext(); 
     final ProductItem item = mItems.get(position); 

     holder.itemView.setTag(item); 

     final int bannerType = holder.getItemViewType(); 
     final Banner banner = bannerType == Banner.ONE ? item.getBanner1() : (bannerType == Banner.FIVE ? item.getBanner5() : (bannerType == Banner.TWO ? item.getBanner2() : (bannerType == Banner.THREE ? item.getBanner3() : item.getBanner4()))); 

     if (banner != null && holder.productImage != null) { 
      holder.productImage.post(new Runnable() { 
       @Override 
       public void run() { 
        float width = holder.productImage.getWidth(); 
        float height = holder.productImage.getHeight(); 
        Picasso.with(context) 
          .load(banner.getImageURL6()) 
          .resize((int) width, (int) height) 
          .into(holder.productImage); 
       } 
      }); 
     } 
    } 

    private void setImageRatio(ImageView imgview, int bannerType, int width) { 
     Context context = imgview.getContext(); 
     switch (bannerType) { 
      case Banner.ONE: 
       /** Product image ratio is 32 x 15 **/ 
       float height = (15f/32f) * width; 
       LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) imgview.getLayoutParams(); 
       params.width = width; 
       params.height = (int) height; 
       imgview.setLayoutParams(params); 
       break; 
      case Banner.TWO: 
       /** Product image ratio is 11 x 3 **/ 
       float height1 = (3f/11f) * width; 
       LinearLayout.LayoutParams params1 = (LinearLayout.LayoutParams) imgview.getLayoutParams(); 
       params1.width = width; 
       params1.height = (int) height1; 
       imgview.setLayoutParams(params1); 
       break; 
      case Banner.THREE: 
       /** Product image ratio: 27 x 40 **/ 
       float height2 = (40f/27f) * width; 
       RelativeLayout.LayoutParams params2 = (RelativeLayout.LayoutParams) imgview.getLayoutParams(); 
       params2.width = (int) width; 
       params2.height = (int) height2; 
       imgview.setLayoutParams(params2); 
       break; 
      case Banner.FOUR: 
       int dip8 = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8f, context.getResources().getDisplayMetrics()); 

       /** Product image ratio: 1 x 1 **/ 
       int size = (int) width - dip8; 
       RelativeLayout.LayoutParams params3 = (RelativeLayout.LayoutParams) imgview.getLayoutParams(); 
       params3.width = size; 
       params3.height = size; 
       params3.leftMargin = dip8; 
       params3.topMargin = dip8; 
       params3.rightMargin = dip8; 
       imgview.setLayoutParams(params3); 
       break; 
      case Banner.FIVE: 
       /** Product image ratio: 162 x 71 **/ 
       float height3 = (71f/162f) * width; 
       RelativeLayout.LayoutParams params4 = (RelativeLayout.LayoutParams) imgview.getLayoutParams(); 
       params4.width = (int) width; 
       params4.height = (int) height3; 
       imgview.setLayoutParams(params4); 
       break; 
     } 
    } 
} 

事情了previous problem而這個問題所做的是改變以編程方式顯示ImageView寬度&高度。爲什麼更改View的佈局會影響RecyclerView

回答

0

我找到了最終解決方案。而不是使用previous solution,我已經找到了罪魁禍首:

final ViewHolderRVProductItem finalVh = vh; 
     vh.itemView.post(new Runnable() { 
      @Override 
      public void run() { 
       setImageRatio(finalVh.productImage, viewType, finalVh.productImage.getWidth()); 
      } 
     }); 

我認爲這是不建議修改使用post適配器內部ImageView的大小。我現在使用AspectRatioImageView,並且工作順利。