android 自定义view局部刷新,GitHub - hongri-xiao/GraceViewPager: 1.支持ViewPager按需添加、删除视图,以及局部刷新; 2.修复多场景下Vie...

GraceViewPager

68747470733a2f2f6170692e62696e747261792e636f6d2f7061636b616765732f7772732f6d6176656e2f47726163655669657750616765722f696d616765732f646f776e6c6f61642e737667

背景

ViewPager在实际项目使用过程中,出现数据刷新使用姿势不正确、动画偏移、动态修改width、paddingLeft、paddingRight、pageMargin导致当前page滚动位置定位异常。于是通过源码分析,解决这些问题,并对使用场景进行了封装。

可以通过下面的文章了解ViewPager为何会出现这些问题以及对应的解决方案:

简介

可实现如下效果:

c92f6f2db09418de83fcfcea201220da.gif

主要功能

支持ViewPager按需添加、删除视图,以及局部刷新;

修复多场景下ViewPager.PageTransformer返回的position错误,让开发者专注于动画实现;

修复ViewPager的width、paddingLeft、paddingRight、pageMargin动态改变导致当前page滚动位置定位异常的问题;

提供自定义的ViewPager:GraceViewPager,可快速实现一屏显示多Page的功能。

使用方式

build.gradle添加依赖:

// 确保仓库已添加jcenter()

allprojects {

repositories {

...

jcenter()

}

}

// 添加依赖

dependencies {

compile 'com.lancewu:graceviewpager:'

}

请替换为对应的版本号。

1.直接使用GraceViewPager

推荐直接使用GraceViewPager来替代ViewPager,在布局中直接使用:

android:id="@+id/vp"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@color/colorAccent"

app:gvp_pageHorizontalMinMargin="50dp"

app:gvp_pageHeightWidthRatio="2"

app:gvp_pageVerticalMinMargin="50dp" />

自定义属性说明:

自定义属性

说明

gvp_pageHeightWidthRatio

page高宽比例值:如2,代表page的 高:宽=2:1,负数和0表示不需要按照比例

gvp_pageHorizontalMinMargin

page水平最小边距,指显示page与ViewPager水平方向间的最小间距;当按比例设定时,高度可能不足以容纳,此时就要缩小宽度,增加间距,即最后的padding值会大于该设定值

gvp_pageVerticalMinMargin

page垂直最小边距,指显示page与ViewPager垂直方向间的最小间距; 当按比例设定时,宽度可能不足以容纳,此时就要缩小高度,增加间距,即最后的padding值会大于该设定值

继承GracePagerAdapter,声明了泛型来表示item的实体类型:

private class Adapter extends GracePagerAdapter {

Adapter(@NonNull List items) {

super(items);

}

@NonNull

@Override

protected View instantiateItemView(@NonNull ViewGroup container, String item, int position) {

return getLayoutInflater().inflate(R.layout.page_item, container, false);

}

@Override

protected void bindItemView(@NonNull View itemView, String item, int position, boolean first) {

TextView tv = itemView.findViewById(R.id.tv);

tv.setText(item);

}

}

把GracePagerAdapter实例设置给GraceViewPager:

mViewPager.setGraceAdapter(mAdapter);

添加页面切换动画,只需要继承GracePageTransformer:

private class Transformer extends GracePageTransformer {

private static final float SCALE = 0.9f;

Transformer(@NonNull GracePagerAdapter pagerAdapter) {

super(pagerAdapter);

}

@Override

public void transformPageWithCorrectPosition(@NonNull View page, float position) {

if (position >= -1 && position <= 1) {

// [-1,1],中间以及相邻的页面,一般相邻的才会用于计算动画

float scale = SCALE + (1 - SCALE) * (1 - Math.abs(position));

page.setScaleX(scale);

page.setScaleY(scale);

} else {

// [-Infinity,-1)、(1,+Infinity],超出相邻的范围

page.setScaleX(SCALE);

page.setScaleY(SCALE);

}

}

}

