仿旅游App梦想旅行的一个Listview的自定义控件

新手>.<,大牛请多指点

效果:

                     

就是每个item中的背景图片会跟随ListView的滑动而滑动,接下来看一下具体的代码实现过程



先是自定义的Adapter

import com.example.dreamtravel2.R;

public class MyAdapter extends BaseAdapter {
	int[] imageres;
	Context context;
	private Resources resources;

	//手指滑动的方向
	public boolean isUP = true;

	public MyAdapter(int[] imageres, Context context) {
		super();
		this.imageres = imageres;
		this.context = context;
		resources = context.getResources();
	}

	@Override
	public int getCount() {
		return imageres.length;
	}

	@Override
	public Object getItem(int position) {
		return null;
	}

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

	@SuppressLint("NewApi") @Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder;
		if (convertView == null) {
			holder = new ViewHolder();
			convertView = LayoutInflater.from(context).inflate(R.layout.listitem, parent, false);
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}

		holder.imageView = (ImageView) convertView.findViewById(R.id.iv);
		holder.textView = (TextView) convertView.findViewById(R.id.tv);

		holder.imageView.setImageDrawable(resources.getDrawable(imageres[position]));
		holder.textView.setText("城市--" + position);
		
		//应为用了ViewHolder会记录imageView的ScrollY值
		//所以再次getView时先设置ScrollY值为0
		holder.imageView.setScrollY(0);

		// 判断是什么方向划出图片 提前滑动预定地点
		//350是我设定的图片向上或向下最大的滑动距离
		if (isUP)
			holder.imageView.scrollBy(0, -350);
		else
			holder.imageView.scrollBy(0, 350);
		return convertView;
	}

	public static class ViewHolder {
		ImageView imageView;
		TextView textView;

	}

}

很简单,对大家来说应该没什么难度,重要的代码上都加了注释说明

isUP是记录手指滑动的方向,在Listview的滑动监听中回去实时的去给他设定具体的值

350...是我自己设定的,大家用的时候最好根据图片的大小,和item的高度去设定

应为用ViewHolder,所以在加载一个新的item时去吧imageView的ScrollY值归0

item的布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="240dp"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/iv"
        android:layout_width="wrap_content"
        android:layout_height="240dp"
        android:layout_centerHorizontal="true"
        android:scaleType="center" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="test"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="city"
        android:textColor="#f00"
        android:textSize="50sp" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal" >

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:text="test"
            android:textColor="#f00"
            android:textSize="20sp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:text="test"
            android:textColor="#f00"
            android:textSize="20sp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:text="test"
            android:textColor="#f00"
            android:textSize="20sp" />
    </LinearLayout>

</RelativeLayout>

很简单,item的高度可以自己去调节哈~

ListView的代码

public class MyListView extends ListView implements AbsListView.OnScrollListener {

	// 记录上一次滑动的距离
	int proY = 0;

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

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

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

	private void init() {
		this.setOnScrollListener(this);
	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {

	}

	@Override
	public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

		int scrollY = myGetScrollY();

		if (scrollY - proY > 0) {
			//手指向上滑
			for (int i = 0; i < visibleItemCount; i++) {
				View child = this.getChildAt(i);
				ImageView imageView = (ImageView) child.findViewById(R.id.iv);
				//350是我设定的图片向上或向下最大的滑动距离
				if (imageView.getScrollY() + (scrollY - proY) < 350) {
					//(scrollY - proY) / 2使滑动的速度不会太快。。
					imageView.scrollBy(0, (scrollY - proY) / 2);
				}
				MyAdapter adapter = (MyAdapter) getAdapter();
				adapter.isUP = true;
			}
		} else {
			for (int i = 0; i < visibleItemCount; i++) {
				View child = this.getChildAt(i);
				ImageView imageView = (ImageView) child.findViewById(R.id.iv);
				if (imageView.getScrollY() + (scrollY - proY) > -350) {
					imageView.scrollBy(0, (scrollY - proY) / 2);
				}
				MyAdapter adapter = (MyAdapter) getAdapter();
				adapter.isUP = false;
			}
		}
		proY = scrollY;

	}

	/*
	 * 就相当于 listView 对第一个item 的绝对的滑动距离 在 滑动过程中一直 比较两次的 差值 就可以得到每次极小距离的滑动值 在
	 * OnScrollListener中 去监视 ,就可以在不同的滑动状态(手指滑动 , 飞行滑动)去滑动你想要滑动的东西
	 * 也可以去检测Listview的滑动方向(通过判断两次差值的正负)
	 */
	public int myGetScrollY() {
		View c = getChildAt(0);
		if (c == null) {
			return 0;
		}
		int firstVisiblePosition = getFirstVisiblePosition();
		int top = c.getTop();
		return -top + firstVisiblePosition * c.getHeight();
	}

}


第一次把图片的滑动的逻辑写到了onTrackballEvent,导致了手指离开了屏幕,ListView处于SCROLL_STATE_FLING状态时,item中的图片不会跟着滑动。。

所以就写到了listview的滑动监听里了。。


获取listview滑动的值:

myGetScrollY()
是获取listview相对于listview顶部的绝对的滑动距离,随着手指向上滑,返回值是从0开始增大的正数。

但是这个距离会慢慢的增大,我们要的是极短时间内的滑动距离,所以要记录滑动前后的值相减就得到我们想要的值

其他的就没什么难的了


还可以改进,adapter的图片可以联网获取

这个控件用来展示景点,汽车,之类的还不错

在item中可以加好多东西如:好评,收藏,分享。。。

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

在这里面的for循环不会很长,我觉得listview列表长点应该没关系。。但是滑的快了或许会卡。。


第一篇博客。。请大家多多指点>.<


代码地址:http://download.csdn.net/detail/youxi52710/9323411


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值