最近在玩一个叫“约会吧”的应用,也是在看直播app,默认下载安装的,安装点进去看这个应用做的不错,就留下来了。然后看他们动态详情页底部有一个效果:RecyclervIEw滑动到的评论列表的时候,底部点赞那栏会往左滑动,出现一个输入评论的栏;然后下拉到底部的时候输入评论栏会往右滑动,出现点赞栏。详细细节直接来看效果图吧。
其实这种效果现在在应用中还是很常见的,有上拉,toolbar、底部vIEw隐藏,下拉显示,或者像现在约会吧这样左右滑动的效果。而且网上资料现在也有很多,有通过ObjectAnimation来实现的,这里我们通过另外一种方法来实现。仔细下看下这个效果,其实他就是vIEw滚动的效果,想到AndroID里面的滚动,马上就能想到scroller类了,scroller有一个startScroll()方法,通过这个方法我们就可以滚动了。滚动问题解决了,那么这个效果就很简单了,进入页面时,把要显示vIEw的先显示出来,不该显示的暂时放在屏幕外面,当滚动的时间,我们控制vIEw进入屏幕或者退出屏幕。大概思路就是这样,下面我们就来实现这样的效果吧。
效果的实现
首先,我们根据上面的思路把布局给整出来。结构如下图:
这里说明下上面的图,分为3块来说,
- 当RecyclervIEw上拉的时候,屏幕内5位置的vIEw会隐藏,也就是移动到屏幕外面的6位置,当RecyclervIEw下拉的时候,屏幕外面的6位置vIEw又会回到5位置显示。
- 当RecyclervIEw上拉的时候,屏幕内的1位置的vIEw会隐藏,也就是移动到屏幕外面的4位置,当RecyclervIEw下拉的时候,屏幕外面的4位置vIEw会回到1位置显示。
- 当RecyclerVIEw上拉的时候,而且设置为水平方向左右滑动的时候,屏幕内的1位置的vIEw会移动到3位置,同时屏幕外面2位置vIEw会移动到屏幕内1位置来显示,当RecyclerVIEw下拉的时候,屏幕外的3位置会移动到屏幕内的1位置。1位置显示的vIEw也会回到屏幕外的2位置隐藏。这也就是上面应用的效果。
布局效果和代码如下(这里添加两个按钮来切换底部方向的效果):
效果图
activity_main.xml
<?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:background="@androID:color/white"> <androID.support.v7.Widget.RecyclerVIEw androID:ID="@+ID/ID_recyclervIEw" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" /> <relativeLayout androID:ID="@+ID/ID_horization_rl" androID:layout_wIDth="match_parent" androID:layout_height="60dp" androID:layout_alignParentBottom="true" androID:orIEntation="horizontal" > <TextVIEw androID:ID="@+ID/ID_bottom_float" androID:layout_wIDth="match_parent" androID:layout_height="60dp" androID:text="我是点赞 *** 作布局" androID:textSize="18sp" androID:gravity="center" androID:background="#E2E2E2"> </TextVIEw> <TextVIEw androID:ID="@+ID/ID_bottom_comment" androID:layout_wIDth="match_parent" androID:layout_height="60dp" androID:text="我是评论输入布局" androID:textSize="18sp" androID:gravity="center" androID:background="#FF4500"> </TextVIEw> </relativeLayout> <TextVIEw androID:ID="@+ID/ID_bottom_vertical" androID:layout_wIDth="match_parent" androID:layout_height="60dp" androID:text="你滑动,我随你而变" androID:layout_alignParentBottom="true" androID:background="#eeeeee" androID:gravity="center" androID:textSize="16sp" /> <TextVIEw androID:ID="@+ID/ID_top_vertical" androID:layout_wIDth="match_parent" androID:layout_height="60dp" androID:text="你滑动,我随你而变" androID:background="#eeeeee" androID:gravity="center" androID:textSize="16sp" /> <linearLayout androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:ID="@+ID/ID_switch" androID:orIEntation="vertical" androID:layout_alignParentRight="true" androID:layout_centerVertical="true"> <TextVIEw androID:layout_wIDth="wrap_content" androID:layout_height="60dp" androID:gravity="center" androID:background="#eeeeee" androID:text="切换底部水平动画" androID:onClick="showHorization"/> <TextVIEw androID:layout_wIDth="wrap_content" androID:layout_height="60dp" androID:gravity="center" androID:background="#eeeeee" androID:onClick="showVertical" androID:layout_margintop="10dp" androID:text="切换底部垂直动画"/> </linearLayout></relativeLayout>
然后,我们再写一个线程来实现滚动的效果。代码如下:
@H_419_44@public class AnimationUtil implements Runnable{ private Context mContext; //传入需要 *** 作的vIEw private VIEw mAnimationVIEw; //vIEw的宽和高 private int mVIEwWIDth; private int mVIEwHeight; //动画执行时间 private final int DURATION = 400; //是水平还是垂直滑动变化 public boolean mOrIEntaion ; //滚动 *** 作类 private Scroller mScroller; private boolean isShow; public AnimationUtil(Context context,final VIEw mAnimationVIEw){ this.mContext = context ; this.mAnimationVIEw = mAnimationVIEw ; mScroller = new Scroller(context,new linearInterpolator()); //水平布局这里以屏幕宽为准 mVIEwWIDth = getScreenWIDth(); mVIEwHeight = mAnimationVIEw.getMeasuredHeight(); if(mVIEwHeight==0){ mAnimationVIEw.getVIEwTreeObserver().addOnPreDrawListener(new VIEwTreeObserver.OnPreDrawListener() { @OverrIDe public boolean onPreDraw() { mAnimationVIEw.getVIEwTreeObserver().removeOnPreDrawListener(this); mVIEwHeight = mAnimationVIEw.getMeasuredHeight(); return true; } }); } } public voID setorIEntaion(boolean isHorization){ this.mOrIEntaion = isHorization; } //根据滑动变化,isScrollUp为true水平左边滑动,否则反之, //为false垂直往下隐藏,否则反之, public voID startHIDeAnimation(boolean isScrollUp){ isShow = false ; if(!mOrIEntaion){ int dy = (int) (mAnimationVIEw.getTranslationY()+mVIEwHeight); if(!isScrollUp){ dy = (int)(mAnimationVIEw.getTranslationY() - mVIEwHeight); } dy = cling(-mVIEwHeight,mVIEwHeight,dy); mScroller.startScroll(0,(int) mAnimationVIEw.getTranslationY(),dy,DURATION); VIEwCompat.postOnAnimation(mAnimationVIEw,this); return; } int dx = (int) (mAnimationVIEw.getTranslationX()-mVIEwWIDth); if(!isScrollUp){ dx = (int)(mAnimationVIEw.getTranslationX() + mVIEwWIDth); } dx = cling(-mVIEwWIDth,mVIEwWIDth,dx); mScroller.startScroll((int)mAnimationVIEw.getTranslationX(),dx,DURATION); VIEwCompat.postOnAnimation(mAnimationVIEw,this); } //显示控件 public voID startShowAnimation(){ isShow = true ; if(!mOrIEntaion){ int dy = (int) VIEwCompat.getTranslationY(mAnimationVIEw); dy = cling(-mVIEwHeight,-dy,this); return; } int dx = (int) VIEwCompat.getTranslationX(mAnimationVIEw); dx = cling(-mVIEwWIDth,dx); mScroller.startScroll(dx,-dx,this); } //判断当前绑定动画控件是否显示, public boolean isShow() { return isShow; } //终止动画 public voID abortAnimation(){ mScroller.abortAnimation(); } @OverrIDe public voID run() { if(mScroller.computeScrollOffset()){ //动画没停止就继续滑动 VIEwCompat.postOnAnimation(mAnimationVIEw,this); if(!mOrIEntaion){ VIEwCompat.setTranslationY(mAnimationVIEw,mScroller.getCurrY()); return; } VIEwCompat.setTranslationX(mAnimationVIEw,mScroller.getCurrX()); } } public int getScreenWIDth(){ WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); displayMetrics dm = new displayMetrics(); windowManager.getDefaultdisplay().getMetrics(dm); return dm.wIDthPixels; } //控制在一个范围的值 public int cling(int min,int max,int value){ return Math.min(Math.max(min,value),max); }}这里简单说下上面AnimationUtil线程,首先它会创建一个滚动 *** 作类Scroller,然后获取需要滚动的vIEw的宽和高的获取,这里宽直接取屏幕的宽度。同时还有一个mOrIEntaion属性,方向的控制。然后startHIDeAnimation和startShowAnimation两个方法。其中startHIDeAnimation中,我们计算出每个效果的初始位置的x和y。然后x和y轴移动的偏移量,然后startScroll方法的调用,然后把通过VIEwCompat.postOnAnimation把移动动画绑定在传入的vIEw里面。startShowAnimation方法也是同理。我们知道,调用了startScroll,只是告诉Scroller移动到什么位置,具体的移动信息是在computeScrollOffset获取。所以我们通过这个方法就去判断vIEw是否移动完成,没有移动,继续调用当前线程,同时根据方向设置setTranslationY或者setTranslationX。
vIEw滚动的帮助类实现完了,我们就写个RecyclervIEw来简单的测试下,MainActivity代码如下:
@H_419_44@public class MainActivity extends AppCompatActivity { //通过recyclervIEw来提供滑动事件 private RecyclerVIEw mRecyclerVIEw; //一些简单的测试数据 private TestAdapter mRecyclerAdapter; //水平简单赞布局vIEw绑定动画 private AnimationUtil mZanAnimationUtil; //水平简单评论布局vIEw绑定动画 private AnimationUtil mCommAnimationUtil; //垂直底部vIEw绑定动画 private AnimationUtil mBottomVerticalUtil; //垂直头顶vIEw绑定布局 private AnimationUtil mtopVerticalUtil; private List<String> mDataList=Arrays.asList("对Ta说了悄悄话","冲哥","小欢","对象,你在哪","暖心男神","一次就好","对Ta说了悄悄话","一次就好"); private linearlayoutmanager mRecyclerManager; //赞布局控件 private TextVIEw mZanTextVIEw; //评论布局控件 private TextVIEw mCommentVIEw; private relativeLayout mHorizationalRl; //底部布局控件 private TextVIEw mVerticalBottomTv; //头部布局控件 private TextVIEw mVerticaltopTv; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main); mRecyclerVIEw = (RecyclerVIEw) findVIEwByID(R.ID.ID_recyclervIEw); mZanTextVIEw = (TextVIEw) findVIEwByID(R.ID.ID_bottom_float); mCommentVIEw = (TextVIEw)findVIEwByID(R.ID.ID_bottom_comment) ; mVerticalBottomTv = (TextVIEw)findVIEwByID(R.ID.ID_bottom_vertical); mHorizationalRl = (relativeLayout)findVIEwByID(R.ID.ID_horization_rl) ; mVerticaltopTv = (TextVIEw)findVIEwByID(R.ID.ID_top_vertical); mZanAnimationUtil = new AnimationUtil(this,mZanTextVIEw); mCommAnimationUtil = new AnimationUtil(this,mCommentVIEw); mBottomVerticalUtil = new AnimationUtil(this,mVerticalBottomTv); mtopVerticalUtil = new AnimationUtil(this,mVerticaltopTv); mZanAnimationUtil.setorIEntaion(true); mCommAnimationUtil.setorIEntaion(true); mCommAnimationUtil.startHIDeAnimation(false); mHorizationalRl.setVisibility(VIEw.GONE); mRecyclerManager = new linearlayoutmanager(this); mRecyclerVIEw.setLayoutManager(mRecyclerManager); mRecyclerAdapter = new TestAdapter(mDataList,this); mRecyclerVIEw.setAdapter(mRecyclerAdapter); mRecyclerVIEw.addOnScrollListener(new RecyclerVIEw.OnScrollListener() { @OverrIDe public voID onScrollStateChanged(RecyclerVIEw recyclerVIEw,int newState) { //当滑动停止时动画开始 if(newState == RecyclerVIEw.SCRolL_STATE_IDLE){ //在到达某个item改变水平布局 if(mRecyclerManager.findFirstVisibleItemposition()>4){ mZanAnimationUtil.startHIDeAnimation(true); mCommAnimationUtil.startShowAnimation(); }else{ mZanAnimationUtil.startShowAnimation(); if(mCommAnimationUtil.isShow()){ mCommAnimationUtil.startHIDeAnimation(false); } } //头部和底部动画 *** 作 if(mRecyclerManager.findFirstVisibleItemposition()>0){ mBottomVerticalUtil.startHIDeAnimation(true); mtopVerticalUtil.startHIDeAnimation(false); }else{ mBottomVerticalUtil.startShowAnimation(); mtopVerticalUtil.startShowAnimation(); } } } @OverrIDe public voID onScrolled(RecyclerVIEw recyclerVIEw,int dx,int dy) { } }); } public voID showVertical(VIEw vIEw){ mHorizationalRl.setVisibility(VIEw.GONE); mVerticalBottomTv.setVisibility(VIEw.VISIBLE); } public voID showHorization(VIEw vIEw){ mHorizationalRl.setVisibility(VIEw.VISIBLE); mVerticalBottomTv.setVisibility(VIEw.GONE); }}主要是onScrollStateChanged方法里面的 *** 作。主要就是注意下评论布局控件的初始化就好了。
再贴下其他的类
TestAdapter.class
simple_item.xml
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:orIEntation="vertical" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:background="@androID:color/white"> <linearLayout androID:layout_wIDth="match_parent" androID:layout_height="100dp" androID:orIEntation="horizontal" androID:gravity="center_vertical"> <ImageVIEw androID:layout_wIDth="60dp" androID:layout_height="60dp" androID:background="#EEEEEE" androID:layout_margin="10dp" androID:src="@drawable/post_default_avatar"/> <TextVIEw androID:ID="@+ID/ID_text" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:text="21111111" androID:textSize="14sp" androID:layout_marginleft="10dp"/> </linearLayout> <VIEw androID:layout_wIDth="match_parent" androID:layout_height="0.5dp" androID:layout_margintop="10dp" androID:background="#eeeeee"/></linearLayout>
最后,看下实现的效果:
这里 开发环境为androID studio 2.1.0 -prevIEw4
源码下载:Recyclerview滑动左右移动
以上就是本文的全部内容,希望对大家学习AndroID软件编程有所帮助。
总结以上是内存溢出为你收集整理的Android实现评论栏随Recyclerview滑动左右移动全部内容,希望文章能够帮你解决Android实现评论栏随Recyclerview滑动左右移动所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)