QQ空间5.0的ActionBar会随着滚动的距离让ActionBar的透明度发生变化,效果还是非常cool,自己实现了一个小demo,基本实现了上面的所说的效果,但是其他控件的事件监听以及一系列较为复杂的控件的冲突还没考虑,暂时来总结下。
1,实现思路:
在最外层包裹一个自定义的FadingScrollView,监听滑动事件,然后去滚动控件,不过滚动范围只是最上面的fadingView的高度减去actionBar的高度,然后根据已经滚动的距离和fadingView的height来改变actionbar的透明度。还有一点注意让actionBar悬停在contentView之上。
package huwei.com.fadingactionbardemo;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.v7.app.ActionBar;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageView;
import android.widget.LinearLayout;
/**
* Created by huwei on 15-1-31.
*/
public class FadingScrollView extends LinearLayout {
private static String TAG = "FadingScrollView";
private ActionBar mActionBar;
private Drawable mBgDrawable;
private ImageView fadingBar;
private int fadingHeight; //可隐藏的控件高度
private int oldY;
private int fadingOffset;
public static final int ALPHA_START=20;
public static final int ALPHA_END=255;
public FadingScrollView(Context context) {
this(context, null);
}
public FadingScrollView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FadingScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setOrientation(VERTICAL);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
fadingBar = (ImageView) findViewById(R.id.fading_bar);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
fadingHeight = fadingBar.getMeasuredHeight()-fadingOffset;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
oldY = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
int scrollY = getScrollY();
Log.i(TAG, "scrollY:" + scrollY + " ;-fadingHeight" + fadingHeight);
int y = (int) ev.getY();
int deltaY = y - oldY;
int willScrollY = scrollY - deltaY;
if (willScrollY > fadingHeight) {
willScrollY = fadingHeight;
}
if (willScrollY < 0) {
willScrollY = 0;
}
scrollTo(0, willScrollY);
updateActionBarAlpha(willScrollY*(ALPHA_END-ALPHA_START)/fadingHeight+ALPHA_START);
oldY = y;
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
public void bindingActionBar(ActionBar actionBar) {
mActionBar = actionBar;
}
public void setActionBarBgDrawable(Drawable bgDrawable) throws Exception{
if(mActionBar==null){
throw new Exception("Please try to binding the actionBar before set it's background.");
}
mBgDrawable = bgDrawable;
mBgDrawable.setAlpha(ALPHA_START);
mActionBar.setBackgroundDrawable(mBgDrawable);
}
public void setActionBarAlpha(int alpha) throws Exception{
if(mActionBar==null||mBgDrawable==null){
throw new Exception("acitonBar is not binding or bgDrawable is not set.");
}
mBgDrawable.setAlpha(alpha);
mActionBar.setBackgroundDrawable(mBgDrawable);
}
void updateActionBarAlpha(int alpha){
try {
setActionBarAlpha(alpha);
} catch (Exception e) {
e.printStackTrace();
}
}
public void setFadingOffset(int height){
fadingOffset=height;
}
}
2,让ActionBar悬停。
1)代码实现:
RequestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
2)自定义样式
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
<!-- Customize your theme here. -->
<item name="windowActionBarOverlay">true</item>
</style>
3,改变透明度
设置背景的Drawable的透明度即可,比如:
mBgDrawable.setAlpha(ALPHA_START);
mActionBar.setBackgroundDrawable(mBgDrawable);