自定义控件之轮播图RollViewPager

import java.util.List;

import android.content.Context;
import android.os.Handler;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.lidroid.xutils.BitmapUtils;
import com.study.smartservice.R;
import com.study.smartservice.adapter.MyPagerAdapter;

public class RollViewPager extends ViewPager {

	private static final String tag = "RollViewPager";
	private MyAdapter myAdapter;
	private Context context;

	private List<String> imgUrlList;
	private List<String> titleList;
	private List<String> imgUrlSkipList;
	private TextView top_news_title;
	private BitmapUtils bitmapUtils;

	// 维护当前ViewPager指向的索引
	private int currentPager = 0;

	private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			// ViewPager指向索引界面
			RollViewPager.this.setCurrentItem(currentPager);
			startRoll();
		};
	};
	private OnViewClickListener viewClickListener;

	/**
	 * 缓存机制:三级缓存:(1.内存(Map<url,Bitmap>,LRU算法) 2.文件(url) 3.网络)
	 */
	public RollViewPager(Context context, final List<View> dotList,
			OnViewClickListener viewClickListener) {
		super(context);
		this.context = context;
		// this.dotList = dotList;
		bitmapUtils = new BitmapUtils(context);

		// 接口
		this.viewClickListener = viewClickListener;

		this.setOnPageChangeListener(new OnPageChangeListener() {

			@Override
			public void onPageSelected(int position) {
				// 选中某一页后要去修改文字
				top_news_title.setText(titleList.get(position));
				// 切换点
				for (int i = 0; i < dotList.size(); i++) {
					if (position == i) {
						// 选中页面的点
						View view = dotList.get(position);
						view.setBackgroundResource(R.drawable.dot_focus);
					} else {
						View view = dotList.get(i);
						view.setBackgroundResource(R.drawable.dot_normal);
					}
				}
			}

			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {

			}

			@Override
			public void onPageScrollStateChanged(int arg0) {

			}
		});
	}

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

	// 顶部轮播图文字集合对应数据,显示控件传递进来
	public void initTitle(List<String> titleList, TextView top_news_title) {
		if (titleList != null && top_news_title != null && titleList.size() > 0) {
			top_news_title.setText(titleList.get(0));
		}
		this.titleList = titleList;
		this.top_news_title = top_news_title;
	}

	public void initImgUrl(List<String> imgUrlList) {
		this.imgUrlList = imgUrlList;
	}

	public void initImgSkipUrl(List<String> imgUrlSkipList) {
		this.imgUrlSkipList = imgUrlSkipList;
	}

	// 数据填充数据适配器的操作
	public void startRoll() {
		if (myAdapter == null) {
			myAdapter = new MyAdapter(context, imgUrlList);
			this.setAdapter(myAdapter);
		} else {
			myAdapter.notifyDataSetChanged();
		}

		// 滚起来
		handler.postDelayed(new Runnable() {

			@Override
			public void run() {
				// 维护一个ViewPager指向的索引
				currentPager = (currentPager + 1) % imgUrlList.size();
				// 发送一个空消息
				handler.obtainMessage().sendToTarget();
				// Log.i(tag, "scroll_run");
			}
		}, 2000);
	}

	int downX;
	int downY;

	// 事件分发
	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			// 点击下去的时候,具体是刷新还是加载未知
			// 当前ViewPager对应的父控件不能去拦截事件
			getParent().requestDisallowInterceptTouchEvent(true);

			downX = (int) ev.getX();
			downY = (int) ev.getY();
			break;
		case MotionEvent.ACTION_MOVE:
			int moveX = (int) ev.getX();
			int moveY = (int) ev.getY();

			if (Math.abs(moveX - downX) > Math.abs(moveY - downY)) {
				// 如果x轴上的偏移量大于y轴偏移量(翻页,滑动ViewPager)

				int diff = moveX - downX;
				// System.out.println("moveX:"+moveX);
				// System.out.println("downX:"+downX);
				// System.out.println("diff:"+diff);
				if (diff > 0 && getCurrentItem() == 0) {
					// 向右滑动。出现左侧界面
					// 此时出现SlidingMenu 需要父控件响应事件
					Log.i(tag, "右滑+父响应");
					getParent().requestDisallowInterceptTouchEvent(false);
				} else if (diff > 0
						&& getCurrentItem() < getAdapter().getCount() - 1) {
					// 移动内部的ViewPager滑动轮播图
					Log.i(tag, "右滑+父不响应");
					getParent().requestDisallowInterceptTouchEvent(true);
				} else if (diff < 0
						&& getCurrentItem() == getAdapter().getCount() - 1) {
					Log.i(tag,
							"左滑+父响应");
					// 向左滑动
					// 父控件拦截事件,滑动到下一个模块
					getParent().requestDisallowInterceptTouchEvent(false);
				} else if (diff < 0
						&& getCurrentItem() < getAdapter().getCount() - 1) {
					Log.i(tag,
							"左滑+父不响应");
					getParent().requestDisallowInterceptTouchEvent(true);
				}

			} else {
				// 如果y轴上的偏移量大于x轴偏移量(刷新)
				getParent().requestDisallowInterceptTouchEvent(false);
			}
			break;
		}
		return super.dispatchTouchEvent(ev);
	}

	public interface OnViewClickListener {
		public void onViewClick(String url);
	}

	class MyAdapter extends MyPagerAdapter<String> {

		public MyAdapter(Context context, List<String> list) {
			super(context, list);
		}

		@Override
		public Object instantiateItem(ViewGroup container, final int position) {
			View view = View.inflate(context, R.layout.viewpager_item, null);
			ImageView imageView = (ImageView) view.findViewById(R.id.image);

			// 网络获取图片
			bitmapUtils.display(imageView, imgUrlList.get(position));
			Log.i(tag, imgUrlList.get(position));
			// viewPager和内部view的时间交互过程
			// viewPager继承自viewGroup,所以事件默认向内部传递。
			// action_down先传递给内部的view,如果手指不动,抬起事件依然在view上;
			// action_down先传递给内部的view,如果手指滑动,事件优先传递给viewGroup,然后再传递给view,响应。
			// 如果移动到一定距离的时候,view就不再响应,转而响应Action_CANCEL,所有的事件在view上不响应。
			// 此时所有的事件(move,up)在viewGroup上响应,

			view.setOnTouchListener(new OnTouchListener() {
				private int downX;
				private long downTime;
				private int upX;

				@Override
				public boolean onTouch(View v, MotionEvent event) {
					switch (event.getAction()) {
					case MotionEvent.ACTION_DOWN:
						handler.removeCallbacksAndMessages(null);

						// 点击事件
						downX = (int) event.getX();
						downTime = System.currentTimeMillis();
						break;
					case MotionEvent.ACTION_UP:
						upX = (int) event.getX();
						if (downX == upX
								&& System.currentTimeMillis() - downTime < 500) {
							// 响应点击事件,回调(先定义一个接口,暴露一个方法,谁用谁实现,实现完了在必要的地方调用)
							viewClickListener.onViewClick(imgUrlSkipList
									.get(position));
						}
						startRoll();
						break;
					case MotionEvent.ACTION_CANCEL:
						startRoll();
						break;
					}
					return true;
				}
			});
			container.addView(view);
			return view;
		}

		@Override
		public void destroyItem(ViewGroup container, int position, Object object) {
			container.removeView((View) object);
		}
	}

	// 如果当前界面不可见调用
	@Override
	protected void onDetachedFromWindow() {
		// handler不去发送消息
		handler.removeCallbacksAndMessages(null);
		super.onDetachedFromWindow();
	}

}

以下为布局:使用LinearLayout代替了ViewPager。

<?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="185dp" >

    <!-- 放置轮播图片位置 -->

    <LinearLayout
        android:id="@+id/top_news_viewpager"
        android:layout_width="fill_parent"
        android:layout_height="185dp"
        android:orientation="horizontal" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="30dp"
        android:layout_alignParentBottom="true"
        android:background="#88000000"
        android:gravity="center_vertical"
        android:orientation="horizontal" >

        <!-- 放置图片标题的位置 -->

        <TextView
            android:id="@+id/top_news_title"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="8dp"
            android:layout_weight="1"
            android:singleLine="true"
            android:text="图片标题"
            android:textColor="#F6F6F6" />
        <!-- 放置图片中选中点的位置 -->

        <LinearLayout
            android:id="@+id/dots_ll"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="5dp"
            android:gravity="center"
            android:orientation="horizontal" />
    </LinearLayout>

</RelativeLayout>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值