然后给GraceViewPager设置动画:

mViewPager.setGracePageTransformer(false, new Transformer(mAdapter));

如果需要动态修改相关属性,也提供了对应的API:

// 动态修改比例

mViewPager.setPageHeightWidthRatio(ratio);

// 动态修改水平最小间距

mViewPager.setPageHorizontalMinMargin(horizontalMinMargin);

// 动态修改垂直最小间距

mViewPager.setPageVerticalMinMargin(verticalMinMargin);

// 修改pageMargin,请使用如下修正过滚动位置的方法

mViewPager.setGracePageMargin(pageMargin);

2.给ViewPager添加支持

如果不便于用GraceViewPager替换掉项目中已有的ViewPager,也提供对应的支持方式。

添加一屏多页支持

支持对已有的ViewPager进行一屏多页的支持,首先去除布局中的padding属性:

android:id="@+id/vp"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@color/colorAccent" />

代码中创建一屏多页插件实例GraceMultiPagePlugin,并给ViewPager添加插件支持:

GraceMultiPagePlugin mMultiPagePlugin;

// 添加一屏多页支持

mMultiPagePlugin = new GraceMultiPagePlugin.Builder(mViewPager)

.pageHeightWidthRatio(2f)

.pageHorizontalMinMargin(dip2px(50))

.pageVerticalMinMargin(dip2px(50))

.build();

GraceViewPagerSupport.supportMultiPage(mViewPager, mMultiPagePlugin);

同时支持动态修改属性:

// 修改比例

mMultiPagePlugin.setPageHeightWidthRatio(ratio);

// 修改水平最小间距

mMultiPagePlugin.setPageHorizontalMinMargin(horizontalMinMargin);

// 修改垂直最小间距

mMultiPagePlugin.setPageVerticalMinMargin(verticalMinMargin);

添加布局变化后滚动位置修正

// 添加布局变化支持修复滚动

GraceViewPagerSupport.supportLayoutChange(mViewPager);

添加动态修改pageMargin后滚动位置修正

// 动态修改pageMargin时使用该方法

GraceViewPagerSupport.setPageMargin(mViewPager, pageMargin);

添加按需创建、销毁视图和动态刷新视图的PagerAdapter

private class Adapter extends GracePagerAdapter {

Adapter(@NonNull List items) {

super(items);

}

@NonNull

@Override

protected View instantiateItemView(@NonNull ViewGroup container, String item, int position) {

return getLayoutInflater().inflate(R.layout.page_item, container, false);

}

@Override

protected void bindItemView(@NonNull View itemView, String item, int position, boolean first) {

TextView tv = itemView.findViewById(R.id.tv);

tv.setText(item);

}

}

使用修正的页面切换动画,专注于动画本身的实现

需要配合GracePagerAdapter使用:

private class Transformer extends GracePageTransformer {

private static final float SCALE = 0.9f;

Transformer(@NonNull GracePagerAdapter pagerAdapter) {

super(pagerAdapter);

}

@Override

public void transformPageWithCorrectPosition(@NonNull View page, float position) {

if (position >= -1 && position <= 1) {

// [-1,1],中间以及相邻的页面,一般相邻的才会用于计算动画

float scale = SCALE + (1 - SCALE) * (1 - Math.abs(position));

page.setScaleX(scale);

page.setScaleY(scale);

} else {

// [-Infinity,-1)、(1,+Infinity],超出相邻的范围

page.setScaleX(SCALE);

page.setScaleY(SCALE);

}

}

}

Change Log

License

Copyright 2018 LanceWu

Licensed under the Apache License, Version 2.0 (the "License");

you may not use this file except in compliance with the License.

You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software

distributed under the License is distributed on an "AS IS" BASIS,

WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

See the License for the specific language governing permissions and

limitations under the License.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值