用RecyclerView来实现苹果后台样式的卡片布局

来源:互联网 发布:淘宝手机端网址 编辑:程序博客网 时间:2024/06/03 22:39

       说到苹果的卡片布局我就想起当年我的挚爱--web OS系统了。在功能机转换到智能机的时代,Web oS系统是那样的出类拨萃,傲压群雄,只可惜现在流落到只能在电视上才能看到他的身影了。记得我的第一台智能手机就是诺基亚的N81,为了这台手机,我花掉了我的全部奖学金,还跟家里说谎掉钱了。一心只读圣年书的我,从QQ都不知道掉进了智能手机的坑。

       在被诺基亚N81深深吸引的我很快就被Paml pixi这款手机迷倒了。多后台,卡片式管理,动感的“小彩虹菜单”,迷人的便签,还有那个酷帅的手势操作,前卫的点金石无线充电。接着就是Paml pixi plus-->Pre-->Pre plus-->Pre2-->Pre3-->I touch.很快全都落尽我的怀里。然后就在各种论坛折腾,那种乐趣只能剩下回忆了。在web OS被HP抛弃后,才慢慢接触了黑莓8830,苹果,最后才是android。不得不说,Android的开源给了他强大的生命力。

       曾几何时,我希望用Android系统复活Web OS,至少能把他的UI设计传承下来。于是想尽办法设计开发了一整套UI出来,在大学的时候,导师对我的作品非常给了很大的鼓励。

      如今,Android已不是当年所可以比拟的了,各种开源的如汗牛充栋。各种开发控件及UI设计,简直就是淋漓满目。特效更是流畅动感。这里说说v7的RecyclerView吧。RecyclerView的拓展能力非常优秀。不仅替代了传统的ListView,GridView,还为瀑布流这种怪异的布局的实现变得非常方便。之前还在为滑动删除,拖动换位这样的控件搞的焦头烂额,如今就仅仅是几句代码的事情了。最近我就用ReCyclerView变着法子来实现WEB OS的几个经典UI(代码比较粗糙)

      


       让我们看看RecyclerView的神奇之处吧:

       在这里要涉及到几个类,RecyclerView,ItemTouchHelper,ItemTouchHelper.Callback,LinearLayoutManager,RecyclerView.Adapter,RecyclerView.ViewHolder等。

      首先,你要是现实ItemTouchHelper.Callback这个抽象类,实现里面的抽象方法

      getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)   //配置可以拖动的方向和是否可以被滑动删除,UP,DOWN,LEFT,RIGHT表示四个方向,START,END表示删除的动作方向。

      onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)   //交换的时候被调用

      onSwiped(RecyclerView.ViewHolder viewHolder, int direction)    //移除的时候被调用

      onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState)      // 选中的ITEM发生改变被调用

      clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)      //取消选中状态被调用

      然后

      ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback();  //实例化Callback

      itemTouchHelper = new ItemTouchHelper(callback);   //实例化

      itemTouchHelper.attachToRecyclerView(recyclerView);   //绑定RecyclerView

      就这样一个可拖动Item,滑动item移除的ListView就搞定了。当然,基本的适配器,设置竖线线性布局还是很有必要的。

public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback{    private DragEvent mEvent;    public SimpleItemTouchHelperCallback(DragEvent event){        this.mEvent = event;    }    @Override    public boolean isItemViewSwipeEnabled() {        return super.isItemViewSwipeEnabled();    }    @Override    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {        final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;        final int swipFlags = ItemTouchHelper.START | ItemTouchHelper.END;        return makeMovementFlags(dragFlags,swipFlags);    }    @Override    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {        if(viewHolder.getItemViewType() != target.getItemViewType()) return false;        mEvent.onItemSwap(viewHolder.getAdapterPosition(),target.getAdapterPosition());        return true;    }    @Override    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {        mEvent.onItemRemove(viewHolder.getAdapterPosition());    }    @Override    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {        if(actionState != ItemTouchHelper.ACTION_STATE_IDLE){            if(viewHolder instanceof OnViewHolderStatChanageListener){                if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE){                    OnViewHolderStatChanageListener listener = (OnViewHolderStatChanageListener)viewHolder;                    listener.onItemSelectedSwiped();                }else if(actionState == ItemTouchHelper.ACTION_STATE_DRAG){                    OnViewHolderStatChanageListener listener = (OnViewHolderStatChanageListener)viewHolder;                    listener.onItemSelectedDrag();                }            }        }        super.onSelectedChanged(viewHolder, actionState);    }    @Override    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {        super.clearView(recyclerView, viewHolder);        if(viewHolder instanceof OnViewHolderStatChanageListener){            OnViewHolderStatChanageListener listener = (OnViewHolderStatChanageListener)viewHolder;            listener.onItemNormal();        }    }}

在这里我还定义了一个接口,DragEvent,为了我以后可以再其他地方干一些事。同样,这个类的实现同样适用表格布局的RecyclerView。那个便签就是那样实现的。

然而事情才刚刚开始。我想,如果把RecyclerView设置为横向线性布局呢?是不是同样适用呢?怀着猜想的尝试了下,发现问题了,横线的Item可以交换位置,却不能竖向删除。其实从

getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)这个方法的视线可以看出:

int  dragFlags 表示Item的可移动方向;

int  swipFlags 表示Item删除操作的方向;

只需要把Start | End 换成 UP | Down 即可。横线的RecyclerView是不是很像那个卡片布局的样子了?再对Item的布局做一下调整就OK了。看起来比UC浏览器的卡片页面高端多了,那个还不能调整页的顺序,这个一点压力也没有。RecyclerView其实还有很多妙用,之前就在网看到有人用RecyclerView做柱形图,这样的脑洞想不佩服都不行。

         有句话说,方法总比困难多。我想问题的时候总会习惯性的去想想有没有别的途径或者方法可以实现。很多人一看到不规则的UI的时候就会想到如何从写控件,事件分发,事件拦截,事件分析,布局分配,视图重绘等机械式的思考过程,这样就不会有创新可言了。不管怎么样,多一种思路就多一种出路。有时候可以想想,比如线程安全有哪些类或者那些方式可以实现,比如,Vector,Collection.synchronizedList(),Thread.join(),synchronized关键字,CountDownLatch,ReentrantLock,Handler等。有时候觉得编程很写文章有点类似,会的词汇多了,写出来的文章多烂都不觉得那么乏味。



后续:http://blog.csdn.net/rj113/article/details/65660756


0 0
原创粉丝点击