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

заселить метод выполняется как ответ asyntask, который поступает в формате json:

      ... 
      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

Sebastian, У меня такая же проблема, у вас есть лучшее решение, чем то, что предлагает кровотечение182 ? – 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

Смежные вопросы