[Android UI]ActionBar随ScorllView上下拖动而透明度渐变效果

我看到越来越多的应用使用这样的效果,如QQ空间5.0的主界面,确实很好看!大概就搜了一下相关的实现方式,发现早就有了相关的方案:

仿QQ空间滚动ActionBar透明度变化Demo

还有我在github上看到就有这样的实现方式,这也是本博文的主要核心内容:

具体请查看:https://github.com/AChep/Header2ActionBar

效果如下:


这是Demo结构:


1.FadingActionBarHelper.java 这个类是处理Actionbar的核心类,处理对scroll事件对actionbar背景色alpha的处理。

public class FadingActionBarHelper {

    private static final String TAG = "FadingActionBarHelper";

    private int mAlpha = 255;
    private Drawable mDrawable;
    private boolean isAlphaLocked;

    private final ActionBar mActionBar;

    public FadingActionBarHelper(final ActionBar actionBar) {
        mActionBar = actionBar;
    }

    public FadingActionBarHelper(final ActionBar actionBar, final Drawable drawable) {
        mActionBar = actionBar;
        setActionBarBackgroundDrawable(drawable);
    }

    public void setActionBarBackgroundDrawable(Drawable drawable) {
        setActionBarBackgroundDrawable(drawable, true);
    }

    @TargetApi(Build.VERSION_CODES.KITKAT)
	public void setActionBarBackgroundDrawable(Drawable drawable, boolean mutate) {
        mDrawable = mutate ? drawable.mutate() : drawable;
        mActionBar.setBackgroundDrawable(mDrawable);
        if (mAlpha == 255) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
                mAlpha = mDrawable.getAlpha();
        } else {
            setActionBarAlpha(mAlpha);
        }
    }

    /**
     * An {@link android.app.ActionBar} background drawable.
     *
     * @see #setActionBarBackgroundDrawable(android.graphics.drawable.Drawable)
     * @see #setActionBarAlpha(int)
     */
    public Drawable getActionBarBackgroundDrawable() {
        return mDrawable;
    }

    /**
     * Please use this method for global changes only!
     * This is helpful when you need to provide something like
     * Navigation drawer: lock ActionBar and set
     * {@link android.graphics.drawable.Drawable#setAlpha(int)}
     * to {@link #getActionBarBackgroundDrawable()} directly.
     *
     * @param alpha a value from 0 to 255
     * @see #getActionBarBackgroundDrawable()
     * @see #getActionBarAlpha()
     */
    public void setActionBarAlpha(int alpha) {
        if (mDrawable == null) {
            Log.w(TAG, "Set action bar background before setting the alpha level!");
            return;
        }
        if (!isAlphaLocked) {
			mDrawable.setAlpha(alpha);
			View view = mActionBar.getCustomView();
			if(view!=null){
				//这里是对自定义actionbar背景的处理,我这边就草草了事了
				if(alpha>=55){
					view.findViewById(R.id.search_button).setBackgroundResource(R.drawable.search);
					view.findViewById(R.id.refresh_button).setBackgroundResource(R.drawable.refresh);
				}else{
					view.findViewById(R.id.search_button).setBackgroundResource(R.drawable.skin_nav_icon_l_search_rev);
					view.findViewById(R.id.refresh_button).setBackgroundResource(R.drawable.skin_nav_icon_r_refresh_rev);
				}
				Log.i(TAG, "search_button.alpha=>"+alpha);
			}
		}
        mAlpha = alpha;
    }

    public int getActionBarAlpha() {
        return mAlpha;
    }

    /**
     * When ActionBar's alpha is locked {@link #setActionBarAlpha(int)}
     * won't change drawable\'s alpha (but will change {@link #getActionBarAlpha()} level)
     *
     * @param lock
     */
    public void setActionBarAlphaLocked(boolean lock) {

        // Update alpha level on unlock
        if (isAlphaLocked != (isAlphaLocked = lock) && !isAlphaLocked) {
            setActionBarAlpha(mAlpha);
        }
    }

    public boolean isActionBarAlphaLocked() {
        return isAlphaLocked;
    }
}

2.其他的组件类我这不copy了,有兴趣的朋友自行下载github上的项目吧o(∩_∩)o。

public class NotifyingScrollView extends ScrollView {
    // Edge-effects don't mix well with the translucent action bar in Android 2.X
    private boolean mDisableEdgeEffects = true;

    /**
     * @author Cyril Mottier
     */
    public interface OnScrollChangedListener {
        void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt);
    }

    private OnScrollChangedListener mOnScrollChangedListener;

    public NotifyingScrollView(Context context) {
        super(context);
    }

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

    public NotifyingScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (mOnScrollChangedListener != null) {
            mOnScrollChangedListener.onScrollChanged(this, l, t, oldl, oldt);
        }
    }

    public void setOnScrollChangedListener(OnScrollChangedListener listener) {
        mOnScrollChangedListener = listener;
    }

    @Override
    protected float getTopFadingEdgeStrength() {
        // http://stackoverflow.com/a/6894270/244576
        if (mDisableEdgeEffects && Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            return 0.0f;
        }
        return super.getTopFadingEdgeStrength();
    }

    @Override
    protected float getBottomFadingEdgeStrength() {
        // http://stackoverflow.com/a/6894270/244576
        if (mDisableEdgeEffects && Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            return 0.0f;
        }
        return super.getBottomFadingEdgeStrength();
    }
}


