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

Android控件显示/隐藏时添加动画:ViewSwitcher

2016-12-22 14:52 399 查看
需求描述:整个页面有一个头布局和内容显示布局,头布局会根据下面内容区域的上下滑动来隐藏或显示(隐藏或显示时均有动画)。

内容布局可以是任何可以上下滑动的布局。当头布局隐藏时,整个页面都要可以显示内容,所以内容布局高度需match_parent。



实现思路:

1.将头布局用ViewSwitcher(ViewSwitcher最多两个子View)包裹,另外在ViewSwitcher中添加一个高度为0dp的布局跟这个头布局进行交替显示。

@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
if (getChildCount() >= 2) {
throw new IllegalStateException("Can't add more than 2 views to a ViewSwitcher");
}
super.addView(child, index, params);
}


2.可以在ViewSwitcher中设置动画。

3.内容布局设置滚动监听,根据上下滑动的偏移量来控制ViewSwitcher具体显示哪个子View。

代码实现:

布局文件

<?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.support.v7.widget.RecyclerView
android:id="@+id/rv_movie"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

<com.example.customview.MyViewSwitcher
android:id="@+id/viewswitch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/head"
android:inAnimation="@anim/slide_in_top"
android:outAnimation="@anim/slide_out_top"
android:persistentDrawingCache="animation">

<LinearLayout
android:id="@+id/ll_head"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@color/white"
android:gravity="center">

<TextView
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="6dp"
android:paddingTop="6dp"
android:textColor="@color/colorTitle2"
android:textSize="@dimen/text_size_14"
android:text="头布局" />

</LinearLayout>

<!--高度为0的空布局-->
<View
android:layout_width="match_parent"
android:layout_height="0dp" />

</com.example.customview.MyViewSwitcher>

</RelativeLayout>


动画文件

slide_in_top.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:fromYDelta="-100%p"
android:interpolator="@android:anim/decelerate_interpolator"
android:toYDelta="0" />


slide_out_top.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:fromYDelta="0"
android:interpolator="@android:anim/accelerate_interpolator"
android:toYDelta="-100%p" />


自定义ViewSwitcher:MyViewSwitcher

在MyViewSwitcher中封装了具体显示哪个子View的方法

public class MyViewSwitcher extends ViewSwitcher {

/**
* 真正的头布局
*/
private View firstChildView;

/**
* 高度为0的空布局
*/
private View secondChildView;

private static final int DELTA = 400;//根据具体情况设置值的大小

/**
* y方向偏移量总和
*/
private int DY = 0;

public MyViewSwitcher(Context context) {
this(context, null);
}

public MyViewSwitcher(Context context, AttributeSet attrs) {
super(context, attrs);
}

@Override
protected void onFinishInflate() {
super.onFinishInflate();

firstChildView = getChildAt(0);
secondChildView = getChildAt(1);
}

/**
* 根据外部传入的y值来设置显示哪个子View
* 如果向上滑动了好几页,突然想回到头布局时,只需向下滑动DELTA偏移即可显示头布局(语言功底差,描述不到位,相信大家都懂)
*
* @param delta
*/
public void whichOneShow(int delta) {
DY += delta;

//向上滑动
//当y偏移量总和大于DELTA,且第一个子View显示时,设置第二个子View显示
if (DY > DELTA && firstChildView.getVisibility() == VISIBLE) {
DY = 0;
setDisplayedChild(1);
} else if (DY > 0 && secondChildView.getVisibility() == VISIBLE) {
//继续向上滑动,且第二个子View一直处于显示状态,则将偏移量总和置零
DY = 0;
}

//向下滑动
//当y偏移量总和大于DELTA(即小于[-DELTA]),且第二个子View显示时,设置第一个子View显示
if (DY < -DELTA && secondChildView.getVisibility() == VISIBLE) {
DY = 0;
setDisplayedChild(0);
} else if (DY < 0 && firstChildView.getVisibility() == VISIBLE) {
//继续向下滑动,且第一个子View一直处于显示状态,则将偏移量总和置零
DY = 0;
}
}
}


MainActivity

public class MainActivity extends AppCompatActivity{

private RecyclerView mRecyclerView;

private MyViewSwitcher mViewSwitch;

@Override
public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
setContentView(R.layout.activity_search_movie);
initViews();
}

protected void initViews() {

mRecyclerView = (RecyclerView) findViewById(R.id.rv_movie);
mViewSwitch = (MyViewSwitcher) findViewById(R.id.viewswitch);

//RecyclerView设置数据部分代码省略
//...

//根据RecyclerView在竖直方向滑动的偏移量来控制头布局显示/隐藏
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);

mViewSwitch.whichOneShow(dy);
}
});

}
}


如有错误或不足之处,欢迎指正。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 布局 动画