我经常阅读简书,能在其中获取很多有意思的知识,今天就想来实现以下简书首页动态搜索展开、收起的效果,觉得很有意思,当然了网上也有很多前辈们实现了这一功能,我也只是自己练习以下而已
先看效果图:本来想录个视频,发现还没弄明白怎么整就来看图把,把几幅图动态联系就来就是最终实现的效果图了
一、分析实现思路:
这个效果就是在内容区上下滑动的过程中,动态改变搜索部分的背景色,搜索填充区的宽度和提示语
1、 首先利用ScrollView嵌套ListView作为内容区,通过获取ScrollView的Y轴方向的距离,计算搜索部分的背景透明度
2、 要有一个计算透明度比率的参照物,我把内容区滑动的距离和搜索区的高度变化来做为参照物
3、设置透明度和搜索区的控件宽度即可
二、代码实现
1、重写ScrollView,获取滑动距离
public class VScrollView extends ScrollView {
//实现滑动监听获取滑动的距离
private onScrollListener onScrollChangeListener;
public VScrollView(Context context) {
super(context);
}
public VScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public onScrollListener getOnScrollChangeListener() {
return onScrollChangeListener;
}
public void setScrollChangeListener(onScrollListener onScrollChangeListener) {
this.onScrollChangeListener = onScrollChangeListener;
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public VScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (onScrollChangeListener != null) {
onScrollChangeListener.OnScrollChanged(l, t, oldl, oldt);
}
}
public interface onScrollListener {
void OnScrollChanged(int x, int y, int oldx, int oldy);
}
}
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="#ffffff"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/rl_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffff00">
<EditText
android:id="@+id/et_search"
android:layout_width="45dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_margin="10dp"
android:background="@drawable/search_background"
android:gravity="center"
android:hint="搜索"
android:padding="5dp"
android:singleLine="true"
android:textColor="#bcadad"
android:textColorHint="#999191"
android:textSize="13sp" />
</RelativeLayout>
<ImageView
android:id="@+id/iv_img"
android:layout_width="match_parent"
android:layout_height="240dp"
android:background="#ff0000"
android:src="@mipmap/ic_launcher" />
<com.liulije.myfilterdemo.VScrollView
android:id="@+id/scrollview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/lv_list"
android:layout_width="match_parent"
android:layout_height="3000dp"
android:background="#9ad27a"></ListView>
</RelativeLayout>
</com.liulije.myfilterdemo.VScrollView>
</LinearLayout>
3、activity中代码如下
a、声明控件(先把rl_rearch的背景透明度设为0)
b、给控件添加监听,获取搜索EditText控件的宽度,参照对比高度控件ImageView的宽高(用来计算透明度和设置搜索控件的最大宽度,也可以用viewPager等代替)
rl_search.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//用来计算透明度
searchHeight = rl_search.getHeight();
}
});
iv_img.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//用来计算透明度和et_search的宽度
imageHeight = iv_img.getHeight();
imgwidht = iv_img.getWidth();
}
});
et_search.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (tvWidth == 0) {
//et_search的宽度最小值
tvWidth = et_search.getWidth();
}
}
});
c、scrollview实现onScrollListener监听器(核心代码)
scrollview.setScrollChangeListener(new VScrollView.onScrollListener() {
@Override
public void OnScrollChanged(int x, int y, int oldx, int oldy) {
Log.w(TAG, "OnScrollChanged: " + x + "***" + y + "***" + oldx + "***" + oldy);
float changeHeight = imageHeight - searchHeight;
//透明度变化率
int alpha = (int) (((float) y / changeHeight) * 255);
ViewGroup.LayoutParams params = et_search.getLayoutParams();
if (alpha >= 255) {
alpha = 255;
params.width += imgwidht;
} else if (alpha > 20 && alpha < 255) {
if (oldy < y) {
params.width += 20;
} else {
params.width -= 20;
}
} else {
alpha = 0;
params.width = tvWidth;
}
Log.w(TAG, "OnScrollChanged: alpha" + alpha);
rl_search.getBackground().setAlpha(alpha);
if (params.width >= imgwidht) {
params.width = imgwidht;
et_search.setHint("搜索简书的内容和朋友");
}
if (params.width <= tvWidth) {
params.width = tvWidth;
et_search.setHint("搜索");
}
//设置新的参数
et_search.setLayoutParams(params);
}
});
就能实现简书app的搜索效果了。
感谢http://www.jianshu.com/p/51918b355150作者给我的思路,本来想不写来着,不过作者实现的功能过度不够平滑,我就修改了一下只是记录学习一下
当然了除了这个方法,还可以使用动画来实现可参考这个,http://www.jb51.net/article/116797.htm