实现首页图片浏览手势控制与listview上拉加载item点击事件响应
首先是布局文件:
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<!--footerDividersEnabled设成flase时,此ListView将不会在页脚视图前画分隔符。此属性缺省值为true -->
<com.example.hdu.MyListView
android:id="@+id/lv_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:headerDividersEnabled="false"
android:footerDividersEnabled="false" >
</com.example.hdu.MyListView>
</LinearLayout>
item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textSize="25sp" />
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textSize="15sp" />
</LinearLayout>
moredata.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btn_load"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="上滑或点击加载更多数据" />
<ProgressBar
android:id="@+id/pgb_load"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:visibility="gone" />
</LinearLayout>
viewflipper
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="205dp" >
<com.example.hdu.MyViewFlipper
android:id="@+id/viewflipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<com.example.hdu.MarkView
android:id="@+id/markView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/viewflipper"
android:layout_centerHorizontal="true"
android:layout_marginBottom="20dp" />
</RelativeLayout>
在res文件下创建anim文件夹,实现viewflipper动画模式,anim文件下有如下四个xml文件
push_left_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="500"
android:fromXDelta="100%p"
android:toXDelta="0" />
<alpha
android:duration="500"
android:fromAlpha="0.1"
android:toAlpha="1.0" />
</set>
push_left_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="500"
android:fromXDelta="0"
android:toXDelta="-100%p" />
<alpha
android:duration="500"
android:fromAlpha="1.0"
android:toAlpha="0.1" />
</set>
push_right_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="500"
android:fromXDelta="-100%p"
android:toXDelta="0" />
<alpha
android:duration="500"
android:fromAlpha="0.1"
android:toAlpha="1.0" />
</set>
push_right_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="500"
android:fromXDelta="0"
android:toXDelta="100%p" />
<alpha
android:duration="500"
android:fromAlpha="1.0"
android:toAlpha="0.1" />
</set>
Java代码:
MainActivity.java
package com.example.hdu;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.ProgressBar;
import android.widget.Toast;
import android.widget.ViewFlipper;
import com.example.hdu.MyViewFlipper.OnDisplayChangedListener;
public class MainActivity extends Activity implements OnScrollListener,
OnGestureListener {
// 设置全局变量,监控自动播放时候图片浏览顺序
private boolean Flag = true;
private GestureDetector detector;
private Adapter mSimpleAdapter;
private MyListView lv_main;
private Button btn;
private ProgressBar pgb;
private ArrayList<HashMap<String, String>> list;
private MarkView markView;
private MyViewFlipper viewFlipper;
// ListView顶部View即ViewFlipper
private View headView;
// ListView底部View
private View moreView;
private Handler handler;
private int MaxDateNum;
private int lastVisibleIndex;
// 图片动画
private Animation rInAnim;
private Animation rOutAnim;
private Animation lInAnim;
private Animation lOutAnim;
/**
* 获取viewflipper图片资源
*/
private ArrayList<Integer> getImageDate() {
ArrayList<Integer> imgs = new ArrayList<Integer>();
imgs.add(R.drawable.img1);
imgs.add(R.drawable.img2);
imgs.add(R.drawable.img3);
imgs.add(R.drawable.img4);
imgs.add(R.drawable.img5);
return imgs;
}
/**
* 设置listview的适配器
*/
private void setListViewAdapter() {
// 用map来装载数据,初始化5条数据
list = new ArrayList<HashMap<String, String>>();
for (int i = 0; i < 5; i++) {
HashMap<String, String> map = new HashMap<String, String>();
map.put("ItemTitle", "第" + i + "行标题");
map.put("ItemText", "第" + i + "行");
list.add(map);
}
// 实例化SimpleAdapter
mSimpleAdapter = new Adapter(MainActivity.this, list);
}
/**
* 图片滑动
*/
// viewflipper的孩子
private List<View> views;
/**
* 初始化小点点
*/
void initPoint() {
// 设置标记个数
markView.setMarkCount(views.size());
// // 起始位置设置为0
// markView.setMark(0);
}
/**
* 初始化ViewFlipper
*/
void initViewFlipper() {
views = new ArrayList<View>();
ArrayList<Integer> imgs = getImageDate();
// 图片加载进viewFlipper
for (int i = 0; i < imgs.size(); i++) {
ImageView imageView = new ImageView(this);
imageView.setImageResource(imgs.get(i));
imageView.setScaleType(ScaleType.FIT_XY);
viewFlipper.addView(imageView, new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
views.add(imageView);
}
// 初始化小点点
initPoint();
}
/**
* 初始化headview
*/
void initHeadView() {
/*
* 实例化顶部布局 inflate(resource, root,
* attachToRoot)有root,attachToRoot为false则返回需要添加的布局
* attachToRoot为true则返回添加布局到根布局后的整个新布局
*/
headView = getLayoutInflater().inflate(R.layout.viewflipper, lv_main,
false);
// 顶部布局headview里的控件
viewFlipper = (MyViewFlipper) headView.findViewById(R.id.viewflipper);
markView = (MarkView) headView.findViewById(R.id.markView);
// headview里的viewFlipper初始化
initViewFlipper();
// 初始播放模式
viewFlipper.setInAnimation(lInAnim);
viewFlipper.setOutAnimation(lOutAnim);
// 设置自动播放功能(点击事件前自动播放)
viewFlipper.setAutoStart(true);
viewFlipper.setFlipInterval(3000);
if (viewFlipper.isAutoStart() && !viewFlipper.isFlipping()) {
viewFlipper.startFlipping();
}
// 默认首次进入
markView.setMark(0);
// viewFlipper设置监听事件
viewFlipper.setOnDisplayChangedListener(new OnDisplayChangedListener() {
@Override
public void OnDisplayChildChanging(ViewFlipper view, int index) {
// 小点点跟随图片切换
markView.setMark(index);
}
});
lv_main.addHeaderView(headView, null, false);
}
/**
* 初始化moreview
*/
void initMoreView() {
// 实例化底部布局
moreView = getLayoutInflater().inflate(R.layout.moredata, lv_main,
false);
// 底部布局moreview里的控件
btn = (Button) moreView.findViewById(R.id.btn_load);
pgb = (ProgressBar) moreView.findViewById(R.id.pgb_load);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
pgb.setVisibility(View.VISIBLE);// 将进度条可见
btn.setVisibility(View.GONE);// 按钮不可见
handler.postDelayed(new Runnable() {
@Override
public void run() {
loadMoreDate();// 加载更多数据
btn.setVisibility(View.VISIBLE);
pgb.setVisibility(View.GONE);
mSimpleAdapter.notifyDataSetChanged();
}
}, 500);
}
});
lv_main.addFooterView(moreView);
}
/**
* listview添加headView并初始化
*/
void initListView() {
lv_main = (MyListView) findViewById(R.id.lv_main);
// 射入手势
lv_main.setGestureDetector(detector);
// 设置点击事件
lv_main.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if (position != 0) {
Toast.makeText(MainActivity.this,
"第" + (position - 1) + "条", 0).show();
} else {
int index = getPageIndex(viewFlipper.getCurrentView());
}
}
});
// 设置长点击事件
lv_main.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
if (position != 0) {
Toast.makeText(MainActivity.this,
"onItemLongClick" + "文字" + (position - 1), 0)
.show();
} else {
int index = getPageIndex(viewFlipper.getCurrentView());
}
/**
* 如果返回true,则表示该事件已被消耗,则手松开不会在执行onClick事件。
* 如果返回false则光标还在,手松开会执行onClick事件。
*/
return true;
}
});
// 设置添加长按菜单
lv_main.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
}
});
// 初始化headview
initHeadView();
// 射入viewflipper
lv_main.setViewFlipper(viewFlipper);
// 初始化moreview
initMoreView();
// 设置分隔符(画在列表中每个项目之间)的高度
lv_main.setDividerHeight(2);
}
/**
* 定义viewflipper动画切换模式
*/
void initAnimation() {
// 从左向右滑动(左进右出)
rInAnim = AnimationUtils.loadAnimation(this, R.anim.push_right_in);
rOutAnim = AnimationUtils.loadAnimation(this, R.anim.push_right_out);
// 从右向左滑动(右进左出)
lInAnim = AnimationUtils.loadAnimation(this, R.anim.push_left_in);
lOutAnim = AnimationUtils.loadAnimation(this, R.anim.push_left_out);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
detector = new GestureDetector(this);
handler = new Handler();
// 定义viewflipper动画切换模式
initAnimation();
// 获取viewflipper图片资源
getImageDate();
// 初始化listView
initListView();
// 设置ListView的最大数据数目
MaxDateNum = 35;
// 设置listview适配器
setListViewAdapter();
// listView绑定适配器
lv_main.setAdapter(mSimpleAdapter);
// 绑定listview的滑动监听器
lv_main.setOnScrollListener(this);
}
/**
* 加载更多数据
*/
private void loadMoreDate() {
int count = mSimpleAdapter.getCount();
if (count + 5 < MaxDateNum) {
// 每次加载5条
for (int i = count; i < count + 5; i++) {
HashMap<String, String> map = new HashMap<String, String>();
map.put("ItemTitle", "新增第" + i + "行标题");
map.put("ItemText", "新增第" + i + "行内容");
list.add(map);
}
} else {
// 数据已经不足5条
for (int i = count; i < MaxDateNum; i++) {
HashMap<String, String> map = new HashMap<String, String>();
map.put("ItemTitle", "新增第" + i + "行标题");
map.put("ItemText", "新增第" + i + "行内容");
list.add(map);
}
}
}
/**
* 返回当前第几屏
*/
private int getPageIndex(View view) {
for (int i = 0; i < views.size(); i++) {
if (view == views.get(i))
return i;
}
return 0;
}
@Override
/**
* listview点击事件
*/
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
@Override
// 用户轻触触摸屏
public boolean onDown(MotionEvent e) {
return false;
}
@Override
/**
* 执行图片单击,用户(轻触触摸屏后)松开
*/
public boolean onSingleTapUp(MotionEvent e) {
int index = getPageIndex(viewFlipper.getCurrentView());
Toast.makeText(MainActivity.this, "图" + index + "单击", 0).show();
// 单击切换下一个
viewFlipper.showNext();
return false;
}
@Override
// 用户按下触摸屏,并拖动
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
return false;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return super.dispatchTouchEvent(ev);
}
@Override
/**
* 执行图片长按,用户长按触摸屏
*/
public void onLongPress(MotionEvent e) {
int index = getPageIndex(viewFlipper.getCurrentView());
Toast.makeText(MainActivity.this, "图" + index + "长按", 0).show();
viewFlipper.stopFlipping();
viewFlipper.setAutoStart(false);
}
@Override
// 用户轻触触摸屏,尚未松开或拖动
public void onShowPress(MotionEvent e) {
}
/**
* 监听viewflipper滑动过程
*/
@Override
// 用户按下触摸屏、快速移动后松开
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
try {
if (e2.getX() - e1.getX() > 120) {
/*
* 右滑手势,然后通过下面两行代码改变之后的自动播放方向,仅仅是方向而已, 并不改变图片浏览的顺序
*/
viewFlipper.setInAnimation(rInAnim);
viewFlipper.setOutAnimation(rOutAnim);
viewFlipper.setFlag(false);
viewFlipper.showPrevious();
} else if (e2.getX() - e1.getX() < -120) {
// 左滑
viewFlipper.setInAnimation(lInAnim);
viewFlipper.setOutAnimation(lOutAnim);
viewFlipper.setFlag(true);
viewFlipper.showNext();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
/**
* 监听listview滑动状态
*/
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == 1) {
// listView还在滑动
}
// 滑到底部后自动加载,判断listview已经停止滚动并且最后可视的条目等于adapter的条目
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE
&& lastVisibleIndex == (mSimpleAdapter.getCount() - 1)) {
// 当滑到底部时自动加载
pgb.setVisibility(View.VISIBLE);
btn.setVisibility(View.GONE);
handler.postDelayed(new Runnable() {
@Override
public void run() {
loadMoreDate();
btn.setVisibility(View.VISIBLE);
pgb.setVisibility(View.GONE);
mSimpleAdapter.notifyDataSetChanged();
}
}, 500);
}
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
if (lastVisibleIndex == MaxDateNum) {
Toast.makeText(this, "数据全部加载完成", Toast.LENGTH_SHORT).show();
}
} else {
}
}
/**
* listview滑动过程
*/
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// 计算最后可见条目的索引
lastVisibleIndex = firstVisibleItem + visibleItemCount - 3;
// 所有的条目已经和最大条数相等,则移除底部的View
if (totalItemCount == MaxDateNum + 2) {
lv_main.removeFooterView(moreView);
MaxDateNum -= 1;
}
}
}
MarkView.java
package com.example.hdu;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;
import android.widget.LinearLayout;
public class MarkView extends LinearLayout {
private ImageView[] mImageView;
private Context context;
public MarkView(Context context) {
super(context);
this.context = context;
}
public MarkView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
public void setMarkCount(int iCount) {
mImageView = new ImageView[iCount];
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
p.setMargins(10, 0, 10, 0);
for (int i = 0; i < iCount; i++) {
ImageView image = new ImageView(context);
image.setImageResource(R.drawable.unselected_dot);
image.setLayoutParams(p);
mImageView[i] = image;
image.setId(i);
addView(image);
}
}
public void setMark(int position) {
for(int i = 0; i < mImageView.length; i++) {
if(i == position) {
mImageView[i].setImageResource(R.drawable.select_dot);
}else {
mImageView[i].setImageResource(R.drawable.unselected_dot);
}
}
}
}
MyListView.java
package com.example.hdu;
import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.ListView;
import android.widget.ViewFlipper;
public class MyListView extends ListView {
private GestureDetector gestureDetector;
private ViewFlipper viewFlipper;
private Context mContext;
public void setGestureDetector(GestureDetector gestureDetector) {
this.gestureDetector = gestureDetector;
}
public void setViewFlipper(ViewFlipper viewFlipper) {
this.viewFlipper = viewFlipper;
}
public MyListView(Context context) {
super(context);
this.mContext = context;
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
viewFlipper.setFlipInterval(3000);
viewFlipper.setAutoStart(true);
// 此处ev代表listview传进来的手势动作的方法,只有按下,移动,松开是那种状态
int x = (int) ev.getX();
int y = (int) ev.getY();
// ev里面包含触屏时的位置转换为listview的下标
int position = pointToPosition(x, y);
// 只有headview == 0才进行手势操作
if (position == 0) {
if (ev.getAction() == MotionEvent.ACTION_UP) {
if (viewFlipper.isAutoStart() && !viewFlipper.isFlipping()) {
viewFlipper.startFlipping();
}
} else {
viewFlipper.stopFlipping();
viewFlipper.setAutoStart(false);
}
// 通过listview点击到headview时注入手势,监控headview里面的手势操作
// 可以返回你之前手指滑动方向,返回到onFling()方法
gestureDetector.onTouchEvent(ev);
}
//解决当手按住图片拖动到headview以外区域无法执行抬手自动播放操作
if(ev.getAction() == MotionEvent.ACTION_UP) {
if (viewFlipper.isAutoStart() && !viewFlipper.isFlipping()) {
viewFlipper.startFlipping();
}
}
return super.onTouchEvent(ev);
}
}
MyViewFlipper.java
package com.example.hdu;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ViewFlipper;
public class MyViewFlipper extends ViewFlipper {
private Context mContext;
private boolean mFlag = true;
private OnDisplayChangedListener mListener;
public MyViewFlipper(Context context) {
super(context);
mContext = context;
}
public MyViewFlipper(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
public void setFlag(boolean flag) {
this.mFlag = flag;
}
public void setOnDisplayChangedListener(OnDisplayChangedListener listener) {
if (mListener != listener) {
this.mListener = listener;
}
}
@Override
public void showNext() {
/*
* 因为自动播放时默认调用该方法,所以使用标志mFlag,当滑动趋势为左滑时,使图片播放顺序颠倒,
* 这时mFlag变为false,这样自动播放模式就为往前播放。
*/
if (mFlag == true) {
super.showNext();
}else{
showPrevious();
}
if (mListener != null) {
mListener.OnDisplayChildChanging(this, super.getDisplayedChild());
}
}
@Override
public void showPrevious() {
super.showPrevious();
mListener.OnDisplayChildChanging(this, super.getDisplayedChild());
}
//OnDisplayChangedListener的接口
public interface OnDisplayChangedListener {
void OnDisplayChildChanging(ViewFlipper view, int index);
}
}
Adapter.java
package com.example.hdu;
import java.util.ArrayList;
import java.util.HashMap;
import com.example.hdu.R.layout;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class Adapter extends BaseAdapter {
Context mContext;
ArrayList<HashMap<String, String>> mData;
public Adapter(Context context, ArrayList<HashMap<String, String>> data) {
mContext = context;
mData = data;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mData.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.item,
null);
holder = new ViewHolder();
holder.tvTitle = (TextView) convertView.findViewById(R.id.tv_title);
holder.tvContent = (TextView) convertView
.findViewById(R.id.tv_content);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
String content = mData.get(position).get("ItemText");
String title = mData.get(position).get("ItemTitle");
holder.tvContent.setText(content);
holder.tvTitle.setText(title);
return convertView;
}
class ViewHolder {
TextView tvTitle;
TextView tvContent;
}
}
代码比较多,有需要的可以先弄到Eclipse里面然后再仔细看看各种方法的实现,
重要地方都有相应的注释,相信你会看的懂得。