3.对于普通的java程序员来说,你可以不知道怎么个原理,但是你一定要知道怎么运用它,如何运用到我们的实际项目中并且改造它,这是demo的主界面,用起来就几行代码,是不是很叼?

public class MainActivity extends Activity {

    private FadingActionBarHelper mFadingActionBarHelper;
    private ActionBar mActionBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mActionBar = getActionBar();
        //使用自定义的布局的ActionBar
        mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
        mActionBar.setCustomView(R.layout.my_actionbar);
        //定义白色为Actionbar的背景色
        mFadingActionBarHelper = new FadingActionBarHelper(getActionBar(),
                getResources().getDrawable(R.drawable.actionbar_bg));

        if (savedInstanceState == null) {
            getFragmentManager().beginTransaction()
                    .add(R.id.container, new ListViewFragment())
                    .commit();
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        
        // Inflate the menu; this adds items to the action bar if it is present.
    	//菜单页面碍于效果,即被隐藏
//        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        return super.onOptionsItemSelected(item);
    }
    
    //这段代码可不要忘了
    public FadingActionBarHelper getFadingActionBarHelper() {
        return mFadingActionBarHelper;
    }
}

贴了主要的代码,其实这个实现方式还是有点复杂的,我想应该还有更简洁的方式吧,有的话请留言分享!分享代码是技术圈进步的一种有效方式哦!


----------------------------------------------------------

最后是Demo的下载链接,有兴趣的请自行下载,开如意门


  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
FadingActionBar 仿美团上拉背景渐变,默认背景透明,下拉bar完全隐藏  。开发者使用此依赖,只需要2个方法就可以实现美团外卖中上拉titlebar背景渐变,下拉titlebar隐藏效果效果图:准备工作:1.注意actionbar的依赖库,目前仅支持import android.app.ActionBar;2.actionbar背景渐变需要监听headerview的位置,放在添加headerview后调用该方法     private void initScroll() {         //设置动态改变         mlistview.setOnScrollListener(new AbsListView.OnScrollListener() {             @Override             public void onScrollStateChanged(AbsListView view, int scrollState) {             }             @Override             public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {                 // [0]代表x坐标,location [1] 代表y坐标。                 int[] location = new int[2];                 // 实时设置actionbar透明度,监听header位置(必须是移除屏幕会产生负数的view)                 llheaderview.getLocationInWindow(location);                 helper.setActionBarAlpha(location[1] - XMSettings.getStatusBarHeight(mContext));                 Log.i("tag", "onScroll: "   (location[1] - XMSettings.getStatusBarHeight(mContext)));             }         });      }3.注意activity对应的theme添加属性<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">      <item name="android:windowActionBarOverlay">true</item>      <item name="android:windowContentOverlay">@null</item> </style>使用1.添加Gradle依赖dependencies {     compile 'com.github.ximencx.fadeactionbar:library:1.0.1'     }2.activity中获取actionbar对象,初始化XMFadeBarHelper类    private void initbar() {         //获取actionbar对象         mActionBar = getActionBar();         mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);         mActionBar.setCustomView(R.layout.ab_title);         /**          * actionbar辅助类          * parameter1:action对象          * parameter2:acitonbar背景          * parameter3:初始透明度          */         helper = new XMFadeBarHelper(mActionBar, getResources().getDrawable(R.drawable.bg_actionbar), 0) {             /**              * 设置需要隐藏view透明度              * 注意:是否设置background的区别              *              * @param customView  actionbar布局对象              * @param alpha 回调的alpha              */             @Override             public void setViewAlpha(View customView, int alpha) {                 ButterKnife.findById(customView, R.id.tv_info).setAlpha(alpha);                 ButterKnife.findById(customView, R.id.rl_bg).getBackground().setAlpha(alpha);             }             /**              * 设置隐藏速度              * 默认返回actionbar布局的高度,当然也可以以其它view为参照物              * @param customView actionbar布局              * @return              */             @Override             public int setHeight(View customView) {                 return customView.getHeight();             }         };     }3.listview的监听中调用helper.setActionBarAlpha(),注意减去状态栏的高度    private void initScroll() {         //设置动态改变         mlistview.setOnScrollListener(new AbsListView.OnScrollListener() {             @Override             public void onScrollStateChanged(AbsListView view, int scrollState) {             }             @Override             public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {                 // [0]代表x坐标,location [1] 代表y坐标。                 int[] location = new int[2];                 // 实时设置actionbar透明度,监听header位置(必须是移除屏幕会产生负数的view)                 llheaderview.getLocationInWindow(location);                 helper.setActionBarAlpha(location[1] - XMSettings.getStatusBarHeight(mContext));                 Log.i("tag", "onScroll: "   (location[1] - XMSettings.getStatusBarHeight(mContext)));             }         });      }sample中使用到的第三方库:BGAAdapterBGARefreshLayout-Android

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值