最近在即刻里看到即刻的"猜你喜欢"的板块,觉得效果很赞。

     

    

    当点击"换一换"时,上面三个条目程序切换效果,并且三个条目的切换以不同的速度进行。

    于是开始想办法撸出这样的切换效果。

    我的思路是使用竖直切换的ViewPager,因为之前使用过ViewPager的一些切换动画和这里的切换很相似。

    最后实现的两种效果:

      

     

    github地址点我

    关于竖直切换的ViewPager,你能找到很多资料,我这里使用的是一个日本小哥的VerticalViewPager

   他在onInterceptTouchEvent方法里巧妙的添加了swapTouchEvent方法,将左右滑动切换转换为上下滑动,或者说当你上下滑动时,造成一个假象,viewpager以为你在上下切换。

   

package com.example.xw.jikeviewpager;

/**
* Created by xw on 2016/10/9.
*/ import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent; import Transformer.DefaultTransformer; public class VerticalViewPager extends ViewPager { public VerticalViewPager(Context context) {
this(context, null);
} public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
setPageTransformer(false, new DefaultTransformer());
} private MotionEvent swapTouchEvent(MotionEvent event) {
float width = getWidth();
float height = getHeight(); float swappedX = (event.getY() / height) * width;
float swappedY = (event.getX() / width) * height; event.setLocation(swappedX, swappedY); return event;
} @Override
public boolean onInterceptTouchEvent(MotionEvent event) {
boolean intercept = super.onInterceptTouchEvent(swapTouchEvent(event));
//If not intercept, touch event should not be swapped.
swapTouchEvent(event);
return intercept;
} @Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapTouchEvent(ev));
} }

   关于DefaultTransformer类,是用来控制切换效果的,接下来我们会用ZoomOutTransformer。

   关于这几个类,代码点我

   接下来发现即刻切换中的图片都是圆角矩形,关于自定义一个圆角矩形ImageView,代码如下,具体就不分析了。

   

public class RoundRectImageView extends ImageView{

    private Paint paint;

    public RoundRectImageView(Context context) {
this(context,null);
} public RoundRectImageView(Context context, AttributeSet attrs) {
this(context, attrs,0);
} public RoundRectImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
paint = new Paint();
} /**
* 绘制圆角矩形图片
* @author caizhiming
*/
@Override
protected void onDraw(Canvas canvas) { Drawable drawable = getDrawable();
if (null != drawable) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
Bitmap b = getRoundBitmap(bitmap, 20);
final Rect rectSrc = new Rect(0, 0, b.getWidth(), b.getHeight());
final Rect rectDest = new Rect(0,0,getWidth(),getHeight());
paint.reset();
canvas.drawBitmap(b, rectSrc, rectDest, paint); } else {
super.onDraw(canvas);
}
} /**
* 获取圆角矩形图片方法
* @param bitmap
* @param roundPx,一般设置成14
* @return Bitmap
* @author caizhiming
*/
private Bitmap getRoundBitmap(Bitmap bitmap, int roundPx) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output); final int color = 0xff424242; final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
int x = bitmap.getWidth(); canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output; }
}

    

    接下来我们实现第一种切换效果,以一个RoundRectImageView加textview作为fragment,然后将fragment作为VerticalViewPager的内容。

    fragment_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="130dp"
android:layout_height="130dp">
<com.example.xw.jikeviewpager.RoundRectImageView
android:id="@+id/iv"
android:scaleType="centerCrop"
android:layout_width="match_parent"
android:layout_height="120dp"/> <TextView
android:id="@+id/tv"
android:text="1111"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/> </LinearLayout>

    创建fragment类和一个item的实体类代码就省略了。

    要注意这里利用 Argument传数据生成fragment。

   public static MyFragment newInstance(int imgId,String text){
Bundle args=new Bundle();
args.putSerializable(ARG_IMG_ID,imgId);
args.putSerializable(ARG_TEXT,text); MyFragment fragment=new MyFragment();
fragment.setArguments(args);
return fragment; }

    接下来在MainActivity中,我们的布局使用两个VerticalViewPager和一个负责切换的button。

    

