您的位置:首页 > 移动开发

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

2015-12-03 14:45 411 查看

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

效果:



                     


就是每个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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息