2015-07-23 17:56:45 Relax_Ver 阅读数 260
  • Android界面控件难点精讲

    Android控件开发教程,在Android开发中,有时用到一些常见的控件可以更轻松实现一些效果,比如如果要实现图片轮播效果,我们可以使用动画的方式实现,但是代码比较繁琐,而此时,我们采用ViewFlipper控件即可非常方便地实现图片轮播。同时,在Android开发中,如果能够使用MVC模式进行开发,则开发效率会高很多,此时,我们则可以使用AdapterView与Adapter高级控件来实现类似MVC的模式进行开发,从而大大提高开发效率本课中会给出AdapterView与Adapter的解决具体问题的应用案例。

    9775 人正在学习 去看看 CSDN讲师

当手指在图片中上下滑动的时候,图片的上半部分会有折叠效果。类似地可以扩展到其他需要折叠的场景中。

layer.contentsRect

用来截取layer的部分内容重新在frame中渲染。


代码及关键注释如下:

@interface ViewController ()


{

    /**

     *  创建两个UIImageView,分别用来保存图片的上、下两部分。

     */

    UIImageView *imageViewUp;

    UIImageView *imageViewDown;

}


@end


@implementation ViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor whiteColor];

    // Do any additional setup after loading the view, typically from a nib.

    imageViewUp = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"1"]];

    //设置折叠的锚点

    imageViewUp.layer.anchorPoint = CGPointMake(0.5, 1);

    imageViewUp.frame = CGRectMake(10, 100, 300, 150);

    //设置imageView的内容为图片的上半部分

    imageViewUp.layer.contentsRect = CGRectMake(0, 0, 1, 0.5);

    

    [self.view addSubview:imageViewUp];

    

    imageViewDown = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"1"]];

    imageViewDown.layer.anchorPoint = CGPointMake(0.5, 0);

    imageViewDown.frame = CGRectMake(10, 250, 300, 150);

    imageViewDown.layer.contentsRect = CGRectMake(0, 0.5, 1, 0.5);

    

    [self.view addSubview:imageViewDown];

    

    

    //添加一个透明浮层,用来捕捉手指滑动。

    UIView *clearView = [[UIView alloc] initWithFrame:CGRectMake(10, 100, 300, 300)];

    clearView.backgroundColor = [UIColor clearColor];

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];

    [clearView addGestureRecognizer:pan];

    clearView.userInteractionEnabled = YES;

    clearView.tag = 100;

    [self.view addSubview:clearView];


}


- (void)pan:(UIPanGestureRecognizer *)ges

{

    

    if (ges.state == UIGestureRecognizerStateChanged) {

        UIView *clearView = (UIView *)[imageViewUp viewWithTag:100];

        CGPoint point = [ges translationInView:clearView];

        //计算旋转角度,拉动距离568时旋转90度。

        float R = -point.y*M_PI_2/568.0f;

        CATransform3D tran = CATransform3DIdentity;

        //设置折叠视角,使之更有立体感

        tran.m34 = -1.0/500.0;

        imageViewUp.layer.transform = CATransform3DRotate(tran, R, 1, 0, 0);

    }

    else if(ges.state == UIGestureRecognizerStateEnded)

    {

        //当松开手指时,图片状态恢复。

        [UIView animateWithDuration:0.5f delay:0.0f options:UIViewAnimationOptionCurveLinear animations:^{

            imageViewUp.layer.transform = CATransform3DIdentity;

        } completion:^(BOOL finished) {

            nil;

        }];

    }

}


2018-04-24 15:34:59 qq_30932479 阅读数 559
  • Android界面控件难点精讲

    Android控件开发教程,在Android开发中,有时用到一些常见的控件可以更轻松实现一些效果,比如如果要实现图片轮播效果,我们可以使用动画的方式实现,但是代码比较繁琐,而此时,我们采用ViewFlipper控件即可非常方便地实现图片轮播。同时,在Android开发中,如果能够使用MVC模式进行开发,则开发效率会高很多,此时,我们则可以使用AdapterView与Adapter高级控件来实现类似MVC的模式进行开发,从而大大提高开发效率本课中会给出AdapterView与Adapter的解决具体问题的应用案例。

    9775 人正在学习 去看看 CSDN讲师