private void initViewPager() {

       int[] ims={R.drawable.kenan,R.drawable.mingren,R.drawable.lufei};
String[] text={"身体虽然变小,但头脑依然灵活",
"卡 给 分 新 诺 句 子 !!!",
"我是要成为海贼王的男人!"};
for (int i = 0; i <ims.length ; i++) {
Item item=new Item(ims[i],text[i]);
list.add(item);
} int[] ims2={R.drawable.qinnv,R.drawable.yasuo,R.drawable.timo};
String[] text2={
"为什么哑巴琴女会说话?",
"死亡如风,常伴吾身",
"timo队长,正在送命"
};
for (int i = 0; i <ims2.length ; i++) {
Item item=new Item(ims2[i],text2[i]);
list2.add(item);
} viewPager.setPageTransformer(true, new ZoomOutTransformer());
viewPager2.setPageTransformer(true,new ZoomOutTransformer()); //viewPager.setPageTransformer(true, new StackTransformer());
FragmentManager fm=getSupportFragmentManager();
viewPager.setAdapter(new FragmentStatePagerAdapter(fm) {
@Override
public Fragment getItem(int position) {
Item item=list.get(position);
return MyFragment.newInstance(item.getImageId(),item.getText());
} @Override
public int getCount() {
return list.size();
}
});
viewPager.setOverScrollMode(View.OVER_SCROLL_NEVER);
viewPager.setCurrentItem(list.size()-1); viewPager2.setAdapter(new FragmentStatePagerAdapter(fm) {
@Override
public Fragment getItem(int position) {
Item item=list2.get(position);
return MyFragment.newInstance(item.getImageId(),item.getText());
} @Override
public int getCount() {
return list2.size();
}
}); viewPager2.setOverScrollMode(View.OVER_SCROLL_NEVER);
viewPager2.setCurrentItem(list.size()-1);
}

   因为我们用的是ZoomOut的效果,所以先设置显示在最后一页,点击button时,设置位置减1,刚好可以实现往下切换的效果。

   (其实是因为没有找到ZoomIn的类,如果你找到了直接使用这个转换效果类即可)

   

changeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
viewPager.setCurrentItem((viewPager.getCurrentItem()-1));
viewPager2.setCurrentItem(viewPager2.getCurrentItem()-1);
}
});

    最后,还要实现的是两边切换速度不一样,因为viewPager.setCurrentItem方法设施的切换总是一闪而过,太短暂了,无法形成视觉停留的效果。

    这时候需要用到的类

    FixedSpeedScroller

    

public class FixedSpeedScroller extends Scroller {
private int mDuration = 1500; public FixedSpeedScroller(Context context) {
super(context);
} public FixedSpeedScroller(Context context, Interpolator interpolator) {
super(context, interpolator);
} @Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
// Ignore received duration, use fixed one instead
super.startScroll(startX, startY, dx, dy, mDuration);
} @Override
public void startScroll(int startX, int startY, int dx, int dy) {
// Ignore received duration, use fixed one instead
super.startScroll(startX, startY, dx, dy, mDuration);
} public void setmDuration(int time) {
mDuration = time;
} public int getmDuration() {
return mDuration;
}
public void initViewPagerScroll(ViewPager viewPager) {
try {
Field mScroller = ViewPager.class.getDeclaredField("mScroller");
mScroller.setAccessible(true);
mScroller.set(viewPager, this);
} catch(Exception e) {
e.printStackTrace();
}
}
}

    这里我们看到是利用的反射的手法修改viewpager的"mScroller"字段。

    MainActivity中初始化时调用

    

    private void initSpeed() {
FixedSpeedScroller scroller=new FixedSpeedScroller(this);
scroller.setmDuration(2500);
scroller.initViewPagerScroll(viewPager); FixedSpeedScroller scroller2=new FixedSpeedScroller(this);
scroller2.setmDuration(1500);
scroller2.initViewPagerScroll(viewPager2);
}

    这时候就已经完成了不同的切换速度。

     效果:

    

    至于第二种文字单独切换的,只要将文字单独用一个VerticalViewPager即可。

    以上方法仅供参考,实际应用的话肯定还是要不断地优化处理。

  

    

    

     

  

