2

在我的2列交錯網格中,我使用無限列表的效果自動將元素10加載10,除了向上滾動時,一切正常。前兩個要素改變了他們的立場。它就像前兩項從一列跳到另一列。Android RecyclerView StaggeredGrid項目在滾動頂部時更改位置

當我閱讀時,適配器必須保存每個元素的狀態。但是,我不知道該怎麼做。

這是我用來顯示StaggeredGrid功能的主代碼

public class SpacesItemDecoration extends RecyclerView.ItemDecoration { 
    private int space; 

    public SpacesItemDecoration(int space) { 
     this.space = space; 
    } 

    @Override 
    public void getItemOffsets(Rect outRect, View view, 
           RecyclerView parent, RecyclerView.State state) { 
     outRect.left = space; 
     outRect.right = space; 
     outRect.bottom = space+1; 

     // Add top margin only for the first item to avoid double space between items 
     if(parent.getChildLayoutPosition(view) == 0) 
      outRect.top = space; 
    } 
} 

public class SolventViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener { 

    public TextView vh_name; 
    public TextView vh_price; 
    public ImageView vh_image; 

    public SolventViewHolders(View v) { 
     super(v); 
     v.setOnClickListener(this); 

     vh_image=(ImageView)v.findViewById(R.id.thumbnail); 
     vh_name= (TextView) v.findViewById(R.id.title); 
     vh_price= (TextView) v.findViewById(R.id.subtitle); 
    } 

    public void sendImage(String url) { 
     Picasso.with(ctx) 
       .load(url) 
       .into(vh_image); 
    } 
    @Override 
    public void onClick(View view) { 
     int position = getPosition(); 

     if (user_id != null) { 

      openDetail(MyLogs.get(position).getId_item(), MyLogs.get(position).getItemName(), MyLogs.get(position).getPrice(), MyLogs.get(position).getDescrip(), MyLogs.get(position).getId_store(), MyLogs.get(position).getId_store()); 
     } 
    } 
} 

public class SolventRecyclerViewAdapter extends RecyclerView.Adapter<SolventViewHolders> { 


    private List<productItem> itemList; 
    private Context context; 

    public SolventRecyclerViewAdapter(Context context, List<productItem> itemList) { 
     this.itemList = itemList; 
     this.context = context; 
    } 
    @Override 
    public SolventViewHolders onCreateViewHolder(ViewGroup parent, int viewType) { 

     View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_mosaico_defoult, null); 
     SolventViewHolders rcv = new SolventViewHolders(layoutView); 

     return rcv; 
    } 

    @Override 
    public void onBindViewHolder(SolventViewHolders holder, int position) { 

     holder.vh_name.setText(itemList.get(position).getName()); 
     holder.vh_price.setText("CLP:"+itemList.get(position).getPrice()); 

    } 

    @Override 
    public int getItemCount() { 
     return this.itemList.size(); 
    } 
} 

#Edit 1:

我這是怎麼實例化的適配器

recyclerView = (RecyclerView)view.findViewById(R.id.recycler_view); 
    recyclerView.setHasFixedSize(true); 

    gaggeredGridLayoutManager = new StaggeredGridLayoutManager(2, 1); 
    recyclerView.setLayoutManager(gaggeredGridLayoutManager); 
    recyclerView.addItemDecoration(new SpacesItemDecoration(2)); 

    populateList(currentPage); 

    rcAdapter= new SolventRecyclerViewAdapter(ctx, MyLogs); 
    recyclerView.setAdapter(rcAdapter); 

的填入方法作爲json格式的asyntask響應發生:

      ... 
      for(int i=0; i < lengthJsonArr; i++) 
      { 

       JSONObject jsonChildNode = jsonMainNode.getJSONObject(i); 

          ... 

       MyLogs.add("name,price,etc"); 
       rcAdapter.notifyDataSetChanged(); 

      } 

這就是我如何保持onScroll:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { 
     @Override 
     public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 

      visibleItemCount = gaggeredGridLayoutManager.getChildCount(); 
      totalItemCount = gaggeredGridLayoutManager.getItemCount(); 
      int[] firstVisibleItems = null; 
      firstVisibleItems = gaggeredGridLayoutManager.findFirstVisibleItemPositions(firstVisibleItems); 
      if (firstVisibleItems != null && firstVisibleItems.length > 0) { 
       pastVisiblesItems = firstVisibleItems[0]; 
      } 

      if (loading) { 
       if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) { 
        loading= false; 
        Log.d("tag", "LOAD NEXT ITEM"); 
        currentPage = currentPage + 1; 
        populateList(currentPage); 
       } 
      } 
     } 
    }); 

我感謝所有幫助

+0

你是如何將元素添加到您的數據列表?顯示用於實例化適配器的代碼以及用新項目更新適配器。你說你正在實現它,它使用無限滾動(但沒有方法來添加數據到支持您的回收商的適配器的數據結構「 –

+0

塞巴斯蒂安, 我得到了同樣的問題,你有一個比bleeding182提出的更好的解決方案? – Rxxxx

+0

@Rxxxx不,這是我找到的唯一解決方案。如果你找到另一個,請讓我現在 – Sebastian

回答

3

這是一個特點。重新排序和重新定位視圖以獲得無縫的項目。

使用setGapStrategy(int gapStrategy)

設置縫隙處理策略StaggeredGridLayoutManager。如果gapStrategy參數與當前策略不同,則調用此方法將觸發佈局請求。

您可能需要GAP_HANDLING_NONE

沒有做任何事情來隱藏差距。

+0

是的,這個工作,但現在滾動留下前兩個元素之間的空間差異。看來一個專欄進一步向下。這是唯一的解決方案? – Sebastian

+0

...你可能只是使用網格佈局? –

1

發生這種情況的原因是,當您向上和向下滾動時,持有人無法識別圖像視圖的寬度和高度。當您向下滾動時清除上部視圖,反之亦然。

使用這樣的:

@Override 
public void onBindViewHolder(ViewHolder viewHolder, int position) { 

MyViewHolder vh = (MyViewHolder) viewHolder; 
ImageModel item = imageModels.get(position); 
RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams)vh.imageView.getLayoutParams(); 
float ratio = item.getHeight()/item.getWidth(); 
rlp.height = (int) (rlp.width * ratio); 
vh.imageView.setLayoutParams(rlp); 
vh.positionTextView.setText("pos: " + position); 
vh.imageView.setRatio(item.getRatio()); 
Picasso.with(mContext).load(item.getUrl()). 
placeholder(PlaceHolderDrawableHelper.getBackgroundDrawable(position)). 
into(vh.imageView); 
} 

爲了清楚看到此鏈接:Picasso/Glide-RecyclerView-StaggeredGridLayoutManager

相關問題