整天逛淘宝,偶尔有一天看到其中的展示页有个看起来很炫的效果,闲来无事就试着写一个出来,先来看效果:

简单记一下思路,这里我选择使用UICollectionView控件,先根据其复用和滚动的特性做出无限轮播的效果,关键代码:

//数据源数组
    let totalCount = 100
    var models: [String] = [String]() {
        didSet {
            //判断元素个数
            if models.count < 2 {
                collectionView.isScrollEnabled = false
            }
            //网上的找来的一个办法添加100组数据源对应的索引数组indexArr
            for _ in 0..<totalCount {
                for j in 0..<models.count {
                    indexArr.append(j)
                }
            }
            //开始就滚动到第50组数据源
            collectionView.scrollToItem(at: IndexPath(item: totalCount/2 * models.count, section: 0), at: .centeredHorizontally, animated: false)
        }
    }

滚动停止时走的方法里做处理:

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        //找到滚动停止的点对应的collectionView的indexPath
        let point =  self.convert(collectionView.center, to: collectionView)
        let index = collectionView.indexPathForItem(at: point)
        let indexpath = (index?.row ?? 0) % models.count
        
        collectionView.scrollToItem(at: IndexPath(item: totalCount/2 * models.count + indexpath, section: 0), at: .centeredHorizontally, animated: false)
    }
以上是滚动的处理,接下来就是item的渐变效果处理,看到这种情况就想到要写一个UICollectionViewFlowLayout
类供collectionView使用,UICollectionViewFlowLayout是管理item怎么展示用的,首先重写展示视图内的layoutAttributes方法,在此方法中找到attribute对应的item及其属性,和collectionView的偏移量和中心点,进行一系列的计算:

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        
        //集合视图的宽高(这里默认宽高相等)
        let itemHeight = self.collectionView?.frame.height ?? 0
        //可是视图内的attributes数组
        let array = super.layoutAttributesForElements(in: rect)
        //item透明度开始变化时的item的中心点x
        let centerX = self.collectionView!.contentOffset.x + itemHeight/2
        print(self.collectionView?.contentOffset.x ?? 0)
        
        for attributes in array! {
            //开始变化时的item的中心点x 与 实际中心点相比较
            let value = attributes.center.x - centerX
            let delta = abs(value)
            //设置缩放比例,此处4*itemHeight可根据缩放效果进行修改
            let scale = 1 - delta/(4*itemHeight)
    
            //设置缩放比例
            attributes.transform = CGAffineTransform.init(scaleX: scale, y: scale)
            //层次关系,设置此属性使item依次上下排列
            attributes.zIndex = Int(1 - abs(delta))
            
            //value<=0表示向左移动,最前面的item停止一段距离
            if value <= 0{
                //实际中心点与开始变化时的item的中心点小于等于设定的边界值
                if delta >= 0 && delta <= itemHeight
                {
                    //item的中心点固定不变
                    attributes.center.x = centerX
                    //根据推进值,改变item的透明度,此处的delta>10是想让item有一个达到目标区域时有一个停顿效果而不是直接进入改变透明度的阶段
                    attributes.alpha = (delta > 10) ? (1 - delta/(itemHeight/4)) : 1
                    //设置缩放比例,停顿阶段不进行缩放
                    attributes.transform = CGAffineTransform.init(scaleX: 1, y: 1)
                } else {
                    //移动大于边界值,就是从停顿阶段到透明度改变,此处是下一个item上来,当前item透明度变为0
                    attributes.alpha = 0
                }
            }
        }
        return array
    }

解决最后一个小问题,拖动iitem开始滚动,滚动结束时让它自动滚动到网格区域,而不是停在当前或许不适当的地方,重写UICollectionViewFlowLayout另一个方法:

override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
        
        let targetRect = CGRect(x: proposedContentOffset.x, y: 0.0, width: self.collectionView!.bounds.size.width, height: self.collectionView!.bounds.size.height)
        
        //目标区域中包含的cell
        let attrArray = super.layoutAttributesForElements(in: targetRect) as! [UICollectionViewLayoutAttributes]
        //collectionView落在屏幕重点的x坐标
        let horizontalCenterX = proposedContentOffset.x + (self.collectionView?.frame.height ?? 0)/2
        var offsetAdjustment = CGFloat(MAXFLOAT)
        for layoutAttributes in attrArray {
            
            let itemHorizontalCenterX = layoutAttributes.center.x
            //找出离中心店最近的
            if (abs(itemHorizontalCenterX-horizontalCenterX) < abs(offsetAdjustment)) {
                offsetAdjustment = itemHorizontalCenterX - horizontalCenterX
            }
        }
        
        //返回collectionView最终停留的位置
        return CGPoint(x: proposedContentOffset.x + offsetAdjustment, y: proposedContentOffset.y)
        
    }
//当collectionView的显示范围发生改变的时候,是否重新布局
    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        return true
    }

最后一个方法不写看不到渐变的效果。

源码地址:点击打开链接

2016-04-11 08:04:40 wbwjx 阅读数 7903
  • Android界面控件难点精讲

    Android控件开发教程,在Android开发中,有时用到一些常见的控件可以更轻松实现一些效果,比如如果要实现图片轮播效果,我们可以使用动画的方式实现,但是代码比较繁琐,而此时,我们采用ViewFlipper控件即可非常方便地实现图片轮播。同时,在Android开发中,如果能够使用MVC模式进行开发,则开发效率会高很多,此时,我们则可以使用AdapterView与Adapter高级控件来实现类似MVC的模式进行开发,从而大大提高开发效率本课中会给出AdapterView与Adapter的解决具体问题的应用案例。

    9775 人正在学习 去看看 CSDN讲师

概述

CoverFlow效果是IOS上自带的控件,类似3d轮播图效果。
在Android中也有很多的相关实现,大体都是使用Gallery和Camera来实现的。

相关开源库:ImageCoverFlow

效果图:

这里写图片描述

但是Gallery已经被标记过时,而且ViewPager更方便使用。而且ViewPager中有个接口ViewPagerTransformer,专门用于给ViewPager设置翻页动画的。

ViewPagerTransformer使用

自定义类实现ViewPagerTransformer接口,viewpager调用setPageTransformer即可。

//参数含义:page绘制顺序;transformer实例对象
ViewPager.setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer);

每次界面切换,transformPage()都会为viewpager容器下的缓存页面调用该方法。如,第三页可见且用户向第四页拖动,在操作的各个阶段为第二,三,四页分别调用(ViewPager默认缓存3页)。

//其中view即viewpager的当前item,
transformPage(View view, float position)

如果是3页的 情况下,当前也position的取值范围是[-1,1]
前面的position:[-Infinity,-1)
后面的position:(1,+Infinity]

clipChildren

clipChildren是指子控件是否超过padding区域,这个属性默认是true,利用此属性即可设置viewpager一屏展示多个item,如果将page 沿着y轴旋转即可实现类似coverflow效果了。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:id="@+id/vp_container"
    android:layout_height="match_parent"
    android:clipChildren="false">

    <com.bobomee.android.scrollloopviewpager.autoscrollviewpager.AutoScrollViewPager
        android:id="@+id/picslooper3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="100dp"
        android:layout_marginRight="100dp"
        android:clipChildren="false" />

    <com.bobomee.android.drawableindicator.widget.DrawableIndicator
        android:id="@+id/pageIndexor3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        app:indicator_height="15dp"
        app:indicator_margin="15dp"
        app:indicator_select_src="@drawable/select_drawable"
        app:indicator_unselect_src="@drawable/unselect_drawable"
        app:indicator_width="15dp" />
</RelativeLayout>