仿即刻app"猜你喜欢"切换控件的更多相关文章

  1. Xamarin自定义布局系列——PivotPage,多页面切换控件

    PivotPage ---- 多页面切换控件 PivotPage是一个多页面切换控件,类似安卓中的ViewPager和UWP中的Pivot枢轴控件. 起初打算直接通过ScrollView+StackL ...

  2. 一个类似抖音 APP 拍摄按钮效果的控件

    TouchButton 一个类似抖音 APP 拍摄按钮效果的控件 效果图预览 用法 <net.angrycode.library.TouchButton android:id="@+i ...

  3. delphi Table切换控件顺序问题

    delphi Table切换控件顺序问题 Tagorder的值就是确定Table键切换顺序的 以上做法只能解决同一类型的多个控件(如Edit1,edit2....)显示顺序问题 假如有不同类型的控件如 ...

  4. ImageSwitch图像切换控件

    ImageSwitch图像切换控件 继承ViewAnimator所以可以做动画 继承ViewGroup所以可以装别的控件,所以ImageSwitch里面装的就是image,不过要找个ImageView ...

  5. C#中方向键与回车键切换控件焦点

    环境:界面上有TextBox,ComboBox等控件. 不建议把左右方向键都用来切换焦点,否则你在TextBox里面改变光标所在字符位置就不方便了. 方法一:笨方法,需为每个控件单独注册事件处理 以T ...

  6. 仿饿了么增加购物车旋转控件 - 自带闪转腾挪动画 的button

    本篇文章已授权微信公众号 guolin_blog (郭霖)独家公布 转载请标明出处: http://blog.csdn.net/zxt0601/article/details/54235736 本文出 ...

  7. Windows App开发之经常使用控件与应用栏

    控件的属性.事件与样式资源 怎样加入控件 加入控件的方式有多种,大家更喜欢以下哪一种呢? 1)使用诸如Blend for Visual Studio或Microsoft Visual Studio X ...

  8. ANDROID——仿360手机卫士的旋转打分控件

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 简介 灵感源自360手机卫,主要功能就是实现显示评分或等级的效果.并稍微改良了一下,有更好 ...

  9. 手机APP支付--整合银联支付控件

    长话短说,本文根据银联官方说明文档,简单总结下,并且说明下中途碰到问题该如何解决. 一.开发前的准备工作1. 打开https://open.unionpay.com/,后续说的文档下载.FAQ查询等都 ...

随机推荐

  1. [BZOJ3673&3674]可持久化并查集&加强版

    题目大意:让你实现一个可持久化的并查集(3674强制在线). 解题思路:刚刚介绍了一个叫rope的神器:我是刘邦,在这两题(实际上两题没什么区别)就派上用场了. 正解应该是主席树||可持久化平衡树,然 ...

  2. Linux学习总结(14)——Linux权限控制

    linux中,权限的学习是必不可少的,不论是作为一名运维工程师或者是单一的管理者,学习好linux中的权限控制,你就可以保护好自己的隐私同时规划好你所管理的一切. 权限的学习是很多的,不要认为自己已经 ...

  3. HDU 4725 The Shortest Path in Nya Graph

    he Shortest Path in Nya Graph Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged o ...

  4. 将shell脚本运行情况写入Rsyslog日志server

    在运维工作中,免不了编写一些脚本交由计划任务(cron)去定时运行完毕一些日常工作,实现运维工作自己主动化.比方在我的日常工作中备份数据是一项重要的工作,须要定时将数据备份到备份服器和一些其它的备份介 ...

  5. HDU 5310 Souvenir

    Souvenir  Accepts: 901  Submissions: 2743  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: 262 ...

  6. 漫谈linux之文件IO篇(SSD写性能和机械硬盘差不多,读是4到10倍)

    前同事的文章,觉得写得很清晰,收藏了. http://blog.chinaunix.net/uid-27105712-id-3270102.html 在Linux 开发中,有几个关系到性能的东西,技术 ...

  7. css实现上下左右布局

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. sql server management studio 快速折叠object explorer中的instance

    https://social.msdn.microsoft.com/Forums/sqlserver/en-US/6e20fa7a-c0a9-496b-89b2-19c6bd996ffc/how-to ...

  9. NOIP2017 小凯的疑惑 解题报告(赛瓦维斯特定理)

    题目描述 小凯手中有两种面值的金币,两种面值均为正整数且彼此互素.每种金币小凯都有 无数个.在不找零的情况下,仅凭这两种金币,有些物品他是无法准确支付的.现在小 凯想知道在无法准确支付的物品中,最贵的 ...

  10. Metasploit的攻击实例讲解----ms10_046快捷方式图标漏洞

    不多说,直接上干货! 准备工具 1.Kali linux 2016.2(Rolling)系统  IP:  192.168.1.103 2.受害者机子(windows XP系统)   IP: 10.10 ...