如何使ListView背景随项目滚动

4
我将一张图片设置为ListView的背景,在滚动ListView时,如何让它随着列表项一起滚动呢?
例如:当我向下滚动ListView时,图片1会从原来的位置改变。
        1          
-----1-----1--------
   1         1
-1-------------1----

to

--------1----------
      1    1
---1----------1----
 1              1

也许我可以扩展ListView并覆盖dispatchDraw方法,但如果我使用ListFragment,我该怎么办呢? 有人能帮帮我吗?
2个回答

6

在您的Activity的XML文件中,像这样定义listview:

(根据您的要求在此xml文件中定义属性)

<com.example.MyCustomListView
    android:id="@+id/listview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"/>

创建一个名为MyCustomListView的类:
    public class MyCustomListView extends ListView
    {

       private Bitmap background;

    public MyCustomListView(Context context, AttributeSet attrs) 
    {
        super(context, attrs);
        background = BitmapFactory.decodeResource(getResources(), R.drawable.yourImageName);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) 
    {
        int count = getChildCount();
        int top = count > 0 ? getChildAt(0).getTop() : 0;
        int backgroundWidth = background.getWidth();
        int backgroundHeight = background.getHeight();
        int width = getWidth();
        int height = getHeight();

        for (int y = top; y < height; y += backgroundHeight)
        {
            for (int x = 0; x < width; x += backgroundWidth)
            {
                canvas.drawBitmap(background, x, y, null);
            }
        }
        super.dispatchDraw(canvas);
    }
 }

希望这可以解决你的问题 :)

谢谢,它可以工作。但是如果把ListView改为ListFragment,我该怎么办? - GeminiYellow
@GeminiYellow 如果我的回答对您有帮助,请按照 SO 规则为我的回答点赞,如果您有任何其他问题,请提出单独的问题并展示您已经尝试过的内容。 - AndroidLearner
哦,对不起,我应该现在给你的答案打上标记。 你的答案只是我的问题的一部分。 它有效了,但还没有完成。ListFragment 无法应用此解决方案, 现在我向 ListView 添加了一个 OnLayoutChangeListener, 并且每次更改布局。这会降低性能。 - GeminiYellow
这个解决方案是可行的,但有一个 bug:如果 ListView 设置了 paddingTop,则第一个列表项上方和最后一个列表项下方的区域不会滚动。以下是修复方法:将此行代码替换为 int top = count > 0 ? getChildAt(0).getTop() - getPaddingTop() : 0; - anon

0
AndroidLearner 的代码运行良好,除了一个错误,在 AndroidLearner 答案的评论中有提到。我编写了 Kotlin 版本的代码来修复该错误,并且还可与在 XML 中定义的任何背景一起使用,例如:
<ListViewWithScrollingBackground
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/some_background"/>

这里是代码:

import android.content.Context
import android.graphics.Canvas
import android.util.AttributeSet
import android.widget.ListView


class ListViewWithScrollingBackground(context: Context, attrs: AttributeSet)
: ListView(context, attrs) {

  private val background by lazy { getBackground().toBitmap() }

  override fun dispatchDraw(canvas: Canvas) {
    var y = if (childCount > 0) getChildAt(0).top.toFloat() - paddingTop else 0f
    while (y < height) {
      var x = 0f
      while (x < width) {
        canvas.drawBitmap(background, x, y, null)
        x += background.width
      }
      y += background.height
    }
    super.dispatchDraw(canvas)
  }

  private fun Drawable.toBitmap(): Bitmap = 
    if (this is BitmapDrawable && bitmap != null) bitmap else {
    val hasIntrinsicSize = intrinsicWidth <= 0 || intrinsicHeight <= 0
    val bitmap = Bitmap.createBitmap(if (hasIntrinsicSize) intrinsicWidth else 1,
      if (hasIntrinsicSize) intrinsicHeight else 1, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(bitmap)
    setBounds(0, 0, canvas.width, canvas.height)
    draw(canvas)
    bitmap
  }

}

为了将Drawable转换为Bitmap,我使用了this的帖子。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接