java code:

  PagerAdapter adapter;
        final AutoScrollViewPager viewPager = (AutoScrollViewPager) findViewById(R.id.picslooper3);
        viewPager.setAdapter(adapter = new FragmentStateAdapter(getSupportFragmentManager()));
        viewPager.setDirection(AutoScrollViewPager.LEFT);
        viewPager.setPageTransformer(true, new RotateTransformer());

        BaseIndicator pageIndex = (BaseIndicator) findViewById(R.id.pageIndexor3);
        pageIndex.setViewPager(viewPager);

        viewPager.startAutoScroll();

        //设置幕后item的缓存数目
        viewPager.setOffscreenPageLimit(adapter.getCount());

        //设置页与页之间的间距
        int margin = ((ViewGroup.MarginLayoutParams) viewPager.getLayoutParams()).leftMargin;
        viewPager.setPageMargin(-(px2dip(this, margin)) / 2);

        //将父类的touch事件分发至viewPgaer,否则只能滑动中间的一个view对象
        RelativeLayout vpContainer = (RelativeLayout) findViewById(R.id.vp_container);
        vpContainer.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return viewPager.dispatchTouchEvent(event);
            }
        });

transformer:

public class RotateTransformer implements ViewPager.PageTransformer {

    public static final float MAX_SCALE = 1.2f;
    public static final float MIN_SCALE = 0.6f;

    @Override
    public void transformPage(View page, float position) {
        page.setRotationY(position * -45);

        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();
        }

    }
}

效果图:
3dbanner

实例代码:autoscrollloopviewpager

2017-05-20 15:54:16 zhaofahseng 阅读数 869
  • Android界面控件难点精讲

    Android控件开发教程,在Android开发中,有时用到一些常见的控件可以更轻松实现一些效果,比如如果要实现图片轮播效果,我们可以使用动画的方式实现,但是代码比较繁琐,而此时,我们采用ViewFlipper控件即可非常方便地实现图片轮播。同时,在Android开发中,如果能够使用MVC模式进行开发,则开发效率会高很多,此时,我们则可以使用AdapterView与Adapter高级控件来实现类似MVC的模式进行开发,从而大大提高开发效率本课中会给出AdapterView与Adapter的解决具体问题的应用案例。

    9775 人正在学习 去看看 CSDN讲师



立方体旋转这里用的是UICollectionView 去实现,重写UICollectionViewLayout的布局,再加入3D设置代码,当视图返回了三个以上的cell时,便可实现无缝连接的旋转立体视觉感,这里建议三个到六个之间,当返回的cell数越多,会越接近圆形! 下面贴代码:


-.第一步建立一个新的文件继承至UICollectionViewLayout 文件名为CircleLayout

.h文件为:

#import <UIKit/UIKit.h>


@interface 3DcleLayout :UICollectionViewLayout

@property(nonatomic,assign) CGSize itemSize;//cell的尺寸


- (instancetype)initWithItemSize:(CGSize)itemSize;//重写cell尺寸方法

@end


.m文件实现

#import "3DcleLayout.h"


@implementation CircleLayout


/**

 重写尺寸初始化方法


 @param itemSize cell尺寸

 @return返回对象

 */

- (instancetype)initWithItemSize:(CGSize)itemSize

{

    if (self = [superinit]) {

        _itemSize = itemSize;

    }

    returnself;

}



/**

 返回尺寸大小


 @return 返回尺寸大小

 */

-(CGSize)collectionViewContentSize

{

    float width =self.collectionView.frame.size.width *([self.collectionViewnumberOfItemsInSection:0 ]+2);

    float height=self.collectionView.frame.size.height;

    CGSize  size =CGSizeMake(width, height);

    return size;

}



- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds

{

    returnYES;

}


//这里是关键,这设置3d效果

#pragma mark - UICollectionViewLayout

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath

{

    //3D代码

    UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributeslayoutAttributesForCellWithIndexPath:indexPath];

    UICollectionView *collection =self.collectionView;

    float width = collection.frame.size.width;

    float height = collection.frame.size.height;

    float x = collection.contentOffset.x;

    CGFloat arc =M_PI * 2.0f;

    NSInteger numberOfVisibleItems = [self.collectionViewnumberOfItemsInSection:0];


    attributes.center =CGPointMake(x+width * 0.5,height * 0.5);

