Android中ViewPager支持一屏多个View、切换动画以及无限滚动

1. 首先看一下最终的效果图

image

2. 需求拆解

第一眼看见上面的效果,是不是有些朋友觉得这个效果很酷,有的高手会觉得这个效果很简单。笔者昨天刚拿到需求的时候,最开始也是觉得这个很简单,可是越分析越发现好像实现出来并不是那么容易。单个的效果可能很简单,但是这么多的效果叠在一起,可能就比较复杂了。我简单得将这个效果任务拆解一下:

  1. 一屏要展示3个View,支持左右滑动
  2. 屏幕中间两侧的View移向中间时,会有一个放大的效果;中间的View移向两侧时,会有一个缩小的效果
  3. 点击屏幕两侧的View,会自动滚动到屏幕的中间,同理效果要满足第2点
  4. 当滑动到最左侧或者最右侧时,需要立马衔接最末尾的View和最开头的View,也就是无限滚动
  5. 考虑性能问题,必须有一个缓存机制。否则控件的count大于30的时候,会有非常明显的卡顿

起初我想过用HorizontalScrollView来做,但是在性能问题和无限滚动的实现上有一点困难;然后我想过用RecyclerView来做横向的列表,但是在无限滚动和居中放大的实现上有一点困难;然后我考虑直接重写View来做,但是这样的风险和成本实在太高,我不能不负责任地把这种代码投放到实际项目中。最后想来想去,我觉得用ViewPager来实现是最稳妥的,虽然里面仍然有不少坑,不过都被我解决了。

3. 实现一个普通的ViewPager

这里实现一个最最最普通的ViewPager,一页一个Item,支持横向滑动:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />
</LinearLayout>

MainActivity.java

public class MainActivity extends Activity {
   

    private ViewPager viewPager;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        OnePageThreeItemAdapter adapter = new OnePageThreeItemAdapter(this);
        viewPager.setAdapter(adapter);
    }

}

OnePageThreeItemAdapter.java

public class OnePageThreeItemAdapter extends PagerAdapter {
   

    private Context context;
    private List<String> sourceData = new ArrayList<String>();

    public OnePageThreeItemAdapter(Context context) {
        this.context = context;
        initData();
    }

    /**
     * 初始化原始数据
     */
    public void initData(){
        sourceData.clear();
        for(int i = 0 ; i < 5; i++){
            sourceData.add(i + "");
        }
    }

    @Override
    public int getCount() {
        return sourceData.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    @Override
    public Object instantiateItem(ViewGroup container, final int position) {
        View view = View.inflate(context, R.layout.item, null);
        view.setTag(String.valueOf(position));
        TextView txt = (TextView) view.findViewById(R.id.txt);
        txt.setText(sourceData.get(position));
        container.addView(view);
        return view;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
    }
}

item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher" />

    <TextView
        android:id="@+id/txt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:gravity="center"
        android:textColor="@android:color/black"
        android:textSize="15sp" />

</LinearLayout>

4. 实现一屏三个View

这个功能网上已经有很多了,相信大家都已经看见过了,所以我也就简单得说一下

A. 首先ViewPager和包含ViewPager的ViewGroup设置clipChildren属性

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值