真正的画廊,左右条目可点击居中, 左右条目可滑动
来源:互联网 发布:seo超级外链工具 编辑:程序博客网 时间:2024/06/05 09:19
利用Viewpager实现真正的Gallery, 左右条目可点击居中, 左右条目可滑动,也就是可以获得焦点
前言: 最近公司做一个想Gallery一样的效果,于是想在网上找个现成的,但是怎么找也没找到,就是找到一个鸿洋大神的巧用ViewPager 打造不一样的广告轮播切换效果的,但是左右条目不可点击,又不可以滑动,所以就做了个这个控件,本控件也是利用ViewPgaer做出来的
首先看一下效果:
从图上可以看出, 两边的item可以被点击居中, 可以被滑动,也就是可以获得焦点
接下来讲一下原理
设置PageTransformer
PageTransformer大家估计都相当熟悉吧,下面是PageTransformer的代码
public void transformPage(View page, float position) { if (position < -1) { position = -1; } else if (position > 1) { position = 1; } float tempScale = position < 0 ? 1 + position : 1 - position; float slope = (MAX_SCALE - MIN_SCALE) / 1; float scaleValue = MIN_SCALE + tempScale * slope; page.setScaleX(scaleValue); page.setScaleY(scaleValue); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { page.getParent().requestLayout(); }}
这个的作用就是让Viewpager展示多个条目,看下面的图片, 红色的才是ViewPager的大小,所以此PageTransformer是为了在Viewpager外面展示图片
大家都知道PageTransformer没有真正的改变viewpager的状态,但是为什么本demo中两侧的图片可以点击还可以滑动呢,让我慢慢跟你道来
其实很简单,就是在viewpage的父控件中拦截dispatchTouchEvent的方法来控制ViewPgaer的滑动和相应点击事件的(不懂dispatchTouchEvent即事件分发的, 问问度娘就可以了)
先看一下自定义ViewPager
public class GalleryViewPager extends ViewPager {//默认距离private final static float DISTANCE = 10;private float downX;private float downY;public GalleryViewPager(Context context) { super(context);}public GalleryViewPager(Context context, AttributeSet attrs) { super(context, attrs);}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) { if(ev.getAction() == MotionEvent.ACTION_DOWN){ downX = ev.getX(); downY = ev.getY(); }else if (ev.getAction() == MotionEvent.ACTION_UP) { float upX = ev.getX(); float upY = ev.getY(); if(Math.abs(upX - downX) > DISTANCE || Math.abs(upY - downY) > DISTANCE){ return super.dispatchTouchEvent(ev); } View view = viewOfClickOnScreen(ev); if (view != null) { int index = (Integer) view.getTag(); if (getCurrentItem() != index) { setCurrentItem(index); } } } return super.dispatchTouchEvent(ev);}private View viewOfClickOnScreen(MotionEvent ev) { int childCount = getChildCount(); int currentIndex = getCurrentItem(); int[] location = new int[2]; for (int i = 0; i < childCount; i++) { View v = getChildAt(i); int position = (Integer) v.getTag(); v.getLocationOnScreen(location); int minX = location[0]; int minY = location[1]; int maxX = location[0] + v.getWidth(); int maxY = location[1] + v.getHeight(); if(position < currentIndex){ maxX -= v.getWidth() * (1 - ScalePageTransformer.MIN_SCALE) * 0.5 + v.getWidth() * (Math.abs(1 - ScalePageTransformer.MAX_SCALE)) * 0.5; minX -= v.getWidth() * (1 - ScalePageTransformer.MIN_SCALE) * 0.5 + v.getWidth() * (Math.abs(1 - ScalePageTransformer.MAX_SCALE)) * 0.5; }else if(position == currentIndex){ minX += v.getWidth() * (Math.abs(1 - ScalePageTransformer.MAX_SCALE)); }else if(position > currentIndex){ maxX -= v.getWidth() * (Math.abs(1 - ScalePageTransformer.MAX_SCALE)) * 0.5; minX -= v.getWidth() * (Math.abs(1 - ScalePageTransformer.MAX_SCALE)) * 0.5; } float x = ev.getRawX(); float y = ev.getRawY(); if ((x > minX && x < maxX) && (y > minY && y < maxY)) { return v; } } return null;}}
等会让VIewPgaer的父控件的dispatchTouchEvent实现此ViewPager的dispatchTouchEvent就可以了 比如在mainactivity中找到父控件, 根据父控件的dispatchTouchEvent来控制此ViewPgaer的变化
findViewById(R.id.root).setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return mViewPager.dispatchTouchEvent(event); } });
控制两边图片的点击事件只响应居中图片, 不响应点击事件
在viewpageradapter中设置如下代码, 中间的图片永远是mViewPager.getCurrentItem(),只有中间的图片可以响应点击事件
imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.i("wwwwwwwwss", mViewPager.getCurrentItem()+ "------" + position); if ((mViewPager.getCurrentItem() ) == position) { Toast.makeText(mContext, "点击的位置是:::"+position, Toast.LENGTH_SHORT).show(); } } });
使用方式
添加依赖
1.在根目录的build.gradle中添加
allprojects {repositories { jcenter() maven { url 'https://jitpack.io' }// 添加jitpack.依赖}
2.在app的build.gradle中添加
compile 'com.github.niezhiyang:NGallery:v1.0.1'
在使用的xml中,用一个父控件包裹住GalleryViewPager,目的是为了控制父控件的滑动,和点击,来设置Viewpager的状态
<RelativeLayout android:id="@+id/root" android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false" > <!--是否限制子View在其范围内,我们将其值设置为false后那么当子控件的高度高于父控件时也会完全显示,而不会被压缩--> <com.nie.ngallerylibrary.GalleryViewPager android:id="@+id/viewpager" android:layout_width="200dp" android:layout_height="200dp" android:layout_centerInParent="true" android:clipChildren="false" android:overScrollMode="never"/></RelativeLayout>
代码中设置
mViewPager = (GalleryViewPager) findViewById(R.id.viewpager);//找到这个控件 mViewPager.setPageTransformer(true, new ScalePageTransformer());//设置PageTransformer,本库只有一个ScalePageTransformer,如果这个ScalePageTransformer满足不了您的需求,您可以自己写一个PageTransformer findViewById(R.id.root).setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return mViewPager.dispatchTouchEvent(event); } });//找到这个父控件设置他的listener mPagerAdapter = new SimpleAdapter(this);//初始化adapter mViewPager.setAdapter(mPagerAdapter);//设置adapter
adapter要继承MyPageradapter;例如
public class SimpleAdapter extends MyPageradapter { private final List<Integer> mList; private final Context mContext; public SimpleAdapter(Context context) { mList = new ArrayList<>(); mContext = context; } public void addAll(List<Integer> list) { mList.addAll(list); notifyDataSetChanged(); } @Override public View getView(final int position, View convertView, ViewGroup container) { ImageView imageView = null; if (convertView == null) { imageView = new ImageView(mContext); } else { imageView = (ImageView) convertView; } imageView.setTag(position); imageView.setImageResource(mList.get(position)); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if ((mViewPager.getCurrentItem() ) == position) { Toast.makeText(mContext, "点击的位置是:::"+position, Toast.LENGTH_SHORT).show(); } } }); return imageView; } @Override public int getCount() { return mList.size(); }}
这只不过是简单的添加imageview,你也可以添加fragment做出绚丽的效果,还可以跟任意的viewpgaerindicator使用了,是不是想想就高兴了
具体实现请看源码:NGallery
apk位置:demo.apk
欢迎start
阅读全文
0 0
- 真正的画廊,左右条目可点击居中, 左右条目可滑动
- 真正的画廊,左右条目可点击居中, 左右条目可滑动
- android自定义控件--条目可以左右滑动的listview
- Android自定义折线图,可左右滑动,可点击
- Android图片查看器,点击可放大缩小,左右滑动
- listview条目点击可展开(初级)
- 左右滑动删除ListView条目Item(SwipeToDismiss)
- Android SwipeToDismiss:左右滑动删除ListView条目Item
- 左右滑动删除ListView条目Item--第三方开源--SwipeToDismiss
- 另一种可左右滑动的横向GridView的实现
- 利用ViewPager实现可左右滑动的Action Tab
- FragmentTabHost + pageView 实现可左右滑动的底部菜单 ...
- android 自定义view实现可左右滑动的Tabbar
- 利用ViewPager实现可左右滑动的Action Tab
- 利用ViewPager实现可左右滑动的Action Tab
- ViewPager 可左右滑动和缩放的图片浏览
- 可左右上下滑动切换图片的界面
- Android 实现item可左右滑动移除的GridView
- 无法通过公网访问阿里云服务器Tomcat下部署的项目
- 在ubuntu 安装软件的经验
- 1153: 简易版最长序列
- Android 动画Activity转场动画入门
- 初学JVAV 笔记 7月13号 JDK环境配置 介绍JAVA Java如何运行的
- 真正的画廊,左右条目可点击居中, 左右条目可滑动
- 域名解析中的cname解析和显性URL跳转和隐性URL跳转三者有什么区别
- button drawableLeft 加上动画效果
- Convert excel to xml
- exception in initAndListen: 29 Data directory /data/db not found., terminating
- 【MyBatis学习01】宏观上把握MyBatis框架
- 背景,尺寸及显示的相关属性
- 添加一个桥设备——br_add_bridge(二)
- 【二叉树】后序遍历【Add to List 145. Binary Tree Postorder Traversal】