//  attributes.size = CGSizeMake(width * 0.5, height - 40);

    attributes.size =_itemSize;

    

    CATransform3D transform =CATransform3DIdentity;

    transform.m34 = -1.0f/700.0f;


    CGFloat radius = attributes.size.width/2/tanf(arc/2.0f/numberOfVisibleItems);

    CGFloat angle = (indexPath.row-x/width+1)/ numberOfVisibleItems * arc;

    transform = CATransform3DRotate(transform, angle,0.0f, 1.0f,0.0f);

    transform = CATransform3DTranslate(transform,0.f, 0.0f, radius);

    attributes.transform3D = transform ;


    return attributes;

}

-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect

{

    NSArray *arr = [superlayoutAttributesForElementsInRect:rect];

    if ([arrcount] >0) {

        return arr;

    }

    NSMutableArray* attributes = [NSMutableArrayarray];

    for (NSInteger i=0 ; i < [self.collectionViewnumberOfItemsInSection:0 ]; i++) {

        NSIndexPath* indexPath = [NSIndexPathindexPathForItem:i inSection:0];

        [attributes addObject:[selflayoutAttributesForItemAtIndexPath:indexPath]];

    }

    return attributes;

}



@end



第二步:第一步已经封装好了3D效果,接下来只要去初始化UICollectionView的时候调用它即可,方法是在一个UIviewController,或者UIView上初始化一个UICollectionView,例如:

 //控制上下左右边距

    self.collectionView = [[UICollectionViewalloc]

               initWithFrame:rect

        collectionViewLayout:[[CircleLayoutalloc]

                                 initWithItemSize:CGSizeMake(

                                                      rect.size.width *0.55,

                                                      rect.size.height -placeBank)]];


placeBank是控制3d轮播图距离上下边距的大小,rect是collectionView的frame.


到这里以后只需要在实现对应的代理方法,返回3个以上cell即可实现,cell可自行自定义,也可使用定时器做成自动旋转效果





2018-07-24 14:16:40 u010960265 阅读数 22933
  • Android界面控件难点精讲

    Android控件开发教程,在Android开发中,有时用到一些常见的控件可以更轻松实现一些效果,比如如果要实现图片轮播效果,我们可以使用动画的方式实现,但是代码比较繁琐,而此时,我们采用ViewFlipper控件即可非常方便地实现图片轮播。同时,在Android开发中,如果能够使用MVC模式进行开发,则开发效率会高很多,此时,我们则可以使用AdapterView与Adapter高级控件来实现类似MVC的模式进行开发,从而大大提高开发效率本课中会给出AdapterView与Adapter的解决具体问题的应用案例。

    9775 人正在学习 去看看 CSDN讲师

效果:
这里写图片描述

参考UITableView的UITableViewDataSource和UITableViewDelegate两个方法实现;支持五险轮播,可以加载本地图片,也可以加载网络图片,可以根据自己的需求自定义
Demo地址

UITableViewDelegate

/**
 *  当前显示cell的Size(中间页显示大小)
 *
 *  @param flowView <#flowView description#>
 *
 *  @return <#return value description#>
 */
- (CGSize)sizeForPageInFlowView:(HQFlowView *)flowView;

/**
 *  滚动到了某一列
 *
 *  @param pageNumber <#pageNumber description#>
 *  @param flowView   <#flowView description#>
 */
- (void)didScrollToPage:(NSInteger)pageNumber inFlowView:(HQFlowView *)flowView;

/**
 *  点击了第几个cell
 *
 *  @param subView 点击的控件
 *  @param subIndex    点击控件的index
 *
 *  @return <#return value description#>
 */
- (void)didSelectCell:(HQIndexBannerSubview *)subView withSubViewIndex:(NSInteger)subIndex;

UITableViewDataSource

/**
 *  返回显示View的个数
 *
 *  @param flowView <#flowView description#>
 *
 *  @return <#return value description#>
 */
- (NSInteger)numberOfPagesInFlowView:(HQFlowView *)flowView;

/**
 *  给某一列设置属性
 *
 *  @param flowView <#flowView description#>
 *  @param index    <#index description#>
 *
 *  @return <#return value description#>
 */
- (HQIndexBannerSubview *)flowView:(HQFlowView *)flowView cellForPageAtIndex:(NSInteger)index;

3D-立体旋转轮播

阅读数 282

没有更多推荐了,返回首页