简单炫酷的轮播图
来源:互联网 发布:淘宝起名字 编辑:程序博客网 时间:2024/05/29 04:29
现在的App都必须是炫酷才能吸引用户,特别是手上的项目是电商系列,实现了一个简单炫酷的轮播控件。保证小白加炫酷,理解基本的逻辑大家也可以随意的实现自己想要的效果,那么直接进入正题吧!
首先分析一下轮播图的基本布局
很简单,就是一个RelativeLayout包含了一个ViewPager和一个指示器布局,为了方便作为库依赖,布局都以代码生成的,代码如下
/** * Created by licrynoob on 2016/5/12. * Copyright (C) 2016 Email:licrynoob@gmail.com * <p/> * 轮播图 */public class PlayViewLayout extends LinearLayout { private Context mContext; /** * 轮播布局 */ private RelativeLayout mRelativeLayout; /** * ViewPager */ private ViewPager mViewPager; /** * 导航布局 */ private LinearLayout mNavigationLinearLayout; /** * 数量 */ private int count; /** * 当前选项 */ private int mPosition; /** * ViewPager Adapter */ private PagerAdapter mAdapter; /** * ViewList */ private List<View> mViewList = new ArrayList<>(); /** * 播放的方向 <br> * 0 向右 <br> * 1 向左 */ private int playDirection = 0; /** * 播放的开关 */ private boolean isPlay = false; /** * 播放时间间隔 单位 秒 * 默认5秒 */ private int playTime = 5; /** * 导航图片 */ private Drawable displayDrawable; private Drawable hideDrawable; /** * ViewPager改变监听 */ private MyOnPageChangeListener mMyOnPageChangeListener; /** * View点击监听 */ private MyOnItemClickListener mMyOnItemClickListener; /** * View触摸监听 */ private MyOnTouchListener mMyOnTouchListener; /** * 轮播的handler * 先0++ 再count-- * */ private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 0) { int count = mViewList.size(); int i = mViewPager.getCurrentItem(); if (playDirection == 0) { if (i == count - 1) { playDirection = -1; i--; } else { i++; } } else { if (i == 0) { playDirection = 0; i++; } else { i--; } } mViewPager.setCurrentItem(i, true); if (isPlay) { handler.postDelayed(runnable, playTime * 1000); } } } }; /** * 轮播的线程 */ private Runnable runnable = new Runnable() { public void run() { if (mViewPager != null) { handler.sendEmptyMessage(0); } } }; public PlayViewLayout(Context context) { super(context); initView(context); } public PlayViewLayout(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } public PlayViewLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context); } private void initView(Context context) { mContext = context; mRelativeLayout = new RelativeLayout(context); //子View进行绘制时不要去裁切它们的显示范围 mRelativeLayout.setClipChildren(false); addViewPager(); addNavigationLayout(); this.setOrientation(LinearLayout.VERTICAL); this.addView(mRelativeLayout, new LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); mAdapter = new PagerAdapter() { @Override public int getCount() { return mViewList.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { View view = mViewList.get(position); container.addView(view); return view; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } @Override public int getItemPosition(Object object) { return POSITION_NONE; } }; mViewPager.setAdapter(mAdapter); //设置边框渐变的长度 mViewPager.setFadingEdgeLength(0); mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { if (mMyOnPageChangeListener != null) { mMyOnPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels); } } @Override public void onPageSelected(int position) { mPosition = position; setCurrentNavigationStyle(); if (mMyOnPageChangeListener != null) { mMyOnPageChangeListener.onPageSelected(position); } } @Override public void onPageScrollStateChanged(int state) { } }); setNavPageResources(R.drawable.play_display, R.drawable.play_hide); } /** * 添加ViewPager */ private void addViewPager() { mViewPager = new ViewPager(mContext); //子View进行绘制时不要去裁切它们的显示范围 mViewPager.setClipChildren(false); //设置Page间距 mViewPager.setPageMargin(20); //设置缓存的页面数量为3张 mViewPager.setOffscreenPageLimit(3); //设置旋转动画 mViewPager.setPageTransformer(true, new RotateYTransformer(45)); RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); //设置左右边距为60dp 就是为了显示出左右部分的Page params.setMargins(dp2Px(60), 0, dp2Px(60), 0); params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE); params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE); mViewPager.setLayoutParams(params); mRelativeLayout.addView(mViewPager); } /** * 添加指示器布局 */ private void addNavigationLayout() { mNavigationLinearLayout = new LinearLayout(mContext); mNavigationLinearLayout.setOrientation(LinearLayout.HORIZONTAL); mNavigationLinearLayout.setPadding(0, 0, 0, 5); RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); //指示器的布局 params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE); params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE); mNavigationLinearLayout.setLayoutParams(params); mRelativeLayout.addView(mNavigationLinearLayout); } /** * 设置导航点图标并创建导航点 * * @param displayResId 选择状态图 * @param hideResId 未选择状态图 */ private void setNavPageResources(int displayResId, int hideResId) { this.displayDrawable = this.getResources().getDrawable(displayResId); this.hideDrawable = this.getResources().getDrawable(hideResId); createIndex(); } /** * 创建导航的点 */ private void createIndex() { //先移除所有的点 mNavigationLinearLayout.removeAllViews(); mNavigationLinearLayout.setGravity(Gravity.CENTER); count = mViewList.size(); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); //点距父布局各边距 params.setMargins(5, 5, 5, 5); //自身宽高 params.width = 15; params.height = 15; for (int i = 0; i < count; i++) { ImageView imageView = new ImageView(mContext); imageView.setLayoutParams(params); if (i == 0) { imageView.setImageDrawable(displayDrawable); } else { imageView.setImageDrawable(hideDrawable); } mNavigationLinearLayout.addView(imageView, i); } } /** * 页面被选中时设置导航图片 */ public void setCurrentNavigationStyle() { for (int i = 0; i < count; i++) { if (mPosition == i) { ((ImageView) mNavigationLinearLayout.getChildAt(mPosition)).setImageDrawable(displayDrawable); } else { ((ImageView) mNavigationLinearLayout.getChildAt(i)).setImageDrawable(hideDrawable); } } } /** * dp转px * * @param dpValue * @return */ private int dp2Px(float dpValue) { final float scale = mContext.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } /** * 添加播放的View * * @param playView */ public void addPlayView(View playView) { mViewList.add(playView); //将playView的点击事件交给MyOnItemClickListener playView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (mMyOnItemClickListener != null) { mMyOnItemClickListener.onClick(mPosition); } } }); //将playView的触摸事件交给MyOnTouchListener playView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (mMyOnTouchListener != null) { mMyOnTouchListener.onTouch(event); } return false; } }); //刷新Adapter mAdapter.notifyDataSetChanged(); createIndex(); } public void addPlayViewList(List<View> viewList) { mViewList.addAll(viewList); for (View view : viewList) { //将playViewList的点击事件交给MyOnItemClickListener view.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (mMyOnItemClickListener != null) { mMyOnItemClickListener.onClick(mPosition); } } }); //将playViewList的触摸事件交给MyOnTouchListener view.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { if (mMyOnTouchListener != null) { mMyOnTouchListener.onTouch(event); } return false; } }); } //刷新Adapter mAdapter.notifyDataSetChanged(); createIndex(); } @Override public void removeAllViews() { mViewList.clear(); //刷新Adapter mAdapter.notifyDataSetChanged(); createIndex(); } /** * 开始播放 */ public void startPlay() { if (handler != null) { isPlay = true; handler.postDelayed(runnable, playTime * 1000); } } /** * 停止播放 */ public void stopPlay() { if (handler != null) { isPlay = false; handler.removeCallbacks(runnable); } } /** * 设置播放间隔 * * @param time */ public void setPlayTime(int time) { playTime = time; } /** * 获取ViewPager * * @return */ public ViewPager getViewPager() { return mViewPager; } /** * 获取当前View数量 * * @return */ public int getCount() { return count; } /** * 设置MyOnPageChangeListener * * @param myOnPageChangeListener */ public void setMyOnPageChangeListener(MyOnPageChangeListener myOnPageChangeListener) { mMyOnPageChangeListener = myOnPageChangeListener; } /** * 设置MyOnItemClickListener * * @param myOnItemClickListener */ public void setMyOnItemClickListener(MyOnItemClickListener myOnItemClickListener) { mMyOnItemClickListener = myOnItemClickListener; } /** * 设置MyOnTouchListener * * @param myOnTouchListener */ public void setMyOnTouchListener(MyOnTouchListener myOnTouchListener) { mMyOnTouchListener = myOnTouchListener; } /** * 自定义页面点击接口 */ public interface MyOnItemClickListener { void onClick(int position); } /** * 触摸接口 */ public interface MyOnTouchListener { /** * Touch事件 * * @param event 触摸手势 */ void onTouch(MotionEvent event); } /** * ViewPager ChangeListener */ public interface MyOnPageChangeListener { /** * Page滑动时 * * @param position * @param positionOffset * @param positionOffsetPixels */ void onPageScrolled(int position, float positionOffset, int positionOffsetPixels); /** * Page被选择时 * * @param position */ void onPageSelected(int position); }}代码的注释都写的很详细,其中几个细节说一下
1 ViewPager的getItemPosition重写需要注意,否则不能刷新
2 mViewPager.setPageTransformer(true, new RotateYTransformer(45)),此处为ViewPager的动画效果,具体的内容参照hongyang大神的博客,里面还有好几种炫酷的效果,地址:http://blog.csdn.net/lmj623565791/article/details/51339751
3 为了方便管理事件监听,把ViewPager的子View事件交给了PlayViewLayout,包括MyOnItemClickListener,MyOnTouchListener,MyOnPageChangeListener
下面为具体的使用方法
Activity布局为
<?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="match_parent" android:padding="8dp"> <com.lzy.demo.PlayViewLayout android:id="@+id/play_view" android:layout_width="match_parent" android:layout_height="160dp"/> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_centerVertical="true" android:text="添加View"/> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_below="@+id/button1" android:text="添加ViewList"/> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_below="@+id/button2" android:text="清空ViewList"/> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_below="@+id/button3" android:text="开始播放"/> <Button android:id="@+id/button5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_below="@+id/button4" android:text="停止播放"/></RelativeLayout>直接导入控件,还有几个按钮
ViewPager子View布局
<?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="wrap_content"> <ImageView android:id="@+id/mPlayImage" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY"/> <TextView android:id="@+id/mPlayText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_margin="16dp" android:text="我是标题" android:textColor="#ffffff" android:textSize="13sp"/></RelativeLayout>
Activity中使用
/** * Created by licrynoob on 2016/5/12. * Copyright (C) 2016 Email:licrynoob@gmail.com */public class MainActivity extends AppCompatActivity { private PlayViewLayout mPlayViewLayout; private Button bt1, bt2, bt3, bt4, bt5; private LayoutInflater mInflater; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mInflater = LayoutInflater.from(this); bt1 = (Button) findViewById(R.id.button1); bt2 = (Button) findViewById(R.id.button2); bt3 = (Button) findViewById(R.id.button3); bt4 = (Button) findViewById(R.id.button4); bt5 = (Button) findViewById(R.id.button5); mPlayViewLayout = (PlayViewLayout) findViewById(R.id.play_view); final View mPlayView0 = mInflater.inflate(R.layout.item_play_view, null); ImageView mPlayImage = (ImageView) mPlayView0.findViewById(R.id.mPlayImage); TextView mPlayText = (TextView) mPlayView0.findViewById(R.id.mPlayText); mPlayText.setText("开始标题0"); mPlayImage.setBackgroundResource(R.drawable.pic1); final View mPlayView1 = mInflater.inflate(R.layout.item_play_view, null); ImageView mPlayImage1 = (ImageView) mPlayView1.findViewById(R.id.mPlayImage); TextView mPlayText1 = (TextView) mPlayView1.findViewById(R.id.mPlayText); mPlayText1.setText("开始标题1"); mPlayImage1.setBackgroundResource(R.drawable.pic2); final View mPlayView2 = mInflater.inflate(R.layout.item_play_view, null); ImageView mPlayImage2 = (ImageView) mPlayView2.findViewById(R.id.mPlayImage); TextView mPlayText2 = (TextView) mPlayView2.findViewById(R.id.mPlayText); mPlayText2.setText("开始标题2"); mPlayImage2.setBackgroundResource(R.drawable.pic3); mPlayViewLayout.addPlayView(mPlayView0); mPlayViewLayout.addPlayView(mPlayView1); mPlayViewLayout.addPlayView(mPlayView2); //设置播放间隔 mPlayViewLayout.setPlayTime(4); //添加View bt1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { View mPlayView = mInflater.inflate(R.layout.item_play_view, null); ImageView mPlayImage = (ImageView) mPlayView.findViewById(R.id.mPlayImage); TextView mPlayText = (TextView) mPlayView.findViewById(R.id.mPlayText); mPlayText.setText("添加第" + mPlayViewLayout.getCount() + "个"); mPlayImage.setBackgroundResource(R.drawable.pic3); mPlayViewLayout.addPlayView(mPlayView); } }); //添加ViewList bt2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mPlayViewLayout.removeAllViews(); mPlayViewLayout.addPlayView(mPlayView0); mPlayViewLayout.addPlayView(mPlayView1); mPlayViewLayout.addPlayView(mPlayView2); } }); //清除全部 bt3.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mPlayViewLayout.removeAllViews(); } }); //开始播放 bt4.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mPlayViewLayout.startPlay(); } }); //停止播放 bt5.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mPlayViewLayout.stopPlay(); } }); mPlayViewLayout.setMyOnPageChangeListener(new PlayViewLayout.MyOnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { //Toast.makeText(MainActivity.this, "当前页面偏移量为" + positionOffset, Toast.LENGTH_SHORT).show(); } @Override public void onPageSelected(int position) { Toast.makeText(MainActivity.this, "当前页面为:" + position, Toast.LENGTH_SHORT).show(); } }); mPlayViewLayout.setMyOnItemClickListener(new PlayViewLayout.MyOnItemClickListener() { @Override public void onClick(int position) { Toast.makeText(MainActivity.this, "你点击了" + position, Toast.LENGTH_SHORT).show(); } }); } @Override public void finish() { mPlayViewLayout.stopPlay(); super.finish(); }}可以添加,删除View,设置时间和各个监听,还是很方便的,最后记得finish()时停止,防止可能引起界面切换卡顿。
到此一个简单炫酷的轮播图就结束拉,还没研究上传动态图。。。,不足的地方欢迎大家指出
下载地址:
2 0
- 简单炫酷的轮播图
- 简单、易用、酷炫的图表插件
- 简单实现不一样的炫酷Toast
- 炫酷简单的loading效果
- 简单酷炫的网页登录界面
- 炫酷简单的loading效果
- javascript简单的轮播图
- 简单的轮播图代码
- 轮播图的简单实现
- 简单轮播图的实现
- 简单的轮播图
- 简单的左右轮播图
- 简单的左右轮播图
- 简单的轮播图
- 简单的轮播图
- 简单的轮播图切换
- 巨简单的轮播图
- 简单的,简单的
- Github资源整理
- k8s 部署
- c++之继承1
- 作业——在线学习Android课程之第十二周(内存优化)
- jQuery uploadify 在chrome上崩溃的解决办法
- 简单炫酷的轮播图
- 编码规范 目录管理
- 自增id算法snowflake
- c++实验6-数组合并
- Android开发:ListView、AdapterView、RecyclerView全面解析
- 自定义Listview适配器的优化
- 我没有解决的迷之错误
- 数据结构栈的操作
- 同一个服务器上的不同项目要注意session的死锁问题