首页 文章 精选 留言 我的

精选列表

搜索[设备详情页],共10001篇文章
优秀的个人博客,低调大师

ecshop 详情页面获取商品销量和评论数

添加页面:根目录下面的goods.php 找到 /* 记录浏览历史 */ if (!empty($_COOKIE['ECS']['history'])) ...... 添加代码如下: /*新添加的程序 获取销量和评论数*/ function get_buy_sum($goods_id) { // $sql = 'SELECT IFNULL(SUM(g.goods_number), 0) ' . // 'FROM ' . $GLOBALS['ecs']->table('order_info') . ' AS o, ' . // $GLOBALS['ecs']->table('order_goods') . ' AS g ' . // "WHERE o.order_id = g.order_id " . // "AND o.order_status = '" . OS_CONFIRMED . "' " . // "AND o.shipping_status " . db_create_in(array(SS_SHIPPED, SS_RECEIVED)) . // " AND o.pay_status " . db_create_in(array(PS_PAYED, PS_PAYING)) . // " AND g.goods_id = '$goods_id'"; $sql = 'SELECT IFNULL(SUM(g.goods_number), 0) ' . 'FROM ' . $GLOBALS['ecs']->table('order_info') . ' AS o, ' . $GLOBALS['ecs']->table('order_goods') . ' AS g ' . "WHERE o.order_id = g.order_id " . " AND o.order_status " . db_create_in(array(OS_CONFIRMED, OS_SPLITED, OS_SPLITING_PART)) . " AND g.goods_id = '$goods_id'"; return $GLOBALS['db']->getOne($sql); } function get_comment_num($goods_id) { $sql= "select count(*) from ".$GLOBALS['ecs']->table('comment')." where id_value='".$goods_id."' AND status = 1"; return $GLOBALS['db']->getOne($sql); } $smarty->assign('buy_num',get_buy_sum($goods_id)); $smarty->assign('comment_num',get_comment_num($goods_id)); 本文转自 gutaotao1989 51CTO博客,原文链接:http://blog.51cto.com/taoyouth/1406188

优秀的个人博客,低调大师

Android仿微信图片详情页面,可下拉关闭页面

话不多说,直接上效果图 imagereview.gif ImageReview 在这个库里面用到了第三方的缩放图片查看库 1、要实现效果图的方案,需要操作重写ViewPager的事件处理。 2、下滑透明的方案可以使用设置背景来实现 下拉缩放的效果需要重写onInterceptTouchEvent和onTouchEvent, 在onInterceptTouchEvent中不拦截down事件,并且在move事件中判断是否满足下滑缩放的条件; 在onTouchEvent中实现具体的缩放以及透明度变化的效果; 同时在ViewPager的滑动要与下滑缩放区分开,因此需要监听OnPageChangeListener,并在onTouchEvent判断是否ViewPager在滑动中 public class DragViewPager extends ViewPager implements View.OnClickListener { public static final int STATUS_NORMAL = 0;//正常浏览状态 public static final int STATUS_MOVING = 1;//滑动状态 public static final int STATUS_RESETTING = 2;//返回中状态 public static final String TAG = "DragViewPager"; public static final float MIN_SCALE_SIZE = 0.3f;//最小缩放比例 public static final int BACK_DURATION = 300;//ms public static final int DRAG_GAP_PX = 50; private int currentStatus = STATUS_NORMAL; private int currentPageStatus; private float mDownX; private float mDownY; private float screenHeight; /** * 要缩放的View */ private View currentShowView; /** * 滑动速度检测类 */ private VelocityTracker mVelocityTracker; private IAnimClose iAnimClose; public void setIAnimClose(IAnimClose iAnimClose) { this.iAnimClose = iAnimClose; } public DragViewPager(Context context) { super(context); init(context); } public DragViewPager(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public void init(Context context) { screenHeight = ScreenUtils.getScreenHeight(context); setBackgroundColor(Color.BLACK); addOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { } @Override public void onPageScrollStateChanged(int state) { currentPageStatus = state; } }); } public void setCurrentShowView(View currentShowView) { this.currentShowView = currentShowView; if (this.currentShowView != null) { this.currentShowView.setOnClickListener(this); } } //配合SubsamplingScaleImageView使用,根据需要拦截ACTION_MOVE @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (getAdapter() instanceof ImagePagerAdapter) { ImagePagerAdapter adapter = ((ImagePagerAdapter) getAdapter()); SubsamplingScaleImageView mImage = (SubsamplingScaleImageView) adapter.getItem(getCurrentItem()).getView().findViewById(R.id.image); switch (ev.getAction()){ case MotionEvent.ACTION_DOWN: Log.e("jc","onInterceptTouchEvent:ACTION_DOWN"); mDownX = ev.getRawX(); mDownY = ev.getRawY(); break; case MotionEvent.ACTION_MOVE: Log.e("jc","onInterceptTouchEvent:ACTION_MOVE"); if (mImage.getCenter() != null && mImage.getCenter().y <= mImage.getHeight() / mImage.getScale() / 2) { Log.e("jc","onInterceptTouchEvent:ACTION_MOVE"); int deltaX = Math.abs((int) (ev.getRawX() - mDownX)); int deltaY = (int) (ev.getRawY() - mDownY); if (deltaY > DRAG_GAP_PX && deltaX <= DRAG_GAP_PX) {//往下移动超过临界,左右移动不超过临界时,拦截滑动事件 return true; } } break; case MotionEvent.ACTION_UP: Log.e("jc","onInterceptTouchEvent:ACTION_UP"); break; } } return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent ev) { if (currentStatus == STATUS_RESETTING) return false; switch (ev.getActionMasked()) { case MotionEvent.ACTION_DOWN: mDownX = ev.getRawX(); mDownY = ev.getRawY(); addIntoVelocity(ev); break; case MotionEvent.ACTION_MOVE: addIntoVelocity(ev); int deltaY = (int) (ev.getRawY() - mDownY); //手指往上滑动 if (deltaY <= DRAG_GAP_PX && currentStatus != STATUS_MOVING) return super.onTouchEvent(ev); //viewpager不在切换中,并且手指往下滑动,开始缩放 if (currentPageStatus != SCROLL_STATE_DRAGGING && (deltaY > DRAG_GAP_PX || currentStatus == STATUS_MOVING)) { moveView(ev.getRawX(), ev.getRawY()); return true; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: if (currentStatus != STATUS_MOVING) return super.onTouchEvent(ev); final float mUpX = ev.getRawX(); final float mUpY = ev.getRawY(); float vY = computeYVelocity();//松开时必须释放VelocityTracker资源 if (vY >= 1200 || Math.abs(mUpY - mDownY) > screenHeight / 4) { //下滑速度快,或者下滑距离超过屏幕高度的一半,就关闭 if (iAnimClose != null) { iAnimClose.onPictureRelease(currentShowView); } } else { resetReviewState(mUpX, mUpY); } break; } return super.onTouchEvent(ev); } //返回浏览状态 private void resetReviewState(final float mUpX, final float mUpY) { currentStatus = STATUS_RESETTING; if (mUpY != mDownY) { ValueAnimator valueAnimator = ValueAnimator.ofFloat(mUpY, mDownY); valueAnimator.setDuration(BACK_DURATION); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float mY = (float) animation.getAnimatedValue(); float percent = (mY - mDownY) / (mUpY - mDownY); float mX = percent * (mUpX - mDownX) + mDownX; moveView(mX, mY); if (mY == mDownY) { mDownY = 0; mDownX = 0; currentStatus = STATUS_NORMAL; } } }); valueAnimator.start(); } else if (mUpX != mDownX) { ValueAnimator valueAnimator = ValueAnimator.ofFloat(mUpX, mDownX); valueAnimator.setDuration(BACK_DURATION); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float mX = (float) animation.getAnimatedValue(); float percent = (mX - mDownX) / (mUpX - mDownX); float mY = percent * (mUpY - mDownY) + mDownY; moveView(mX, mY); if (mX == mDownX) { mDownY = 0; mDownX = 0; currentStatus = STATUS_NORMAL; } } }); valueAnimator.start(); } else if (iAnimClose != null) iAnimClose.onPictureClick(); } //移动View private void moveView(float movingX, float movingY) { if (currentShowView == null) return; currentStatus = STATUS_MOVING; float deltaX = movingX - mDownX; float deltaY = movingY - mDownY; float scale = 1f; float alphaPercent = 1f; if (deltaY > 0) { scale = 1 - Math.abs(deltaY) / screenHeight; alphaPercent = 1 - Math.abs(deltaY) / (screenHeight / 2); } ViewHelper.setTranslationX(currentShowView, deltaX); ViewHelper.setTranslationY(currentShowView, deltaY); scaleView(scale); setBackgroundColor(getBlackAlpha(alphaPercent)); } //缩放View private void scaleView(float scale) { scale = Math.min(Math.max(scale, MIN_SCALE_SIZE), 1); ViewHelper.setScaleX(currentShowView, scale); ViewHelper.setScaleY(currentShowView, scale); } private int getBlackAlpha(float percent) { percent = Math.min(1, Math.max(0, percent)); int intAlpha = (int) (percent * 255); return Color.argb(intAlpha,0,0,0); } private void addIntoVelocity(MotionEvent event) { if (mVelocityTracker == null) mVelocityTracker = VelocityTracker.obtain(); mVelocityTracker.addMovement(event); } private float computeYVelocity() { float result = 0; if (mVelocityTracker != null) { mVelocityTracker.computeCurrentVelocity(1000); result = mVelocityTracker.getYVelocity(); releaseVelocity(); } return result; } private void releaseVelocity() { if (mVelocityTracker != null) { mVelocityTracker.clear(); mVelocityTracker.recycle(); mVelocityTracker = null; } } @Override public void onClick(View v) { if (iAnimClose != null) { iAnimClose.onPictureClick(); } } public interface IAnimClose { void onPictureClick(); void onPictureRelease(View view); } } 需要进行缩放的View我这里在Adapter中添加回调设置,并且adapter可以实现更新的效果 public class ImagePagerAdapter extends FragmentStatePagerAdapter { private DragViewPager mPager; private ArrayList<Fragment> mFragmentList; public ImagePagerAdapter(FragmentManager fm, List<String> datas,DragViewPager pager) { super(fm); mPager=pager; mPager.setAdapter(this); updateData(datas); } public void updateData(List<String> dataList) { ArrayList<Fragment> fragments = new ArrayList<>(); for (int i = 0, size = dataList.size(); i < size; i++) { final ImageDetailFragment fragment = ImageDetailFragment.newInstance(dataList.get(i)); fragment.setOnImageListener(new ImageDetailFragment.OnImageListener() { @Override public void onInit() { View view = fragment.getView(); mPager.setCurrentShowView(view); } }); fragments.add(fragment); } setViewList(fragments); } private void setViewList(ArrayList<Fragment> fragmentList) { if (mFragmentList != null) { mFragmentList.clear(); } mFragmentList = fragmentList; notifyDataSetChanged(); } @Override public int getCount() { return mFragmentList==null?0:mFragmentList.size(); } public int getItemPosition(Object object) { return POSITION_NONE; } @Override public Fragment getItem(int position) { return mFragmentList.get(position); } } 要实现透明度变化的效果还需要对activity设置theme <style name="translucent" parent="AppTheme"> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> <item name="android:windowIsTranslucent">true</item> <item name="android:windowBackground">@android:color/transparent</item> </style> <activity android:name=".ui.ImagePagerActivity" android:theme="@style/translucent"/> 在需要使用的页面只需要调用即可 ImagePagerActivity.startImagePage(MainActivity.this, urls,pos,recyclerView.getLayoutManager().findViewByPosition(pos)); 在整个demo中采用的转场动画,需要设置共享元素,因此在需要使用的页面需要设置如下: 首先设置转场动画的共享元素,因为跳转和返回时都会调用onMapSharedElements,需要判断bundle是否为空,bundle会在返回的时候在onActivityReenter获取到 //设置转场动画的共享元素,因为跳转和返回时都会调用onMapSharedElements,需要判断bundle是否为空 setExitSharedElementCallback(new SharedElementCallback() { @Override public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) { if (bundle!=null){ int index = bundle.getInt(ImagePagerActivity.STATE_POSITION,0); sharedElements.clear(); sharedElements.put("img", recyclerView.getLayoutManager().findViewByPosition(index)); bundle=null; } } }); 其次在返回的时候获取数据bundle @Override public void onActivityReenter(int resultCode, Intent data) { super.onActivityReenter(resultCode, data); bundle = data.getExtras(); int currentPosition = bundle.getInt(ImagePagerActivity.STATE_POSITION,0); //做相应的滚动 recyclerView.scrollToPosition(currentPosition); //暂时延迟 Transition 的使用,直到我们确定了共享元素的确切大小和位置才使用 //postponeEnterTransition后不要忘记调用startPostponedEnterTransition ActivityCompat.postponeEnterTransition(this); recyclerView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { recyclerView.getViewTreeObserver().removeOnPreDrawListener(this); // TODO: figure out why it is necessary to request layout here in order to get a smooth transition. recyclerView.requestLayout(); //共享元素准备好后调用startPostponedEnterTransition来恢复过渡效果 ActivityCompat.startPostponedEnterTransition(MainActivity.this); return true; } }); } 完整的调用页面的代码如下: public class MainActivity extends AppCompatActivity { private RecyclerView recyclerView; private MainAdapter mainAdapter; //图片集合 private ArrayList<String> urls; //存放返回时当前页码 private Bundle bundle; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); urls=new ArrayList<>(); //为了显示效果,重复添加了三次 urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524477979306&di=3eb07e9302606048abe13d7b6a2bc601&imgtype=0&src=http%3A%2F%2Fimg4.duitang.com%2Fuploads%2Fitem%2F201406%2F12%2F20140612211118_YYXAC.jpeg"); urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524133463580&di=1315bc4db30999f00b89ef79c3bb06e5&imgtype=0&src=http%3A%2F%2Fpic36.photophoto.cn%2F20150710%2F0005018721870517_b.jpg"); urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524133463575&di=6221f21bcb761675c5d161ebc53d5948&imgtype=0&src=http%3A%2F%2Fimg5.duitang.com%2Fuploads%2Fitem%2F201410%2F03%2F20141003112442_AkkuH.thumb.700_0.jpeg"); urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524477979306&di=3eb07e9302606048abe13d7b6a2bc601&imgtype=0&src=http%3A%2F%2Fimg4.duitang.com%2Fuploads%2Fitem%2F201406%2F12%2F20140612211118_YYXAC.jpeg"); urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524133463580&di=1315bc4db30999f00b89ef79c3bb06e5&imgtype=0&src=http%3A%2F%2Fpic36.photophoto.cn%2F20150710%2F0005018721870517_b.jpg"); urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524133463575&di=6221f21bcb761675c5d161ebc53d5948&imgtype=0&src=http%3A%2F%2Fimg5.duitang.com%2Fuploads%2Fitem%2F201410%2F03%2F20141003112442_AkkuH.thumb.700_0.jpeg"); urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524477979306&di=3eb07e9302606048abe13d7b6a2bc601&imgtype=0&src=http%3A%2F%2Fimg4.duitang.com%2Fuploads%2Fitem%2F201406%2F12%2F20140612211118_YYXAC.jpeg"); urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524133463580&di=1315bc4db30999f00b89ef79c3bb06e5&imgtype=0&src=http%3A%2F%2Fpic36.photophoto.cn%2F20150710%2F0005018721870517_b.jpg"); urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524133463575&di=6221f21bcb761675c5d161ebc53d5948&imgtype=0&src=http%3A%2F%2Fimg5.duitang.com%2Fuploads%2Fitem%2F201410%2F03%2F20141003112442_AkkuH.thumb.700_0.jpeg"); initView(); } private void initView() { recyclerView = (RecyclerView) findViewById(R.id.recycler); recyclerView.setLayoutManager(new GridLayoutManager(this, 2)); mainAdapter = new MainAdapter(urls); mainAdapter.setOnItemClickListener(new MainAdapter.OnItemClickListener() { @Override public void onItemClick(int pos) { ImagePagerActivity.startImagePage(MainActivity.this, urls,pos,recyclerView.getLayoutManager().findViewByPosition(pos)); } }); recyclerView.setAdapter(mainAdapter); //设置转场动画的共享元素,因为跳转和返回都会调用,需要判断bundle是否为空 setExitSharedElementCallback(new SharedElementCallback() { @Override public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) { if (bundle!=null){ int index = bundle.getInt(ImagePagerActivity.STATE_POSITION,0); sharedElements.clear(); sharedElements.put("img", recyclerView.getLayoutManager().findViewByPosition(index)); bundle=null; } } }); } //返回的时候获取数据 @Override public void onActivityReenter(int resultCode, Intent data) { super.onActivityReenter(resultCode, data); bundle = data.getExtras(); int currentPosition = bundle.getInt(ImagePagerActivity.STATE_POSITION,0); //做相应的滚动 recyclerView.scrollToPosition(currentPosition); //暂时延迟 Transition 的使用,直到我们确定了共享元素的确切大小和位置才使用 //postponeEnterTransition后不要忘记调用startPostponedEnterTransition ActivityCompat.postponeEnterTransition(this); recyclerView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { recyclerView.getViewTreeObserver().removeOnPreDrawListener(this); // TODO: figure out why it is necessary to request layout here in order to get a smooth transition. recyclerView.requestLayout(); //共享元素准备好后调用startPostponedEnterTransition来恢复过渡效果 ActivityCompat.startPostponedEnterTransition(MainActivity.this); return true; } }); } } 需要查看完整代码点击这里,喜欢的请给个star,谢谢 作者:JC_Hou 链接:https://www.jianshu.com/p/3c6384973db6 来源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

优秀的个人博客,低调大师

iOS 开发商品详情页中的banner中点击查看图片

本文出自code4app,原文地址:http://www.code4app.com/blog-928210-1694.html 轮翻播放与查看是分开的,轮翻是是用 开源的SDCycleScrollView 这里是给出的是查看的: //// FullScreenShowImageView.swift// joopic//// Created by jianxiong li on 16/9/27.// Copyright © 2016年 joobot. All rights reserved.//import Foundation import UIKit//图片轮播组件代理协议protocol FullScreenShowImageViewDelegate{ //获取数据源 func galleryDataSource()->[String] //获取内部scrollerView的宽高尺寸 func galleryScrollerViewSize()->CGSize func hiddenForCliked(index:Int) }//图片轮播组件控制器class FullScreenShowImageView: UIView,UIScrollViewDelegate{ //代理对象 var delegate : FullScreenShowImageViewDelegate! //屏幕宽度 let kScreenWidth = BWidth //当前展示的图片索引 var currentIndex : Int = 0 //数据源 var dataSource : [String]? //用于轮播的左中右三个image(不管几张图片都是这三个imageView交替使用) var leftImageView , middleImageView , rightImageView : UIImageView? //放置imageView的滚动视图 var scrollerView : UIScrollView? //scrollView的宽和高 var scrollerViewWidth : CGFloat? var scrollerViewHeight : CGFloat? //页控制器(小圆点) var pageControl : UIPageControl? //加载指示符(用来当iamgeView还没将图片显示出来时,显示的图片) var placeholderImage:UIImage! //自动滚动计时器 var autoScrollTimer:NSTimer? init(frame: CGRect,delegate:FullScreenShowImageViewDelegate) { super.init(frame: frame) self.delegate = delegate praperaUI() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } func praperaUI() { //获取并设置scrollerView尺寸 let size : CGSize = self.delegate.galleryScrollerViewSize() self.scrollerViewWidth = size.width self.scrollerViewHeight = size.height //获取数据 self.dataSource = self.delegate.galleryDataSource() //设置scrollerView self.configureScrollerView() //设置加载指示图片 self.configurePlaceholder() //设置imageView self.configureImageView() //设置页控制器 self.configurePageController() //设置自动滚动计时器 //self.configureAutoScrollTimer() self.backgroundColor = UIColor.blackColor() self.addTapAction() } func addTapAction(){ //添加组件的点击事件 let tap = UITapGestureRecognizer(target: self, action: #selector(FullScreenShowImageView.handleTapAction(_:))) self.addGestureRecognizer(tap) } //点击事件响应 func handleTapAction(tap:UITapGestureRecognizer)->Void{ //获取图片索引值 self.delegate.hiddenForCliked(self.currentIndex) self.dismissViewAnimate() } func presentViewAnimate() { let fr = self.middleImageView?.frame self.middleImageView?.frame = CGRect(x: fr!.origin.x, y: 22, width: fr!.width, height: fr!.height) UIView.animateWithDuration(10, animations: { self.middleImageView?.frame = fr! }) { (_) in } } func dismissViewAnimate() { let fr = self.middleImageView?.frame self.middleImageView?.frame = CGRect(x: fr!.origin.x, y: fr!.origin.y - StatusAndNavHeight, width: fr!.width, height: fr!.height) UIView.animateWithDuration(10, animations: { self.middleImageView?.frame = CGRect(x: fr!.origin.x , y: -42, width: fr!.width, height: fr!.height) }) { (_) in self.hidden = true self.middleImageView?.frame = fr! } } //设置scrollerView func configureScrollerView(){ self.scrollerView = UIScrollView(frame: CGRect(x: 0,y: 0, width: self.scrollerViewWidth!, height: BHeight)) self.scrollerView?.backgroundColor = UIColor.blackColor() self.scrollerView?.delegate = self self.scrollerView?.contentSize = CGSize(width: self.scrollerViewWidth! * 3, height: BHeight) //滚动视图内容区域向左偏移一个view的宽度 self.scrollerView?.contentOffset = CGPoint(x: self.scrollerViewWidth!, y: 0) self.scrollerView?.pagingEnabled = true self.scrollerView?.bounces = false self.addSubview(self.scrollerView!) } //设置加载指示图片 func configurePlaceholder(){ //这里我使用ImageHelper将文字转换成图片,作为加载指示符 let font = UIFont.systemFontOfSize(17)// UIFont.systemFont(ofSize: 17.0, weight: UIFontWeightMedium) let size = CGSize(width: self.scrollerViewWidth!, height: self.scrollerViewHeight!) placeholderImage = UIImage(named: "图片加载中...") } //设置imageView func configureImageView(){ self.leftImageView = UIImageView(frame: CGRect(x: 0, y: (BHeight-scrollerViewHeight!)/2, width: self.scrollerViewWidth!, height: self.scrollerViewHeight!)) self.middleImageView = UIImageView(frame: CGRect(x: self.scrollerViewWidth!, y: (BHeight-scrollerViewHeight!)/2, width: self.scrollerViewWidth!, height: self.scrollerViewHeight! )); self.rightImageView = UIImageView(frame: CGRect(x: 2*self.scrollerViewWidth!, y: (BHeight-scrollerViewHeight!)/2, width: self.scrollerViewWidth!, height: self.scrollerViewHeight!)); self.scrollerView?.showsHorizontalScrollIndicator = false self.leftImageView?.contentMode = UIViewContentMode.ScaleAspectFit self.middleImageView?.contentMode = UIViewContentMode.ScaleAspectFit self.rightImageView?.contentMode = UIViewContentMode.ScaleAspectFit //设置初始时左中右三个imageView的图片(分别时数据源中最后一张,第一张,第二张图片) if(self.dataSource?.count != 0){ resetImageViewSource() } self.scrollerView?.addSubview(self.leftImageView!) self.scrollerView?.addSubview(self.middleImageView!) self.scrollerView?.addSubview(self.rightImageView!) } //设置页控制器 func configurePageController() { self.pageControl = UIPageControl(frame: CGRect(x: kScreenWidth/2-60, y: BHeight - 30, width: 120, height: 20)) self.pageControl?.numberOfPages = (self.dataSource?.count)! self.pageControl?.userInteractionEnabled = false self.addSubview(self.pageControl!) } //设置自动滚动计时器 func configureAutoScrollTimer() { //设置一个定时器,每三秒钟滚动一次 autoScrollTimer = NSTimer.scheduledTimerWithTimeInterval(3, target: self, selector: #selector(SliderGalleryController.letItScroll), userInfo: nil, repeats: true) } //计时器时间一到,滚动一张图片 func letItScroll(){ let offset = CGPoint(x: 2*scrollerViewWidth!, y: 0) self.scrollerView?.setContentOffset(offset, animated: true) } //每当滚动后重新设置各个imageView的图片 func resetImageViewSource() { //当前显示的是第一张图片 if self.currentIndex == 0 { self.leftImageView?.sd_setImageWithURL(NSURL(string: self.dataSource!.last!)) self.middleImageView?.sd_setImageWithURL(NSURL(string: self.dataSource!.first!)) let rightImageIndex = (self.dataSource?.count)!>1 ? 1 : 0 //保护 self.rightImageView?.sd_setImageWithURL(NSURL(string: self.dataSource![rightImageIndex])) } //当前显示的是最后一张图片 else if self.currentIndex == (self.dataSource?.count)! - 1 { self.leftImageView?.sd_setImageWithURL(NSURL(string:self.dataSource![self.currentIndex-1])) self.middleImageView?.sd_setImageWithURL(NSURL(string: self.dataSource!.last!)) self.rightImageView?.sd_setImageWithURL(NSURL(string: self.dataSource!.first!)) } //其他情况 else{ self.leftImageView?.sd_setImageWithURL(NSURL(string:self.dataSource![self.currentIndex-1])) self.middleImageView?.sd_setImageWithURL(NSURL(string: self.dataSource![self.currentIndex])) self.rightImageView?.sd_setImageWithURL(NSURL(string: self.dataSource![self.currentIndex+1])) } //设置页控制器当前页码 self.pageControl?.currentPage = self.currentIndex } //scrollView滚动完毕后触发 func scrollViewDidScroll(scrollView: UIScrollView) { //获取当前偏移量 let offset = scrollView.contentOffset.x if(self.dataSource?.count != 0){ //如果向左滑动(显示下一张) if(offset >= self.scrollerViewWidth!*2){ //还原偏移量 scrollView.contentOffset = CGPoint(x: self.scrollerViewWidth!, y: 0) //视图索引+1 self.currentIndex = self.currentIndex + 1 if self.currentIndex == self.dataSource?.count { self.currentIndex = 0 } } //如果向右滑动(显示上一张) if(offset <= 0){ //还原偏移量 scrollView.contentOffset = CGPoint(x: self.scrollerViewWidth!, y: 0) //视图索引-1 self.currentIndex = self.currentIndex - 1 if self.currentIndex == -1 { self.currentIndex = (self.dataSource?.count)! - 1 } } //重新设置各个imageView的图片 resetImageViewSource() } } //手动拖拽滚动开始 func scrollViewWillBeginDragging(scrollView: UIScrollView) { //使自动滚动计时器失效(防止用户手动移动图片的时候这边也在自动滚动) //autoScrollTimer?.invalidate() } //手动拖拽滚动结束 func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) { //重新启动自动滚动计时器 //configureAutoScrollTimer() } } 如何使用: var sliderGallery : FullScreenShowImageView! var bannerCurrentIndex:Int = 0 //图片轮播组件协议方法:获取内部scrollView尺寸 func galleryScrollerViewSize() -> CGSize { return CGSize(width: BWidth, height: BHeight/2) } //图片轮播组件协议方法:获取数据集合 func galleryDataSource() -> [String] { return self.bannerView.imageURLStringsGroup as! [String] } //点击事件响应 func hiddenForCliked(index:Int){ if(bannerCurrentIndex != index){ self.bannerView.scrollToIndex(Int32(index)) } self.navigationController?.setNavigationBarHidden(false, animated: false) } func showImageGallery(index:Int){ //初始化图片轮播组件 if(sliderGallery == nil){ sliderGallery = FullScreenShowImageView(frame: CGRect(x: 0, y: 0, width: BWidth, height: BHeight),delegate:self) sliderGallery.currentIndex = index sliderGallery.resetImageViewSource() //将图片轮播组件添加到当前视图 self.view.addSubview(sliderGallery) }else{ sliderGallery.currentIndex = index sliderGallery.resetImageViewSource() sliderGallery.hidden = false } self.sliderGallery.presentViewAnimate() self.navigationController?.setNavigationBarHidden(true, animated: false) } //pragma -- SDCycleScrollViewDelegate func cycleScrollView(cycleScrollView: SDCycleScrollView!, didSelectItemAtIndex index: Int) { print("--------index:(index)") bannerCurrentIndex = index self.showImageGallery(index) }

优秀的个人博客,低调大师

js识别设备

console.log(window.navigator); Navigator 对象属性 appCodeName返回浏览器的代码名。 appMinorVersion返回浏览器的次级版本。 appName返回浏览器的名称。 appVersion返回浏览器的平台和版本信息。 browserLanguage返回当前浏览器的语言。 cookieEnabled返回指明浏览器中是否启用 cookie 的布尔值。 cpuClass返回浏览器系统的 CPU 等级。 onLine返回指明系统是否处于脱机模式的布尔值。 platform返回运行浏览器的操作系统平台。 systemLanguage返回 OS 使用的默认语言。 userAgent返回由客户机发送服务器的 user-agent 头部的值。 userLanguage返回 OS 的自然语言设置。 Navigator 对象方法 javaEnabled()规定浏览器是否启用 Java。 taintEnabled()规定浏览器是否启用数据污点 (data tainting)。 // 判断pc端还是移动端 function isPC() { var userAgentInfo = navigator.userAgent; var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"]; var flag = true; for (var i = 0; i < Agents.length; i++) { if (userAgentInfo.indexOf(Agents[i]) > 0) { flag = false; break; } } return flag; } // 判断用户移动端使用的系统平台 function isMobile() { var u = navigator.userAgent; if (u.indexOf('Android') > -1 || u.indexOf('Linux') > -1) { return "Android!"; // 安卓手机 } else if (u.indexOf('iPhone') > -1) { return "iPhone!"; // 苹果手机 } else if (u.indexOf('iPad') > -1) { return "iPad!"; // iPad手机 } else if (u.indexOf('Windows Phone') > -1) { return "Windows Phone!"; // winphone手机 } else { return false; } } // 判断用户是否在微信中打开 function isWeChat() { // toLowerCase() 方法用于把字符串转换为小写。 var ua = navigator.userAgent.toLowerCase(); if (ua.indexOf('micromessenger') != -1) { return true; } else { return false; } } document.write("是否PC:" + isPC() + "<br/>是否移动端:" + isMobile() + "<br/>是否微信:" + isWeChat()); GitHub:Fuck me on GitHub 留下你的足迹求推荐呦

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册