当前位置: 首页 > 知识库问答 >
问题:

如何仅为某些视图类型设置项目装饰?

欧金鹏
2023-03-14

我想在< code>RecycleView中仅绘制< code >标题类型的默认< code>ItemDecoration。但是每个< code >视图类型都会显示< code >分隔线。

定制装修:

class DividerDecoration(context: Context, orientation: Int)
    : DividerItemDecoration(context, orientation){

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        val position = parent.getChildAdapterPosition(view)
        val viewType = parent.adapter!!.getItemViewType(position)
        if (viewType == ITEM_VIEW_TYPE_HEADER){
            super.getItemOffsets(outRect, view, parent, state)
        } else {
            outRect.setEmpty()
        }
    }
}

设置:

val itemDecoration = DividerDecoration(binding.recyclerView.context, 
                                       DividerItemDecoration.VERTICAL)
binding.recyclerView.addItemDecoration(itemDecoration)

对为什么会发生这种情况有什么建议吗?

更新

上面的代码是工作代码。但是有一只虫子。启动应用程序后,分隔符出现在所有元素中,然后只出现在正确的元素中。为什么会这样?

共有3个答案

夹谷星纬
2023-03-14

我的错误包括使用< code>ItemDecoration来为不同的< code >视图类型设置自定义分隔符。我已经形成了一个明确的信念,这种自定义分频器应该只做< code >项目装饰。

根据我的问题中的图像gif,它给出了一个错误。我找不到解决方案。StackOverflow上的其他文章提供了覆盖方法:getItemOffsets()onDraw()。我试图实现至少四个案例。他们都以一个绘图错误结束(类似于我的问题中的gif)。

我不知道是什么原因导致这些绘图错误。感谢Tenfour04的回答和评论。我改变了搜索关键词,找到了简单的解决方法。

顺便说一下,我的应用程序设计采用了谷歌应用程序设计的一些功能。我反编译了其中一个应用的apk。并找到了使分离器完全符合解决方案中描述的资源。在这方面,我可以将这一决定视为谷歌的最佳实践。

我有两个视图类型。每个都有自己的布局。解决方案是在标题布局中添加分隔符。

因为< code>ViewTypeHeader只在有嵌套元素时出现,所以在我的例子中,我不需要为最后一个或第一个元素添加< code>Visible条件。

布局\ViewTypeHeader.xml

<LinearLayout ...>

    <TextView ... />

    <!-- This -->
    <View style="@style/DividerStyle" />

</LinearLayout>

values/styles.xml

<style name="DividerStyle">
    <item name="android:layout_width">match_parent</item>
    <item name="android:layout_height">@dimen/dividerHeight</item>
    <item name="android:background">@android:color/black</item>
</style>

如果有几个< code>ViewType -忘掉< code>ItemDecoration。节省大量时间。

有宏邈
2023-03-14

在我看来,试图在装修实施中做到这一点是混乱的。现在装饰必须了解数据集,因此您有了一个直接访问适配器以访问数据的视图。您要确定哪些位置是多个不同类中的标题。意大利面和重复。

理想情况下,适配器类将处理装饰的应用程序,因此您可以有选择地执行此操作,但是由于它没有,我认为目前最好的方法是将分隔符放在标题布局中,并且在onBindView中,如果位置为0(最上面的标题),则可以关闭其可见性。

安浩瀚
2023-03-14

以下是如何根据视图类型或位置显示或隐藏分隔线。将它包含在你的活动/片段中。

recyclerView.addItemDecoration(new DividerItemDecoration(this, linearLayoutManager.getOrientation()) {
            @Override
            public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
                Drawable d = getDrawable();
                for (int i = 0; i < parent.getChildCount(); i++) {
                    View view = parent.getChildAt(i);
                    int position = parent.getChildAdapterPosition(view);
                    int viewType = parent.getAdapter().getItemViewType(position);
                    
                    // Draw divider only for view type 2 (can also put position here to remove for certain positions)
                    if(viewType == 2) {
                        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();
                        int top = view.getBottom() + params.bottomMargin;
                        int bottom = top + d.getIntrinsicHeight();
                        d.setBounds(0, top, parent.getRight(), bottom);
                        d.draw(c);
                    }
                }
            }
        });
 类似资料:
  • 我用eclipse创建了一个maven项目,并用下面的命令制作了jar文件 打包 当我尝试知道我的mvn项目配置是真的还是不是这个命令 mvn exec:Java-D exec . main class = " giraph . hello world . app " 我得到这个错误: 在helloworld项目上执行目标 org.codehaus.mojo: exec-maven-plugin:

  • 我正在实现N个项目的回收器视图,但我想在列表中只显示3个项目。此外,我已经为回收器视图设置了spanCount,但它不起作用

  • 问题内容: 我使用以下bash脚本仅复制某些扩展名的文件(在本例中为* .sh),但是仍会复制所有文件。怎么了? 问题答案: 我认为过去是用来包含文件的子集,否则会被排除,而不仅仅是包括那些文件。换句话说:您必须考虑 包含 含义 ,不要排除 。 请尝试: 对于rsync 3.0.6或更高版本,需要按以下方式修改顺序(请参见注释): 添加该标志将避免在目标位置创建空目录结构。在3.1.2版中测试。

  • 我有一个,其中有8个项目,我想显示其中的所有项目,但在特定条件下,用户只能选择前两个项目,因此我编写了程序,如果条件为真,用户选择任何其他选项,则会显示一个消息框,显示然后自动选择默认值。到现在为止,一直都还不错。 但现在的问题是,用户无法通过查看的选项来判断他可以选择哪些选项,因此我想做的是,如果条件为真,那么除前两个选项之外的所有选项都应该被禁用(或灰显或其他),这样用户就可以判断出您无法选择

  • 尝试为Angular 7代码库设置Sonarqube以进行代码覆盖率分析。我已经安装了Sonarqube并在Admin中创建了一个项目,获得了授权cmd “sonar-scanner.bat-d”sonar.projectkey=testapp“-d”sonar.sources=.“-d”sonar.host.url=http://127.0.0.1:9000“-d”sonar.login=508

  • 我的Android应用程序无法安装在一些“随机”、较旧的API设备上(任何低于API级别25的设备),错误如下: 所以,基本上看起来… API 我见过类似的问题,答案与小写的包名有关。我已经有了。 有人有什么想法吗? 舱单: BTW我用的是Visual Studio 2019和一夫一妻制3.7