Android 设置Listview的背景和ListView一起滚动

package com.siyehuazhilian.shopanimation;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.widget.ListView;

public class MyListView extends ListView {

	public MyListView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(context);
	}

	public MyListView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	public MyListView(Context context) {
		super(context);
		init(context);
	}

	private void init(Context context) {
		this.context = context;
		background = optimizeBitmap();
	}

	private Bitmap background;
	private Context context;

	@Override
	protected void dispatchDraw(Canvas canvas) {
		int scrolly = -getChildAt(0).getTop() + getFirstVisiblePosition()
				* getChildAt(0).getHeight();
		canvas.drawBitmap(background, 0, -scrolly, null);
		super.dispatchDraw(canvas);
	}

	/**
	 * 读取图片
	 */
	private Bitmap optimizeBitmap() {
		DisplayMetrics display = new DisplayMetrics();
		((Activity) context).getWindowManager().getDefaultDisplay()
				.getMetrics(display);
		int width = display.widthPixels;
		int height = display.heightPixels;

		Bitmap result = null;
		// 图片配置对象,该对象可以配置图片加载的像素获取个数
		BitmapFactory.Options options = new BitmapFactory.Options();
		// 表示加载图像的原始宽高
		options.inJustDecodeBounds = true;
		result = BitmapFactory.decodeResource(getResources(), R.drawable.test,
				options);
		// Math.ceil表示获取与它最近的整数(向上取值 如:4.1->5 4.9->5)
		int widthRatio = (int) Math.ceil(options.outWidth / width);
		int heightRatio = (int) Math.ceil(options.outHeight / height);

		// 设置最终加载的像素比例,表示最终显示的像素个数为总个数的
		if (widthRatio > 1 || heightRatio > 1) {
			options.inSampleSize = widthRatio;
			Log.e("@@@@@@", width + "");
			Log.e("@@@@@@", options.outWidth + "");
			Log.e("@@@@@@", widthRatio + "");
		}
		// 解码像素的模式,在该模式下可以直接按照option的配置取出像素点
		options.inJustDecodeBounds = false;
		result = BitmapFactory.decodeResource(getResources(), R.drawable.test,
				options);
		return result;
	}
}



通过计算图片的宽度和高度,平铺一张图片到listview的背景,这样有个缺点,比如listview是200高,你的背景也是200高,而一屏幕只能显示80的情况下,那么这个歌图片下部分是看不到的,每次滚动到快要完成的时候,图片又从顶部开始绘制
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);
    }
 }


>还有一种情况,不需要这么麻烦,因为canvas.drawBitmap绘制图片的第3个参数
void android.graphics.Canvas.drawBitmap(Bitmap bitmap, float left, float top, Paint paint)
de>
指的是,图片距离顶端有多少,所以只需要计算当前显示的第几个乘以每一个view的高度,然后,加上第一个view的实际所在位置,取负值就行
int scrolly = -c.getTop() + getFirstVisiblePosition() * c.getHeight();
			System.out.println(scrolly);
			canvas.drawBitmap(background, 0, -scrolly , null);
这里有个关键的地方
1  那个top参数,是绘制的view距离显示区域的高度,所以为负值的时候,就是上边截掉了一部分
2  看下图,假如每个child的高度都是96,一般情况下每个高度在listview都是相同的,当前显示的索引  getFirstVisiblePosition  得到的是1 ,则第一个view  getTop得到的就是50的那段距离,然后-50  再加上每个view的高度,就是listview滑动的距离,这样再对这个距离取负值,用户drawBitmap  然后看到的就是listview滑动了相应的距离,这里  getFirstVisiblePosition  有个好处就是每次取到的其实就是当前露出来的最顶段的那个view的位置,乘以96刚好得到的就是上面看不见的那几个child view  
android 随着背景一起滑动的listview - 破木吉他 - 破木吉他

其实看懂这几句话,修改listview很容易的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值