listview+viewflipper+markview+OnGestureListener

实现首页图片浏览手势控制与listview上拉加载item点击事件响应

首先是布局文件:

activity_main.xml


    


    
    


item.xml




    


    


 
  

moredata.xml




    


 
  

viewflipper





    


    


 
  

在res文件下创建anim文件夹,实现viewflipper动画模式,anim文件下有如下四个xml文件

push_left_in.xml



    

    
push_left_out.xml


    

    
push_right_in.xml


    

    
push_right_out.xml


    

    
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> 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 getImageDate() {
		ArrayList imgs = new ArrayList();
		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>();
		for (int i = 0; i < 5; i++) {
			HashMap map = new HashMap();
			map.put("ItemTitle", "第" + i + "行标题");
			map.put("ItemText", "第" + i + "行");
			list.add(map);
		}

		// 实例化SimpleAdapter
		mSimpleAdapter = new Adapter(MainActivity.this, list);
	}

	/**
	 * 图片滑动
	 */
	// viewflipper的孩子
	private List views;

	/**
	 * 初始化小点点
	 */
	void initPoint() {
		// 设置标记个数
		markView.setMarkCount(views.size());
		// // 起始位置设置为0
		// markView.setMark(0);
	}

	/**
	 * 初始化ViewFlipper
	 */
	void initViewFlipper() {
		views = new ArrayList();
		ArrayList 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 map = new HashMap();
				map.put("ItemTitle", "新增第" + i + "行标题");
				map.put("ItemText", "新增第" + i + "行内容");
				list.add(map);
			}
		} else {
			// 数据已经不足5条
			for (int i = count; i < MaxDateNum; i++) {
				HashMap map = new HashMap();
				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> mData;

	public Adapter(Context context, ArrayList> 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里面然后再仔细看看各种方法的实现,
重要地方都有相应的注释,相信你会看的懂得。


你可能感兴趣的:(Android)