自定义之类微信底部渐变栏

废话不多说,先看效果:
效果
记得微信刚出来时,他的这个渐变效果还是惊艳到我的。现在网上也有很多微信渐变栏的例子,我看过都是利用Paint的Xfermode来实现的。但是我看过微信apk里头,他的两张(选中与非选中)图片都是有的。所以我以前按照自己的思路写了一个,这段时间整理代码时,把他整理出来了。
要说我实现的原理,其实挺简单的,就是两种图都有,一个变淡,一个变深。

每个小块:

/**
 * 渐变子模块
 * Created by fcp on 2015/9/22.
 */
public class GradualChangeView extends View {
    //选中图片
    private Bitmap bitmapSelect;
    //未选中图片
    private Bitmap bitmapUnselect;
    //限制绘制icon的范围
    private Rect mIconRect  = new Rect();
    //底部文字
    private String mText;
    //文字转变色
    private int mColor = 0x45C01A;//未选
    private int sColor = 0x555555;//选中
    //文本大小
    private int mTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 10, getResources().getDisplayMetrics());
    //文本区域
    private Rect mTextBound = new Rect();
    //画笔
    private Paint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
    private Paint bitmapPaint = new Paint();

    /**
     * 透明度 0.0-1.0
     */
    private float mAlpha = 0f;


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

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

    public GradualChangeView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context, attrs);
    }


    /**
     * 初始化布局
     * @param context Context
     * @param attrs AttributeSet
     */
    private void initView(Context context, AttributeSet attrs) {

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.GradualChangeBar);
        for (int i = 0; i < typedArray.getIndexCount(); i++) {
            int attr = typedArray.getIndex(i);
            switch (attr) {
                case R.styleable.GradualChangeBar_grad_icon_top_selected:
                    BitmapDrawable bitmapDrawable = (BitmapDrawable) typedArray.getDrawable(attr);
                    if(bitmapDrawable != null) bitmapSelect = bitmapDrawable.getBitmap();
                    break;
                case R.styleable.GradualChangeBar_grad_icon_top_unselect:
                    BitmapDrawable bitmapDrawable1 = (BitmapDrawable) typedArray.getDrawable(attr);
                    if(bitmapDrawable1 != null) bitmapUnselect = bitmapDrawable1.getBitmap();
                    break;
                case R.styleable.GradualChangeBar_grad_text_bottom:
                    mText = typedArray.getString(attr);
                    break;
                case R.styleable.GradualChangeBar_grad_text_size:
                    mTextSize = (int) typedArray.getDimension(attr, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                            10, getResources().getDisplayMetrics()));
                    break;
                case R.styleable.GradualChangeBar_grad_text_color:
                    mColor = typedArray.getColor(attr , 0x45C01A);
                    break;
            }
        }
        typedArray.recycle();

        mTextPaint.setTextSize(mTextSize);
        mTextPaint.setColor(sColor);//初始颜色
        // 得到text绘制范围
        mTextPaint.getTextBounds(mText, 0, mText.length(), mTextBound);
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // 得到绘制icon的宽
        //int bitmapWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
        int bitmapHeight = (int)((getMeasuredHeight() - getPaddingTop() - getPaddingBottom() - mTextBound.height()) *0.8);//乘0.8只是让图片更小,整体更居中
        int bitmapWidth = bitmapHeight * bitmapSelect.getWidth() / bitmapSelect.getHeight() ;
        int left = ( getMeasuredWidth() - bitmapWidth ) / 2;
        int top =( getMeasuredHeight() - mTextBound.height() - bitmapHeight) / 2;
        // 设置icon的绘制范围
        mIconRect.set(left, top, left + bitmapWidth, top + bitmapHeight);
    }



    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int alpha = (int) Math.ceil((255 * mAlpha));
        //if(alpha!=255){
            //绘制未选中图标
            bitmapPaint.setAlpha(255 - alpha);
            canvas.drawBitmap(bitmapUnselect, null, mIconRect, bitmapPaint);
            //绘制未选中文本
            mTextPaint.setColor(sColor);
            mTextPaint.setAlpha(255 - alpha);
            canvas.drawText(mText, mIconRect.left + (mIconRect.width() - mTextBound.width()) / 2,
                    mIconRect.bottom +  mTextBound.height() , mTextPaint);
        //}

        //if(alpha!=0){
            //绘制选中图标
            bitmapPaint.setAlpha(alpha);
            canvas.drawBitmap(bitmapSelect, null, mIconRect, bitmapPaint);
            //绘制选中文本
            mTextPaint.setColor(mColor);
            mTextPaint.setAlpha( alpha);
            canvas.drawText(mText, mIconRect.left + (mIconRect.width() - mTextBound.width()) / 2,
                    mIconRect.bottom  +  mTextBound.height() , mTextPaint);
        //}

    }


    public void setIconAlpha(float alpha) {
        this.mAlpha = alpha;
        if (Looper.getMainLooper() == Looper.myLooper()) {
            invalidate();
        } else {
            postInvalidate();
        }
    }

    private static final String INSTANCE_STATE = "instance_state";
    private static final String STATE_ALPHA = "state_alpha";

    @Override
    protected Parcelable onSaveInstanceState() {
        Bundle bundle = new Bundle();
        bundle.putParcelable(INSTANCE_STATE, super.onSaveInstanceState());
        bundle.putFloat(STATE_ALPHA, mAlpha);
        return bundle;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (state instanceof Bundle) {
            Bundle bundle = (Bundle) state;
            mAlpha = bundle.getFloat(STATE_ALPHA);
            super.onRestoreInstanceState(bundle.getParcelable(INSTANCE_STATE));
        } else {
            super.onRestoreInstanceState(state);
        }
    }


}

整个bar类:

/**
 * 渐变导航栏
 * Created by fcp on 2015/9/22.
 */
public class GradualChangeBar extends LinearLayout implements View.OnClickListener,ViewPager.OnPageChangeListener{

    private GradualChangeView one;
    private GradualChangeView two;
    private GradualChangeView three;
    private GradualChangeView four;

    private ArrayList<GradualChangeView> mGradualChangeViews =new ArrayList<>();

    private ViewPager viewPager;
    private OnSelectIdChanged mOnSelectIdChanged;

    private int selectId;


    public GradualChangeBar(Context context) {
        super(context);
        init(context);
    }

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

    public GradualChangeBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }


    private void init(Context context){
        setOrientation(LinearLayout.HORIZONTAL);
        setBackgroundResource(R.drawable.layer_list_graduallchangebar);
        LayoutInflater inflater = LayoutInflater.from(context);
        inflater.inflate(R.layout.activity_app_main_graduallbar, this);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        one = (GradualChangeView) findViewById(R.id.activity_app_main_gradual_bar_one);
        two = (GradualChangeView) findViewById(R.id.activity_app_main_gradual_bar_two);
        three = (GradualChangeView) findViewById(R.id.activity_app_main_gradual_bar_three);
        four = (GradualChangeView) findViewById(R.id.activity_app_main_gradual_bar_four);

        mGradualChangeViews.add(one);
        mGradualChangeViews.add(two);
        mGradualChangeViews.add(three);
        mGradualChangeViews.add(four);

        one.setOnClickListener(this);
        two.setOnClickListener(this);
        three.setOnClickListener(this);
        four.setOnClickListener(this);

    }


    /**
     * 设置ViewPager
     * @param viewPager ViewPager
     */
    public void setViewPager(ViewPager viewPager, OnSelectIdChanged onSelectIdChanged) {
        this.viewPager = viewPager;
        this.mOnSelectIdChanged = onSelectIdChanged;
        //初始化第一项
        viewPager.setCurrentItem(0,false);
        one.setIconAlpha(1);
        two.setIconAlpha(0);
        three.setIconAlpha(0);
        four.setIconAlpha(0);
        selectId = one.getId();
        //监听
        viewPager.addOnPageChangeListener(this);
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if(id == selectId){
            return ;
        }
        selectId = id;
        switch (id){
            case R.id.activity_app_main_gradual_bar_one:
                one.setIconAlpha(1);
                two.setIconAlpha(0);
                three.setIconAlpha(0);
                four.setIconAlpha(0);
                viewPager.setCurrentItem(0,false);
                if(mOnSelectIdChanged !=null) mOnSelectIdChanged.selectOne();
                break;
            case R.id.activity_app_main_gradual_bar_two:
                one.setIconAlpha(0);
                two.setIconAlpha(1);
                three.setIconAlpha(0);
                four.setIconAlpha(0);
                viewPager.setCurrentItem(1, false);
                if(mOnSelectIdChanged !=null) mOnSelectIdChanged.selectTwo();
                break;
            case R.id.activity_app_main_gradual_bar_three:
                one.setIconAlpha(0);
                two.setIconAlpha(0);
                three.setIconAlpha(1);
                four.setIconAlpha(0);
                viewPager.setCurrentItem(2, false);
                if(mOnSelectIdChanged !=null) mOnSelectIdChanged.selectThree();
                break;
            case R.id.activity_app_main_gradual_bar_four:
                one.setIconAlpha(0);
                two.setIconAlpha(0);
                three.setIconAlpha(0);
                four.setIconAlpha(1);
                viewPager.setCurrentItem(3, false);
                if(mOnSelectIdChanged !=null) mOnSelectIdChanged.selectFour();
                break;

        }
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if (positionOffset > 0) {
            GradualChangeView left = mGradualChangeViews.get(position);
            GradualChangeView right = mGradualChangeViews.get(position + 1);
            left.setIconAlpha(1 - positionOffset);
            right.setIconAlpha(positionOffset);
        }
    }

    @Override
    public void onPageSelected(int position) {
        selectId = mGradualChangeViews.get(position).getId();
        switch (position){
            case 0:
                if(mOnSelectIdChanged !=null) mOnSelectIdChanged.selectOne();
                break;
            case 1:
                if(mOnSelectIdChanged !=null) mOnSelectIdChanged.selectTwo();
                break;
            case 2:
                if(mOnSelectIdChanged !=null) mOnSelectIdChanged.selectThree();
                break;
            case 3:
                if(mOnSelectIdChanged !=null) mOnSelectIdChanged.selectFour();
                break;
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }

    public interface OnSelectIdChanged {
        void selectOne();
        void selectTwo();
        void selectThree();
        void selectFour();
    }


}

