具有行跨度和列跨度的自定义网格视图

时间:2013-01-21 15:03:16

标签: java android gridview scroll html-table

我正在尝试实现具有如下图形视图的网格视图。我已经浏览了各种博客和S.O问题,遗憾的是我无法为一个特定网格项提供行和列跨度,并且网格视图也不支持此功能。 我不想创建动态滚动视图与其他视图之间,因为有大量的数据,它会导致性能问题。 所以如果有人有任何建议。请回复 。 提前致谢。 enter image description here

3 个答案:

答案 0 :(得分:3)

以下是您解决所有问题的方法:https://github.com/felipecsl/AsymmetricGridView 是的,我厌倦了Android没有这样的课程并自己写了。 希望它对你有用。

答案 1 :(得分:2)

您打算为可滚动视图重复该模式吗?更清楚的是,具有大跨度的Grid项是否会定期重复?

一个选项是使用列表视图并使用两个普通视图实现大跨度视图作为列表视图的一行,并带有标记,例如“special_row”,并将常规视图实现为另一行,标记为“normal row” ”。根据要求,您可以通过访问行标记来回收行。

编辑:

我找到了一个像android一样实现pinterest的库。它有一个对称的视图。结帐PinterestLisView

编辑:

Here是另一种有趣的技术,它通过为网格项指定coulmn span和row spans。我从this question开始。我想你可以通过以编程方式指定列和行跨度来消除网格项的静态xml声明。

答案 2 :(得分:0)

这是3列网格的特殊解决方案,其特色项目跨越2x2网格。

public class GridAdapter extends ArrayAdapter<GridAdapter.GridItem> {
    public GridAdapter(Context context, int itemViewResId, List<String> things) {
        super(context, itemViewResId, buildGridItems(things));
    }

    /**
     * Assumes 3 column layout. A list of indices that shows a large
     * item on the right of 1st row, then alternating on every 3rd row 
     * to the left and then right. The large item should occupy a 2x2 grid.
     *
     *   X O O
     *   X O O
     *   X X X
     *   X X X
     *   O O X
     *   O O X
     *   X X X
     *   X X X
     *   X O O
     *   X O O
     *   X X X
     *
     * The indices where the large featured items are in item list is 
     * 1, 9, 19, 27, 37, 45, 55, ...         
     */
    protected static List<Integer> getFeaturedIndex(int total) {
        int pos = 1;
        ArrayList<Integer> index = new ArrayList<Integer>();
        if (pos + 1 < total) {
            index.add(pos);
        }
        for (int i = 0; pos < total; i++) {
            int inc = i % 2 == 0 ? 8 : 10;
            pos += inc;
            if (pos + 1 < total) {
                index.add(pos);
            }
        }
        return index;
    }

    protected static List<GridItem> buildGridItems(List<String> things) {
        ArrayList<GridItem> items = new ArrayList<GridItem>();
        List<Integer> featuredIndex = getFeaturedIndex(things.size());
        ArrayList<GridItem> featured = new ArrayList<GridItem>();
        for (int i = 0, k = things.size(); i < k; i++) {
            GridItem item = new GridItem(things.get(i));
            if (featuredIndex.contains(i)) {
                item.feature = true;
                featured.add(item);
            }
            items.add(item);
        }
        for (GridItem feature : featured) {
            int index = items.indexOf(feature);
            GridItem shim = new GridItem(feature.getModel());
            shim.shim = true;
            items.add(index + 1, shim);
            items.add(index + 3, shim);
            items.add(index + 4, shim);
        }
        return items;
    }

    @Override
    public int getItemViewType(int position) {
        return getItem(position).shim ? 0 : 1;
    }

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = new View(getContext());
        }
        GridItem item = getItem(position);
        if (item.feature) {
            convertView.setLayoutParams(new LayoutParams(400,300));
        } else {
            convertView.setLayoutParams(new LayoutParams(200,150));
        }
        if (item.shim) {
            convertView.setVisibility(View.GONE);
        }
        return convertView;
    }

    public static class GridItem {
        private String mItem;
        private boolean shim = false;
        private boolean feature = false;

        public GridItem(String item) {
            mItem = item;
        }
    }
}

我们的想法是使用GridItem包装项目列表,其中包含featureshim标志,用于确定视图的行为方式。

方法getFeaturedIndex()计算原始列表中应包含哪些项目。然后在buildGridItems()我们采取两个步骤。首先,标记所有特色项目(并保留这些项目的列表)。之后,对于每个特色商品,相对于特色商品添加3个垫片(+ 1,+ 3和+4)。

在特色商品的getView()中,我们将适当的尺寸设置为正常商品的2x2。对于垫片项目,请将可见性设置为GONE