java - RecyclerView 中 View 的动态位置

标签 java android android-recyclerview android-view

我的问题是基于之前关于我的 Code 的问题- 这是一个具有不同 View 的新闻源,可以垂直或水平滚动或显示各种内容(基本上是广告)

  • 垂直 View
  • 水平 View
  • 广告 View

现在我在 Ben P 的帮助下,在我之前的帖子中使用以下代码组织了我的观点:

this.items = new ArrayList<>();

if (listVertical.size() > 0) {
    items.add(listVertical.remove(0));
}

if (listHorizontal.size() > 0) {
    items.add(listHorizontal.remove(0));
}

while (listVertical.size() > 0 || listAd.size() > 0) {   

    if (listAd.size() > 0) {
        items.add(listAd.remove(0));
    }

    int count = 5;

    while (count > 0 && listVertical.size() > 0) {
        items.add(listVertical.remove(0));
    }
}

这是一种让动态新闻源静态化的方式。所以我尝试在我的 JSON 中使用位置元素来组织我的 View ,如下所示:

{
"horizontal": [{...,position:"1",},{...,position:"3",...},{...,position:"4",...}] ,
"vertical": [{...,position:"2",},{...,position:"5",},{...,position:"6",}] 
"ad": [{...,position:"0",},{...,position:"7",},{...,position:"8",}] 
}

使用此处的代码,应该可以使 Feed 就位:

int length_tot= vertical.size() + horizontal.size() + ad.size();
this.items = new ArrayList<>();

for(int i = 0; i < lenth_tot; i++) {
    if(vertical.getallthepositions_somehow == i) {
        items.add(vertical.remove(0));
    }

    if(horizontal.getallthepositions_somehow == i) {
        items.add(horizontal.remove(0));
    }

    if(ad.getallthepositions_somehow == i) {
        items.add(ad.remove(0));
    }
}

如您所见,我一直在循环遍历所有列表以找到要添加到我的项目列表中的下一个位置。

所以我的问题是:

找到下一个要添加的职位的最快方法是什么?我的解决方案感觉太重了,你有没有更经济的解决方案(从处理器的角度来看)?

这是我的onBindViewHolder:

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

    if (holder.getItemViewType() == VIEW_TYPE_VERTICAL)
        verticalView((VerticalViewHolder) holder, position);

    if (holder.getItemViewType() == VIEW_TYPE_HORIZONTAL)
        horizontalView((HorizontalViewHolder) holder, position);
}

以及来自适配器的 getItemViewType:

@Override
public int getItemViewType(int position) {
    if (items.get(position) instanceof Vertical)
        return VIEW_TYPE_VERTICAL;

    if (items.get(position) instanceof Horizontal)
        return VIEW_TYPE_HORIZONTAL;
}

编辑:

所以我想从服务器中获取我的 JSON 的内容:

{
"horizontal": [{...,position:"1",},{...,position:"3",...},{...,position:"4",...}] ,
"vertical": [{...,position:"2",},{...,position:"5",},{...,position:"6",}] 
"ad": [{...,position:"0",},{...,position:"7",},{...,position:"8",}] 
}

是具有以下查看顺序的新闻源:

- [AD] (position=0)
- [HORIZONTAL] (position =1)
- [VERTICAL] (position=2)
- [HORIZONTAL]
- [HORIZONTAL]

等等……

因此,由于每个 json 数组中的 psoition 项,服务器基本上决定了我的 View 在我的适配器中的顺序

Ben P - 列表中正确顺序的代码:

    Object[] itemsObject = new Object[listVertical.size() + listHorizontal.size() + adList.size()];

    for (Vertical item : listVertical) {
        itemsObject[Integer.parseInt(item.getPosition())] = item;
    }

    for (Horizontal item : listHorizontal) {
        itemsObject[Integer.parseInt(item.getPosition())] = item;
    }

    for (Adfeed item : adList) {
        it
    ArrayList<Object> itemsPos = new ArrayList<>();
    itemsPos.addAll(listVertical);
    itemsPos.addAll(listHorizontal);
    itemsPos.addAll(adList);

    Collections.sort(items, new Comparator<Object>() {
        @Override
        public int compare(Object o1, Object o2) {
            return Integer.compare(o1.getPosition(),o2.getPosition())
        }
    });

垂直、水平和 Adfeed 包含 .getPosition()。那么如何在我的比较器中访问它们呢?

最佳答案

实际上,无论如何,您需要构建一个项目列表,以便在您的适配器中传递以显示在 RecyclerView 中。因此,循环遍历每个列表中的所有元素(即水平、垂直和广告)并不是一个非常糟糕的主意。您实际上是在对要显示在 RecyclerView 中的项目进行一些预处理,以便它可以相应地执行。

我可以在预处理您的数据时提出一项小的改进建议。在您的代码中,您必须在每次迭代中为每个列表再次遍历所有元素。实际上可以优化哪个。考虑到这种预处理是在适配器之外进行的,您可能会这样做。

int total = vertical.size() + horizontal.size() + ad.size();
int[] types = new int[total];

// Considering the positions are not overlapping.
for(int i = 0; i < vertical.size(); i++) {
    types[vertical[i].position] = VIEW_TYPE_VERTICAL;
}

for(int i = 0; i < horizontal.size(); i++) {
    types[horizontal[i].position] = VIEW_TYPE_HORIZONTAL;
}

for(int i = 0; i < add.size(); i++) {
    types[add[i].position] = VIEW_TYPE_ADD;
}

// The type array has the view types for all elements now. 
// Now add the views accordingly in your items list and then pass it to your adapter.
ArrayList<Item> items = new ArrayList<Item>();
for(int i = 0; i < type.length; i++) {
    items.add(getItemBasedOnType(type[i]));
}

// Populate your adapter or pass new elements
adapter.addListItems(items);

getItemBasedOnType 可以是这样的。

private Item getItemBasedOnType(int type) {
    if(type == VIEW_TYPE_VERTICAL) return vertical.remove(0);
    else if(type == VIEW_TYPE_HORIZONTAL) return horizontal.remove(0);
    else return add.remove(0);
}

希望对您有所帮助。

关于java - RecyclerView 中 View 的动态位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57045195/

相关文章:

android - ItemTouchHelper.Callback 方法 onChildDraw 和 onChildDrawOver 之间有什么区别?

android - RecyclerView Adapter 中的静态和非静态 View 有什么区别?

java - if-else 语句无法正常工作

java - 在java中设置源和数据路径

android - 在 Android 上使用 CouchDB 有什么要求?

java - 带有加速度传感器的移动球应用程序看起来不平滑和连续

java - Recyclerview 从 Picasso 加载缓存的图像非常缓慢

java - java 获取二维数组中行和列的最大长度

java - 使用 REST API 实现属性/字段级安全

android - 在 Samsung Galaxy Tab 2.3.3 android 上禁用 ListView 过度滚动