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

来源:互联网 发布:域名具有 属性 编辑:程序博客网 时间:2024/04/27 19:12

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

效果:

                     

就是每个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();}@Overridepublic int getCount() {return imageres.length;}@Overridepublic Object getItem(int position) {return null;}@Overridepublic long getItemId(int position) {return position;}@SuppressLint("NewApi") @Overridepublic 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值为0holder.imageView.setScrollY(0);// 判断是什么方向划出图片 提前滑动预定地点//350是我设定的图片向上或向下最大的滑动距离if (isUP)holder.imageView.scrollBy(0, -350);elseholder.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);}@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {}@Overridepublic 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 0