您的位置:首页 > 移动开发 > Android开发

Android clipChildren与clipToPadding使用以及简单ViewPager自定义切换效果

2017-10-18 23:45 513 查看
首先看看我们要实现的效果:



主要希望实现两个效果:

1. 滚动的文本框在TITLE“下方“穿过,但初始时,文本框是有TITLE的高度的”paddingTop”的;

2. 下方第三个图标的高度超出其所在的父控件高度。

先上布局文件:

<?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:background="#f6f6f6"
android:clipChildren="false"
android:orientation="vertical">

<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"<
4000
/span>
android:layout_weight="1">

<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingTop="50dp">

<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="很长很长的文本\n很长很长的文本\n很长很长的文本\n很长很长的文本\n很长很长的文本\n很长很长的文本\n很长很长的文本\n很长很长的文本\n很长很长的文本\n很长很长的文本\n很长很长的文本\n很长很长的文本\n很长很长的文本\n"
android:textSize="50sp"/>
</ScrollView>

<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#a00058f1"
android:gravity="center"
android:text="TITLE"
android:textColor="#ffffffff"
android:textSize="20sp"/>
</FrameLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="bottom"
android:background="#fff"
android:elevation="12dp"
android:orientation="horizontal">

<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:src="@mipmap/ic_launcher"/>

<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:src="@mipmap/ic_launcher"/>

<ImageView
android:id="@+id/iv"
android:layout_width="0dp"
android:layout_height="180dp"
android:layout_gravity="bottom"
android:layout_weight="1"
android:scaleType="fitXY"
android:src="@mipmap/ic_launcher"/>

<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:src="@mipmap/ic_launcher"/>

<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:src="@mipmap/ic_launcher"/>
</LinearLayout>

</LinearLayout>


首先先引入两个属性:

1. android:clipChildren – 是否限制子视图在其范围内,简单理解,就是其子view是否可以在超出自身原本的范围绘制“突出”的部分,默认值为true。需要注意的是,突出的部分是没有响应事件的,如下图:



第三个图标虽然超出了LinearLayout的高度范围,但是点击超出的部分,是不会响应imageview的点击事件的。此属性一般需要在根节点设置。

2. android:clipToPadding – 这个就能比较简单理解了,是否允许子view在padding的范围中绘制,默认值为true。一般设置此属性为false,以实现如上图所示的,ListView、RecycleView、ScrollView的“初始padding”的效果。

clipToPadding和clipChildren 还可以配合Viewpager,实现各种酷炫的切换效果,如下面的例子:



布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff"
android:id="@+id/fl"
android:clickable="true"
android:clipChildren="false"
android:orientation="vertical">

<android.support.v4.view.ViewPager
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_gravity="center"
android:layout_marginLeft="60dp"
android:layout_marginRight="60dp"
android:background="#f6f6f6"
android:clipToPadding="false"
android:orientation="vertical"
android:overScrollMode="never"
android:paddingBottom="20dp"
android:paddingTop="20dp"/>
</FrameLayout>


中间灰色的部分是ViewPager,要实现此效果,需要ViewPager的父容器设置clipChildren为false以及自身设置clipToPadding为false,同时设置左右margin,以显示前后两页,同时需在代码中设置:

vp.setPageMargin(30);  // 设置页间的距离
vp.setOffscreenPageLimit(3); // 因为要同时显示三页,因此此处需要将默认的缓存页面从1变为3
vp.setPageTransformer(false, new PageAnimation()); // 自定义切换效果
vp.setAdapter(new Adapter());


其中,setPageTransformer是用来给ViewPager设置切换效果的,主要是重写

/**
* page - Apply the transformation to this page
* position - Position of page relative to the current front-and-center position of the pager. 0 is front and center. 1 is one full page position to the right, and -1 is one page position to the left.
*/
public void transformPage(View page, float position)


方法,page就是ViewPager中的单个页面,position指的是这个page在ViewPager中的当前位置。静止时,

当前选中的(一般是中央的)position是0,左边的是-1,右边的是1,以此类推。在手指向左滑动过程中,当前选中的page的position从0变为-1,这期间的position都会回调到这个方法,我们就可以利用这个做一系列的动画了,以下是上例的切换效果:

/**
* 切换动画
*/
class PageAnimation implements ViewPager.PageTransformer {
final float SCALE_MAX = 0.75f;
final float ALPHA_MAX = 0.5f;
final float MAX_Z = 12;

@Override
public void transformPage(View page, float position) {
float scale = (position < 0)
? ((1 - SCALE_MAX) * position + 1)
: ((SCALE_MAX - 1) * position + 1);
float alpha = (position < 0)
? ((1 - ALPHA_MAX) * position + 1)
: ((ALPHA_MAX - 1) * position + 1);
//为了滑动过程中,page间距不变,这里做了处理
if (position < 0) {
ViewCompat.setPivotX(page, page.getWidth());
ViewCompat.setPivotY(page, page.getHeight() / 2);
} else {
ViewCompat.setPivotX(page, 0);
ViewCompat.setPivotY(page, page.getHeight() / 2);
}
ViewCompat.setScaleX(page, scale);
ViewCompat.setScaleY(page, scale);
ViewCompat.setAlpha(page, Math.abs(alpha));

// 阴影
ViewCompat.setElevation(page, MAX_Z * Math.abs(alpha));
}
}


完整代码可参见此处
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: