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

根据上一篇ActionBar随ScorllView上下拖动而透明度渐变效果的基本描述,我们自定义的actionbar滚动透明的效果使用起来可能有点繁琐。这次想要在上次的代码内容上(可自动切换、无限滑动的图片广告展示栏的实现分享(续1)),博主太懒了,哈哈,实现这样的效果。

技术分享

这次的demo很简单,老样子,你可以自己下载demo稍微看看,结构如下:

技术分享

主界面代码:

package org.jan.adviewpaper.demo;

import android.app.ActionBar;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

import com.achep.header2actionbar.FadingActionBarHelper;
/**
 * demo 主界面
 * @author jan
 */
public class MainActivity extends Activity implements OnClickListener {

	private static final String TAG = "MainActivity";
	private ActionBar mActionBar;
	//这边的是ActionBar的辅助类,设置透明度在里面的干活!
	private FadingActionBarHelper mFadingActionBarHelper;
	private Button mSearchButton;
	//....

	@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);
		mSearchButton = (Button) mActionBar.getCustomView().findViewById(
				R.id.search_button);
		// 给搜索按钮添加点击事件
		mSearchButton.setOnClickListener(this);
		// 注意!定义Actionbar的背景色 ,这句不能忘记!
		mActionBar.getCustomView().setBackground(
				getResources().getDrawable(R.drawable.actionbar_bg));
		mFadingActionBarHelper = new FadingActionBarHelper(getActionBar(),
				getResources().getDrawable(R.drawable.actionbar_bg));
		if (savedInstanceState == null) {
			getFragmentManager().beginTransaction()
					.add(R.id.container_view, new MyViewFragment()).commit();
		}
	}

	public FadingActionBarHelper getFadingActionBarHelper() {
		return mFadingActionBarHelper;
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.search_button:
			Log.d(TAG, "你点击了搜索按钮!");
			Toast.makeText(this, "you clicked search", 1000).show();
			break;
		}
	}
}

必须继承这个抽象类来实现效果HeaderFragment.java:

public abstract class HeaderFragment extends Fragment {

    private static final String TAG = "HeaderFragment";

    public static final int HEADER_BACKGROUND_SCROLL_NORMAL = 0;
    public static final int HEADER_BACKGROUND_SCROLL_PARALLAX = 1;
    public static final int HEADER_BACKGROUND_SCROLL_STATIC = 2;
    //TODO header’s height 你可以改变他
    public static int headerHeight=350;
    private FrameLayout mFrameLayout;
    private View mContentOverlay;

    // header
    private View mHeader;
    private View mHeaderHeader;
    private View mHeaderBackground;
    private int mHeaderHeight;
    private int mHeaderScroll;

    private int mHeaderBackgroundScrollMode = HEADER_BACKGROUND_SCROLL_NORMAL;

    private Space mFakeHeader;
    private boolean isListViewEmpty;

    // listeners
    private AbsListView.OnScrollListener mOnScrollListener;
    private OnHeaderScrollChangedListener mOnHeaderScrollChangedListener;

    public interface OnHeaderScrollChangedListener {
        public void onHeaderScrollChanged(float progress, int height, int scroll);
    }

    public void setOnHeaderScrollChangedListener(OnHeaderScrollChangedListener listener) {
        mOnHeaderScrollChangedListener = listener;
    }

    public void setHeaderBackgroundScrollMode(int scrollMode) {
        mHeaderBackgroundScrollMode = scrollMode;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final Activity activity = getActivity();
        assert activity != null;
        mFrameLayout = new FrameLayout(activity);

        mHeader = onCreateHeaderView(inflater, mFrameLayout);
        mHeaderHeader = mHeader.findViewById(android.R.id.title);
//        mHeaderBackground = mHeader.findViewById(android.R.id.background);
        assert mHeader.getLayoutParams() != null;
//        mHeaderHeight = mHeader.getLayoutParams().height;
        View content = onCreateContentView(inflater, mFrameLayout);
        mHeaderHeight = headerHeight;
        mFakeHeader = new Space(activity);
        mFakeHeader.setLayoutParams(
                new ListView.LayoutParams(0, mHeaderHeight));
        mFakeHeader.setLayoutParams(
                new ListView.LayoutParams(0, 0));
        
        mHeaderBackground = content.findViewById(android.R.id.background);
        if (content instanceof ListView) {
            isListViewEmpty = true;

            final ListView listView = (ListView) content;
            listView.addHeaderView(mFakeHeader);
            listView.setOnScrollListener(new AbsListView.OnScrollListener() {

                @Override
                public void onScrollStateChanged(AbsListView absListView, int scrollState) {
                    if (mOnScrollListener != null) {
                        mOnScrollListener.onScrollStateChanged(absListView, scrollState);
                    }
                }

                @Override
                public void onScroll(AbsListView absListView, int firstVisibleItem,
                                     int visibleItemCount, int totalItemCount) {
                    if (mOnScrollListener != null) {
                        mOnScrollListener.onScroll(
                                absListView, firstVisibleItem, 
                                visibleItemCount, totalItemCount);
                    }
                    
                    if (isListViewEmpty) {
                        scrollHeaderTo(0);
                    } else {
                        final View child = absListView.getChildAt(0);
                        assert child != null;
                        scrollHeaderTo(child == mFakeHeader ? child.getTop() : -mHeaderHeight);
                    }
                }
            });
        } else {

            // Merge fake header view and content view.
            final LinearLayout view = new LinearLayout(activity);
            view.setLayoutParams(new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT));
            view.setOrientation(LinearLayout.VERTICAL);
            view.addView(mFakeHeader);
            view.addView(content);

            // Put merged content to ScrollView
            final NotifyingScrollView scrollView = new NotifyingScrollView(activity);
            scrollView.addView(view);
            scrollView.setOnScrollChangedListener(new NotifyingScrollView.OnScrollChangedListener() {
                @Override
                public void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt) {
                    scrollHeaderTo(-t);
                }
            });
            content = scrollView;
        }

        mFrameLayout.addView(content);
        mFrameLayout.addView(mHeader);

        // Content overlay view always shows at the top of content.
        if ((mContentOverlay = onCreateContentOverlayView(inflater, mFrameLayout)) != null) {
            mFrameLayout.addView(mContentOverlay, new FrameLayout.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT));
        }

        // Post initial scroll
        mFrameLayout.post(new Runnable() {
            @Override
            public void run() {
                scrollHeaderTo(0, true);
            }
        });

        return mFrameLayout;
    }

    private void scrollHeaderTo(int scrollTo) {
        scrollHeaderTo(scrollTo, false);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
	private void scrollHeaderTo(int scrollTo, boolean forceChange) {
        scrollTo = Math.min(Math.max(scrollTo, -mHeaderHeight), 0);
        if (mHeaderScroll == (mHeaderScroll = scrollTo) & !forceChange) return;

        setViewTranslationY(mHeader, scrollTo);
        setViewTranslationY(mHeaderHeader, -scrollTo);

        switch (mHeaderBackgroundScrollMode) {
            case HEADER_BACKGROUND_SCROLL_NORMAL:
                setViewTranslationY(mHeaderBackground, 0);
                break;
            case HEADER_BACKGROUND_SCROLL_PARALLAX:
                setViewTranslationY(mHeaderBackground, -scrollTo / 1.6f);
                break;
            case HEADER_BACKGROUND_SCROLL_STATIC:
                setViewTranslationY(mHeaderBackground, -scrollTo);
                break;
        }

        if (mContentOverlay != null) {
            final ViewGroup.LayoutParams lp = mContentOverlay.getLayoutParams();
            final int delta = mHeaderHeight + scrollTo;
            lp.height = mFrameLayout.getHeight() - delta;
            mContentOverlay.setLayoutParams(lp);
            mContentOverlay.setTranslationY(delta);
        }

        notifyOnHeaderScrollChangeListener(
                (float) -scrollTo / mHeaderHeight,
                mHeaderHeight,
                -scrollTo);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
	private void setViewTranslationY(View view, float translationY) {
        if (view != null) view.setTranslationY(translationY);
    }

    private void notifyOnHeaderScrollChangeListener(float progress, int height, int scroll) {
        if (mOnHeaderScrollChangedListener != null) {
            mOnHeaderScrollChangedListener.onHeaderScrollChanged(progress, height, scroll);
        }
    }

    public abstract View onCreateHeaderView(LayoutInflater inflater, ViewGroup container);

    public abstract View onCreateContentView(LayoutInflater inflater, ViewGroup container);

    public abstract View onCreateContentOverlayView(LayoutInflater inflater, ViewGroup container);

    public void setListViewAdapter(ListView listView, ListAdapter adapter) {
        isListViewEmpty = adapter == null;
        listView.setAdapter(null);
        listView.removeHeaderView(mFakeHeader);
        listView.addHeaderView(mFakeHeader);
        listView.setAdapter(adapter);
    }

    /**
     * {@inheritDoc AbsListView#setOnScrollChangedListener}
     */
    public void setListViewOnScrollChangedListener(AbsListView.OnScrollListener listener) {
        mOnScrollListener = listener;
    }

    // //////////////////////////////////////////
    // //////////// -- GETTERS -- ///////////////
    // //////////////////////////////////////////

    public View getHeaderView() {
        return mHeader;
    }

    public View getHeaderHeaderView() {
        return mHeaderHeader;
    }

    public View getHeaderBackgroundView() {
        return mHeaderBackground;
    }

    public int getHeaderBackgroundScrollMode() {
        return mHeaderBackgroundScrollMode;
    }

}
FadingActionBarHelper.java

public class FadingActionBarHelper {

    private static final String TAG = "FadingActionBarHelper";
    //默认的透明度最大值(255)
    private static final int MAX_ALPHA = 220;
    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 == MAX_ALPHA) {
            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);
				}
				//注意!这边是真正设置背景透明度的地方
				if(view.getBackground()!=null&&alpha<=MAX_ALPHA){	
					view.getBackground().setAlpha(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;
    }
}
我们主要内容MyViewFragment.java

public class MyViewFragment extends HeaderFragment {

    private FrameLayout mContentOverlay;
    private static final String TAG = "MyViewFragment";
    private static int PAGER_START_PLAY = 0x123;
	// 切换间隔时间3秒
	private static final int PLAY_TIME = 3 * 1000;
	// 实现viewpager的控件
	private JazzyViewPager mViewPaper;
	// 圆形标签的父层
	private LinearLayout symbolContainer;
	private ImageView[] images;
	private ImageView[] circleSymbols;
	private ArrayList<String> imageUrlList;
	// 图片框架universalimageloader的图形帮助类
	private ImageLoader mImageLoader;
	private Handler mHandler;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        setHeaderBackgroundScrollMode(HEADER_BACKGROUND_SCROLL_PARALLAX);
        //注意!这个是很屌的方法,用来改变actionbar的透明度
        setOnHeaderScrollChangedListener(new OnHeaderScrollChangedListener() {
            @Override
            public void onHeaderScrollChanged(float progress, int height, int scroll) {
                height -= getActivity().getActionBar().getHeight();
                progress = (float) scroll / height;
                if (progress > 1f) progress = 1f;
                progress = (1 - (float) Math.cos(progress * Math.PI)) * 0.5f;
                ((MainActivity) getActivity())
                        .getFadingActionBarHelper()
                        .setActionBarAlpha((int) (255 * progress));
            }
        });
		mImageLoader = ImageLoader.getInstance();
		initMockImages();

    }

    @Override
    public void onDetach() {
        super.onDetach();
    }

    @Override
    public View onCreateHeaderView(LayoutInflater inflater, ViewGroup container) {
        return inflater.inflate(R.layout.fragment_header, container, false);
    }

    @Override
    public View onCreateContentView(LayoutInflater inflater, ViewGroup container) {
        View view  =  inflater.inflate(R.layout.fragment_myview, container, false);
		setupMyHandler();
		initViews(view);
        return view;
    }

    @Override
    public View onCreateContentOverlayView(LayoutInflater inflater, ViewGroup container) {
//        ProgressBar progressBar = new ProgressBar(getActivity());
        mContentOverlay = new FrameLayout(getActivity());
//        mContentOverlay.addView(progressBar, new FrameLayout.LayoutParams(
//                ViewGroup.LayoutParams.WRAP_CONTENT,
//                ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
//        if (mLoaded) mContentOverlay.setVisibility(View.GONE);
        return mContentOverlay;
    }

    private void setupMyHandler() {
		mHandler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				if (PAGER_START_PLAY == msg.what) {
					Log.d(TAG, "----PAGER_START_PLAY-----");
					int current = mViewPaper.getCurrentItem();
					if (current == images.length - 1) {
						current = -1;
					}
					Log.d(TAG, "play item = " + current);
					mViewPaper.setCurrentItem(current + 1);
					mHandler.sendEmptyMessageDelayed(PAGER_START_PLAY,
							PLAY_TIME);
				}
			}
		};
	}

	private void initViews(View v) {
		symbolContainer = (LinearLayout) v.findViewById(R.id.symblo_container);
		circleSymbols = new ImageView[imageUrlList.size()];
		images = new ImageView[imageUrlList.size()];
		for (int i = 0; i < imageUrlList.size(); i++) {
			ImageView imageView = new ImageView(getActivity());
			ImageView circle = new ImageView(getActivity());
			imageView.setScaleType(ScaleType.CENTER_CROP);
			images[i] = imageView;
			LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
					LinearLayout.LayoutParams.WRAP_CONTENT,
					LinearLayout.LayoutParams.WRAP_CONTENT);
			lp.setMargins(3, 0, 3, 0);
			circle.setLayoutParams(lp);
			circle.setTag(i);
			circle.setBackgroundDrawable(getResources().getDrawable(
					R.drawable.circle_normal));
			circleSymbols[i] = circle;
			symbolContainer.addView(circleSymbols[i]);
		}
		setViewPager(v,TransitionEffect.Standard);
	}

	private void setViewPager(View v,TransitionEffect effect) {
		mViewPaper = (JazzyViewPager) v.findViewById(R.id.adviewpaper);
		mViewPaper.setTransitionEffect(effect);
		mViewPaper.setAdapter(new MyPagerAdapter());
		mViewPaper.setOnPageChangeListener(new MyPageViewChangeListener());
		mViewPaper.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (imageUrlList.size() == 0 || imageUrlList.size() == 1) {
					return true;
				} else {
					return false;
				}
			}
		});
		circleSymbols[0].setBackgroundDrawable(getResources().getDrawable(
				R.drawable.circle_selected));
		mViewPaper.setCurrentItem(0);
		mHandler.sendEmptyMessageDelayed(PAGER_START_PLAY, PLAY_TIME);
	}

	/**
	 * 创建本地图片数据
	 */
	private void initMockImages() {
		imageUrlList = new ArrayList<String>();
		imageUrlList.add("drawable://" + R.drawable.jd_ad_0);
		imageUrlList.add("drawable://" + R.drawable.jd_ad_1);
		imageUrlList.add("drawable://" + R.drawable.jd_ad_2);
		imageUrlList.add("drawable://" + R.drawable.jd_ad_3);
		imageUrlList.add("drawable://" + R.drawable.jd_ad_4);
	}

	/**
	 * 设置圆形标签的状态
	 * 
	 * @param index
	 *            当前标签的位置
	 */
	private void setSymbolImages(int index) {
		for (ImageView image : circleSymbols) {
			Integer i = (Integer) image.getTag();
			if (i == index) {
				image.setBackgroundDrawable(getResources().getDrawable(
						R.drawable.circle_selected));
			} else {
				image.setBackgroundDrawable(getResources().getDrawable(
						R.drawable.circle_normal));
			}
		}
	}
	private class MyPagerAdapter extends PagerAdapter {

		@Override
		public int getCount() {
			return imageUrlList.size();
		}

		@Override
		public boolean isViewFromObject(View view, Object obj) {
			if (view instanceof OutlineContainer) {
				return ((OutlineContainer) view).getChildAt(0) == obj;
			} else {
				return view == obj;
			}
		}

		@Override
		public void destroyItem(ViewGroup container, int position, Object object) {
			((ViewPager) container).removeView(mViewPaper
					.findViewFromObject(position));
		}

		@Override
		public Object instantiateItem(ViewGroup container, int position) {
			mImageLoader.displayImage(imageUrlList.get(position),
					images[position]);
			container.addView(images[position], LayoutParams.MATCH_PARENT,
					LayoutParams.MATCH_PARENT);
			final int index = position;
			images[position].setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					Log.e(TAG, "you clicked images position is" + index);
					Toast.makeText(getActivity(),
							"你点击了第" + (index + 1) + "张图", Toast.LENGTH_SHORT)
							.show();
				}
			});
			// 注意!不加这个方法要报IllegalStateException
			mViewPaper.setObjectForPosition(images[position], position);
			return images[position];
		}

	}

	private class MyPageViewChangeListener implements OnPageChangeListener {

		@Override
		public void onPageScrollStateChanged(int stateCode) {
			switch (stateCode) {
			case 0:
				// 你什么都没动
				break;
			case 1:
				// 正在滑动哦
				break;
			case 2:
				// 滑动完了
				break;
			}
		}

		@Override
		public void onPageScrolled(int arg0, float arg1, int arg2) {
		}

		@Override
		public void onPageSelected(int position) {
			Log.d(TAG, "onPageSelected-->position:" + position);
			setSymbolImages(position);
		}
	}

    
}
好了。demo的下载连接:点击打开链接




郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。