使用位置更改LinearLayout的背景

时间:2018-01-14 00:47:56

标签: android

我有一个LinearLayout,我想用位置改变背景,它第一次改变,但随后它随机变化。我正在使用RecyclerView和ButterKnife。

body{
    margin: 0;
    border: 0;
    padding: 0;
}
/* Navigation */
.header{
    width: 100vw;
    height: 6vh;
    background: #111111;
    display: flex;
    align-items: center;
    justify-content: center;
    /* additional */
    position: relative; /* required to declare a z-index property and create new stacking context */
    z-index: 1;
}
.header div{
    flex: 1;
}
.header-logo{
    padding-left: 5vw;
}
#header-logo{
    height: 4vh;
}
.header-nav{
    text-align: right;
}
.nav-container{
    padding-right: 5vw;
}
.nav-list1{
    font-family: Oswald;
    font-weight: 500;
    font-size: 1em;
    display: initial;
    padding: 0.25vh 1.25vw;
    color: white;
}
.nav-list2{
    font-family: Oswald;
    font-weight: 500;
    font-size: 1em;
    display: initial;
    border-style: solid;
    border-width: 5px;
    padding: 0.25vh 1vw;
    border-image: linear-gradient(bottom right, #c71d6f 0%, #e36a64 100%);
    -moz-border-image: -moz-linear-gradient(bottom right, #c71d6f 0%, #e36a64 100%);
    -webkit-border-image: -webkit-linear-gradient(bottom right, #c71d6f 0%, #e36a64 100%);
    border-image-slice: 1;    
}
.nav-list2:hover{
    background: linear-gradient(bottom right, #c71d6f 0%, #e36a64 100%);
}
/* End Navigation */

/* Slideshow */
.section1{
    background: url(files/home-slideshow-001.jpeg);
    height: 94vh;
    background-size: cover;
}
#overlay{
    font-family: Oswald;
    text-transform: uppercase;
    font-size: 3vw;
    font-weight: 700;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}
/* End Slideshow */

这里是显示视图如何的图像 in this image shows the positions 0, 1, 2 and 3

1 个答案:

答案 0 :(得分:0)

滚动时视图会被回收。奇数位置上的新项目可能会重复使用偶数位置的视图,导致一段时间内所有内容都具有灰色背景。

快速修复

修复它的快速而肮脏的方法是添加else分支并明确说奇数项目应该具有透明背景:

if (position % 2 == 0) {
    holder.linearLayout.setBackgroundColor(Color.GRAY);
} else {
    holder.linearLayout.setBackgroundColor(0); // Transparent.
}
  

注意:只要您使用setBackgroundColor(0)方法在视图上设置背景,setBackground(null)的效果优于setBackgroundColor

如果您使用RecyclerView.Adapter.notifyItemMoved,这还不够。该方法不会导致在任何项目上调用onBindViewHolder

正确的方式

正确的方法源于这样一个事实:在您的情况下,项目视图的背景颜色不会以任何方式反映数据项。项目视图是否具有灰色背景取决于订购,而不是每个单独的项目。

这是ItemDecoration的用途。例如:

public class EvenOddItemDecoration extends RecyclerView.ItemDecoration {
    @ColorInt private final int mOddColor;
    @ColorInt private final int mEvenColor;

    // Do not allocate objects in onDraw method! Prepare what we need here.
    private final Rect mTempRect = new Rect();
    private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    public EvenOddItemDecoration(@ColorInt final int oddColor, @ColorInt final int evenColor) {
        mOddColor = oddColor;
        mEvenColor = evenColor;
    }

    @Override
    public void onDraw(final Canvas c, final RecyclerView parent, final RecyclerView.State state) {
        for (int i = 0, size = parent.getChildCount(); i < size; i++) {
            final View child = parent.getChildAt(i);
            // Get index of the item this view represents.
            final int adapterPosition = parent.getChildAdapterPosition(child);
            // Pick appropriate background color.
            if (adapterPosition % 2 == 0) {
                // Index 0, 2, 4... / First, third, fifth... items / Odd items
                mPaint.setColor(mOddColor);
            } else {
                // Index 1, 3, 5... / Second, fourth, sixth... items / Even items
                mPaint.setColor(mEvenColor);
            }
            // Get position of child view in the RecyclerView.
            parent.getDecoratedBoundsWithMargins(child, mTempRect);
            // Offset if it's dragging or animating.
            mTempRect.offset((int)child.getTranslationX(), (int)child.getTranslationY());
            // Draw the background!
            c.drawRect(mTempRect, mPaint);
        }
    }
}

将它连接起来:

list.addItemDecoration(new EvenOddItemDecoration(0, Color.GRAY);

您可以根据需要使用和更改代码。