布局:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bar="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.fcp.gradual.view.GradualChangeView
        android:id="@+id/activity_app_main_gradual_bar_one"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:padding="@dimen/grad_view_padding"
        bar:grad_icon_top_selected="@mipmap/ic_grad_store_selected"
        bar:grad_icon_top_unselect= "@mipmap/ic_grad_store_unselect"
        bar:grad_text_bottom="@string/fragment_store_text"
        bar:grad_text_size="@dimen/grad_view_text_size"
        bar:grad_text_color="@color/grad_view_text_color"/>

    <com.fcp.gradual.view.GradualChangeView
        android:id="@+id/activity_app_main_gradual_bar_two"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:padding="@dimen/grad_view_padding"
        bar:grad_icon_top_selected="@mipmap/ic_grad_activity_selected"
        bar:grad_icon_top_unselect= "@mipmap/ic_grad_activity_unselect"
        bar:grad_text_bottom="@string/fragment_activity_text"
        bar:grad_text_size="@dimen/grad_view_text_size"
        bar:grad_text_color="@color/grad_view_text_color" />

    <com.fcp.gradual.view.GradualChangeView
        android:id="@+id/activity_app_main_gradual_bar_three"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:padding="@dimen/grad_view_padding"
        bar:grad_icon_top_selected="@mipmap/ic_grad_message_selected"
        bar:grad_icon_top_unselect= "@mipmap/ic_grad_message_unselect"
        bar:grad_text_bottom="@string/fragment_message_text"
        bar:grad_text_size="@dimen/grad_view_text_size"
        bar:grad_text_color="@color/grad_view_text_color"/>


    <com.fcp.gradual.view.GradualChangeView
        android:id="@+id/activity_app_main_gradual_bar_four"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:padding="@dimen/grad_view_padding"
        bar:grad_icon_top_selected="@mipmap/ic_grad_mine_selected"
        bar:grad_icon_top_unselect= "@mipmap/ic_grad_mine_unselect"
        bar:grad_text_bottom="@string/fragment_mine_text"
        bar:grad_text_size="@dimen/grad_view_text_size"
        bar:grad_text_color="@color/grad_view_text_color"/>


</merge>

完整代码:
https://github.com/fcp12138/Gradual

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值