PinnedHeader Google 加上 GridView?

2024-05-30

背景

Google+(google+)应用程序可以很好地查看“亮点”类别中的图像。

对于该屏幕上的每个部分,他们制作了一个标题,其中包含可单击的文本和一个用于选择该部分的所有照片的按钮。对于每个部分,他们还以网格状方式显示照片。

它是这样的:

这是另一张更新的图片:link https://lh6.ggpht.com/2ocrzuKfmJLr0O2_Vmd5s4GAPa1a8sPbMWZBnq60rt2l7JDsylGjOOvAYAA-44g7Zg=h900-rw .

由于某种原因,此处的图像显示了共享按钮而不是选择,但这不是我想讨论的问题。

问题

我需要对照片进行类似的查看(包括标题上的按钮),但也要使顶部标题始终可见(又名“固定标题”,如这个项目 http://blog.peterkuterna.net/2011/05/pinned-header-listview-as-in-contacts.html) .

事实上,我什至不在乎它是否会被固定(尽管它可能是一个很好的功能)。

我尝试过的

我只发现 2 个具有固定标题 gridViews 的库:

  1. 粘性网格标题 https://github.com/TonicArtos/StickyGridHeaders- 看起来不错。 API和代码设计非常好。然而,我在一些设备上玩过它,发现它崩溃了,出现了一个非常奇怪的异常。我已经报道过这件事here https://github.com/TonicArtos/StickyGridHeaders/issues/88,但当我考虑其他问题时,我认为这个项目不会很快得到解决。

  2. 粘性标题 https://github.com/DWorkS/AStickyHeader- 这个没有我能找到的任何崩溃和错误,但它缺乏良好的代码设计,而且不太可定制。标题不能被点击,也不能有像 Google-plus 那样的按钮。我尝试添加它,但由于某种原因该按钮没有显示。我已经报道了我的言论here https://github.com/DWorkS/AStickyHeader/issues/5.

问题

有没有人尝试过处理这样的事情?

任何可用的库或对我尝试过的库的修改允许拥有我所写的内容?


由于我找不到任何其他解决方案,我决定制作自己的解决方案(基于我制作的另一个代码的代码,here https://stackoverflow.com/a/21504515/878126)

它被用在 ListView 上,但效果很好。您只需在 listView 上设置适配器即可。您可以准确设置标题的外观以及每个单元格的外观。

它的工作原理是有两种类型的行: header-rows 和 cells-rows 。

这不是最好的解决方案,因为它创建了额外的视图,而不是让 ListView/GridView (或您使用的任何内容)正确放置单元格,但它工作正常并且不会崩溃

它也没有点击项目(因为它用于 listView),但对于使用此代码的人来说添加应该不难。

遗憾的是它也没有标题作为固定标题,但也许可以与这个库(PinnedHeaderListView) https://github.com/JimiSmith/PinnedHeaderListView .

这是代码:

public abstract class HeaderGridedListViewAdapter<SectionData, ItemType> extends BaseAdapter {
    private static final int TYPE_HEADER_ROW = 0;
    private static final int TYPE_CELLS_ROW = 1;
    private final int mNumColumns;
    private final List<Row<SectionData, ItemType>> mRows = new ArrayList<Row<SectionData, ItemType>>();
    private final int mCellsRowHeight;
    private final Context mContext;

    public HeaderGridedListViewAdapter(final Context context, final List<Section<SectionData, ItemType>> sections,
            final int numColumns, final int cellsRowHeight) {
        this.mContext = context;
        this.mNumColumns = numColumns;
        this.mCellsRowHeight = cellsRowHeight;
        for (final Section<SectionData, ItemType> section : sections) {
            // add header
            Row<SectionData, ItemType> row = new Row<SectionData, ItemType>();
            row.section = section;
            row.type = TYPE_HEADER_ROW;
            mRows.add(row);
            int startIndex = 0;
            // add section rows
            for (int cellsLeft = section.getItemsCount(); cellsLeft > 0;) {
                row = new Row<SectionData, ItemType>();
                row.section = section;
                row.startIndex = startIndex;
                row.type = TYPE_CELLS_ROW;
                cellsLeft -= Math.min(mNumColumns, cellsLeft);
                startIndex += mNumColumns;
                mRows.add(row);
            }
        }
    }

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

    @Override
    public int getItemViewType(final int position) {
        return getItem(position).type;
    }

    @Override
    public int getCount() {
        return mRows.size();
    }

    @Override
    public Row<SectionData, ItemType> getItem(final int position) {
        return mRows.get(position);
    }

    @Override
    public long getItemId(final int position) {
        return position;
    }

    @Override
    public View getView(final int position, final View convertView, final ViewGroup parent) {
        final Row<SectionData, ItemType> item = getItem(position);
        switch (item.type) {
        case TYPE_CELLS_ROW:
            LinearLayout rowLayout = (LinearLayout) convertView;
            if (rowLayout == null) {
                rowLayout = new LinearLayout(mContext);
                rowLayout.setOrientation(LinearLayout.HORIZONTAL);
                rowLayout.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT, mCellsRowHeight));
                rowLayout.setWeightSum(mNumColumns);
            }
            final int childCount = rowLayout.getChildCount();
            // reuse previous views of the row if possible
            for (int i = 0; i < mNumColumns; ++i) {
                // reuse old views if possible
                final View cellConvertView = i < childCount ? rowLayout.getChildAt(i) : null;
                // fill cell with data
                final View cellView = getCellView(item.section, item.startIndex + i, cellConvertView, rowLayout);

                LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) cellView.getLayoutParams();
                if (layoutParams == null) {
                    layoutParams = new LinearLayout.LayoutParams(0, mCellsRowHeight, 1);
                    cellView.setLayoutParams(layoutParams);
                } else {
                    final boolean needSetting = layoutParams.weight != 1 || layoutParams.width != 0
                            || layoutParams.height != mCellsRowHeight;
                    if (needSetting) {
                        layoutParams.width = 0;
                        layoutParams.height = mCellsRowHeight;
                        layoutParams.weight = 1;
                        cellView.setLayoutParams(layoutParams);
                    }
                }
                if (cellConvertView == null)
                    rowLayout.addView(cellView);
            }
            return rowLayout;
        case TYPE_HEADER_ROW:
            return getHeaderView(item.section, convertView, parent);
        }
        throw new UnsupportedOperationException("cannot create this type of row view");
    }

    @Override
    public boolean areAllItemsEnabled() {
        return false;
    }

    @Override
    public boolean isEnabled(final int position) {
        return false;
    }

    /** should handle getting a single header view */
    public abstract View getHeaderView(Section<SectionData, ItemType> section, View convertView, ViewGroup parent);

    /**
     * should handle getting a single cell view. <br/>
     * NOTE:read the parameters description carefully !
     * 
     * @param section
     *            the section that this cell belongs to
     * @param positionWithinSection
     *            the position within the section that we need to fill the data with. note that if it's larger than what
     *            the section can give you, it means we need an empty cell (same the the others, but shouldn't show
     *            anything, can be invisible if you wish)
     * @param convertView
     *            a recycled row cell. you must use it when it's not null, and fill it with data
     * @param parent
     *            the parent of the view. you should use it for inflating the view (but don't attach the view to the
     *            parent)
     */
    public abstract View getCellView(Section<SectionData, ItemType> section, int positionWithinSection,
            View convertView, ViewGroup parent);

    // ////////////////////////////////////
    // Section//
    // /////////
    public static class Section<SectionData, ItemType> {
        private final List<ItemType> mItems;
        private final SectionData mSectionData;

        public Section(final SectionData sectionData, final List<ItemType> items) {
            this.mSectionData = sectionData;
            this.mItems = items;
        }

        public SectionData getSectionData() {
            return mSectionData;
        }

        public int getItemsCount() {
            return mItems.size();
        }

        public ItemType getItem(final int posInSection) {
            return mItems.get(posInSection);
        }

        @Override
        public String toString() {
            return mSectionData;
        }
    }

    // ////////////////////////////////////
    // Row//
    // /////
    private static class Row<SectionData, ItemType> {
        int type, startIndex;
        Section<SectionData, ItemType> section;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PinnedHeader Google 加上 GridView? 的相关文章

  • 您的应用中的 Google Analytics SDK

    我按照这里的说明进行操作 https developers google com analytics devguides collection android v3 https developers google com analytics
  • 即使我单击“运行”,Eclipse 也会运行调试模式

    Eclipse 总是在调试模式下启动我的应用程序 即使我单击常规的 运行 按钮 有任何想法吗 我发现我必须重新启动 Xoom 才能使其再次正常工作
  • 使用 ColorMatrix 调整亮度

    我正在尝试使用 ColorMatrix 调整图像的亮度 当尝试调整色相时 您可以在 Photoshop 中看到此选项 亮度和亮度也是两个不同的功能 但我不知道要更改哪些值才能实现此目的 目前我可以使用此代码更改色调 public stati
  • 如何在Android上获取当前播放曲目的路径[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想编写一个应用程序将当前播放的音乐流式传输到另一台设备 两个设备之间的连接确实有效 我还可以通过 wifi 传输一些字符串 但在获取
  • Android Widget ID 是否持久

    在从桌面删除该 Widget 实例之前 您从操作系统收到的用户桌面上特定 Widget 实例的 Widget ID 是否一致 我找不到任何明确说明这一点的文档 但我假设这是因为文档说您可以使用小部件 id 来存储任何实例配置信息 我想将一些
  • 需要对某些片段禁用 CollapsingToolbarLayout 的展开

    我有一个AppCompatActivity控制替换许多片段 这是我的布局 活动 main xml
  • AIRPLANE_MODE 的广播接收器无法与 SDK 26 一起使用

    通常 我使用简单的代码来放置Toast当用户改变AIRPLANE MODE 并且它可以使用targetSdkVersion 25 我的 AirPlaneModeReceiver public class AirPlaneModeReceiv
  • 突出显示列表视图项目

    我需要在触摸列表视图项目时突出显示它并保持突出显示状态 我尝试了我发现的一切 但没有任何效果 这是我的代码 这是列表视图
  • 将项目添加到 android 框架的设置中

    我正在 android 框架中工作 我想向 android 操作系统中的现有设置添加一个项目 您能告诉我如何执行此操作吗 首先阅读有关偏好活动 http developer android com reference android pre
  • Android 音乐播放器应用程序:如何为服务中运行的媒体播放器设置完整的侦听器?

    我正在编写一个音乐播放器应用程序 我在服务中有 MediaPlayer 对象 问题是 我不知道如何从服务更新用户界面 例如 我想更新当前歌曲的剩余时间 但是 因为 MediaPlayer 正在服务 我无法设置 MediaPlayer 对象的
  • Android Studio APK META-INF/BCKEY.DSA 中复制的重复文件

    我的代码构建得很好 但是当我尝试在调试中运行它时 出现以下错误 Error Execution failed for task app transformResourcesWithMergeJavaResForDebug com andro
  • 在 Android 中使用 AES 加密的最佳实践是什么?

    我为什么问这个问题 我知道人们对 AES 加密存在很多疑问 即使对于 Android 也是如此 如果您在网络上搜索 会发现很多代码片段 但在每个页面上 在每个 Stack Overflow 问题中 我都发现了另一个具有重大差异的实现 所以我
  • Android - 使用 SAX 解析器解析大文件

    我正在尝试使用 SAX 解析器解析来自 webservice 的 xml 数据 当我尝试使用 URL 解析数据 大小 7 4MB 时 它工作正常 但是当我从 URL 复制 xml 数据并放置 xml 文件时 size 7 4MB 在raw文
  • 如何防止应用程序被盗(针对Android应用程序)?

    我想知道防止人们窃取我的应用程序的最有效方法是什么 在线下载 apk 的副本而不是购买它 我已经花了一个lot特别是 Droidbox 上的时间 并且不会发布 Sync 直到我可以保证提供专业版本的非法副本的人无法发布 有人实施过这个吗 我
  • GridView:冻结第一列和冻结列标题

    嗨 任何人都可以告诉如何冻结 gridview 标题和基于轴的一些两列 因此 gridview 应该同时具有垂直和水平滚动 以便在垂直滚动时需要冻结标题 在水平滚动时冻结列 嘿 我找到了一种冻结网格标题的有效方法 最终网格被渲染为表格 所以
  • 如何在Room的数据库迁移中正确添加索引?

    我在迁移 Room 数据库时遇到问题 在更新的数据库中 我必须将一个字段从整数更改为双精度值 我读到它并不像听起来那么容易 为了做到这一点 我必须使用这个更改后的属性创建新的临时表 复制前一个表中的所有值 删除旧的值 最后重命名临时表 我的
  • 使用 twitter API 1.1 在 Android 应用程序中显示 twitter feed

    基本上我想展示这个提要 https en twitter com epl live https en twitter com epl live在我的应用程序中 由于 twitter 更改了其 api 1 1 每个调用都必须经过授权 我发现的
  • 用户通过 firebase 动态链接安装应用程序并在应用程序抽屉上打开应用程序后,如何获得深层链接?

    我正在使用 firebase 动态链接邀请朋友使用我的应用程序 一切都很好 单击邀请链接会将我带到 Playstore 当我安装应用程序并等待其完成时 Playstore 会向我显示 继续 按钮 当我单击此按钮时 应用程序将打开 并且我会收
  • Android - 检测视图上的双击和三次点击

    我一直在尝试构建一个可以检测双敲击和三敲击的敲击检测器 在我的努力失败后 我在网上搜索了很长时间以找到可以使用的东西 但没有运气 奇怪的是 像这样的图书馆如此稀缺 有什么帮助吗 你可以尝试这样的事情 尽管我通常建议不要使用三次点击作为一种模
  • 片段中的 SavedInstanceState 始终为 null

    我使用 XML 以及活动中的 setContentView 将片段附加到活动 A 有一个问题 因为我的片段中有非常动态的视图 所以当方向改变时 我必须恢复所有的观点状态 我有问题 因为我正在使用类似的东西 public void onSav

随机推荐

  • 向 JList 添加滚动条? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何将 JList 添加到 JScrollPane 把你的JList in a JScrollPane JScrollPane scrol
  • 数据结构的优化存储以实现快速查找和持久化

    Scenario 我有以下方法 public void AddItemSecurity int itemId int userIds public int GetValidItemIds int userId 最初我正在考虑表单上的存储 i
  • Perl:模板工具包的替代品

    我使用模板工具包来扩展现有的领域特定语言 verilog 已经超过 3 年了 虽然总的来说我对此感到满意 但主要的刺激性是 当出现语法 undef 错误时 错误消息不包含用于调试错误的正确行号信息 例如我会收到一条消息 指示 0 未定义 因
  • 在android中点击地图获取坐标

    我正在尝试做这样的事情 我有一个地图活动 当用户点击地图时 它会显示该位置的坐标 我已经重写了 onclick 方法 但它甚至没有被调用 任何想法 public class MapPoint extends MapActivity impl
  • rspec 用户测试给出“未定义的局部变量或方法‘confirmed_at’”

    我的 rspec 测试给了我 NameError undefined local variable or method confirmed at for
  • 将 NSDictionary 保存到文件有任何限制吗

    我想用下面的方法来保存NSDictionary void writeDicToFile NSDictionary dic fileName NSString fileName NSString filePath NSTemporaryDir
  • Javascript 制作音频 blob

    我正在测试 html 音频标签 我想制作音频 blob url 就像 youtube 或 vimeo 那样 并将其添加到 src 开始播放音频 我一直在测试new Blob and URL createObjectURL 但我不知道如何使用
  • 为什么我的 NSTableView 中的图像淡出?

    首先 有一个NSArrayController 服务器 其内容是 服务器 对象的数组 我也有一个NSTableView与一列 该列绑定到服务器的 arrangedObjects status 属性 我用的是自定义的NSValueConver
  • 不同类型的列表?

    data Plane Plane point Point normal Vector Double data Sphere Sphere center Point radius Double class Shape s where inte
  • Applescript 应用程序从文件中读取

    我有一个已编译的 AppleScript 应用程序 已将其移至 Windows 服务器 然后我想将一个文本文件插入到应用程序中 在 Windows 上看起来像一个 zip 文件 myapplescript app Contents Reso
  • 在列表中查找匹配项的最简洁方法

    在列表中查找内容的最佳方式是什么 我知道 LINQ 有一些不错的技巧 但我们也可以获取有关 C 2 0 的建议 让我们对这个常见的代码模式进行最佳重构 目前我使用这样的代码 mObjList is a List
  • 如何在Python中反转列表的列表? [复制]

    这个问题在这里已经有答案了 我想知道如何反转 python 中的列表列表 例如 原来的 list 1 2 3 4 5 6 7 8 9 输出 new list 7 8 9 4 5 6 1 2 3 现在 我正在尝试这样做 new list re
  • 如何使用 nohup 获取正在运行的程序列表

    我正在通过 SSH 连接访问运行 CentOS linux 发行版 的服务器 由于我无法始终保持登录状态 因此我使用 nohup command 来运行我的程序 我找不到如何获取我开始使用 nohup 的所有程序的列表 工作 只有在我注销之
  • 从我的应用程序 Helm 图表配置第三方 Helm 图表

    我似乎在任何地方都找不到任何关于此的明确信息 但是 Helm 图表中是否有可能需要第三方 例如stable jenkins 并指定配置值 我看到的所有示例都是为了运行helm install直接命令 但我希望能够将其配置为我的应用程序的一部
  • Opera 中 margin-bottom 的计算方式不同

    我有一个具有相对位置的 div 和一个具有绝对位置的子 div div class out div div div CSS container width 100px height 100px position relative insid
  • ASP.NET 会员电子邮件验证

    尝试基于 C 创建电子邮件验证本文 https web archive org web 20211020153319 https www 4guysfromrolla com articles 062508 1 aspx 我创建了一个 ja
  • Strongloop 环回 如何使用路由进行静态服务?

    我想做类似的事情 server js app use client loopback static dirname client using middleware json 但该示例仅适用于根 files loopback static p
  • 3D 空间中两个盒子之间的交集

    我想为我的图形引擎实现一个碰撞检测系统 我不知道这是否是常见的方法 但我的想法是将任何实体对象 如网格或相机 绑定在 3D 盒子内 这会给我比球体更准确的结果 这个盒子由八个顶点定义 x0 min vertices x off parsin
  • 使用 jstl 进行调试 - 具体如何进行?

    我一直试图理解BalusC的回答 https stackoverflow com questions 3177733 how to avoid java code in jsp files关于可调试性 我仍然无法弄清楚 jstl 标签如何比
  • PinnedHeader Google 加上 GridView?

    背景 Google google 应用程序可以很好地查看 亮点 类别中的图像 对于该屏幕上的每个部分 他们制作了一个标题 其中包含可单击的文本和一个用于选择该部分的所有照片的按钮 对于每个部分 他们还以网格状方式显示照片 它是这样的 这是另