自定义View实现微信主页渐变效果

直入主题,先看图
最终效果图
下面看实现原理:
1.先是布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        >
    </android.support.v4.view.ViewPager>
<LinearLayout
    android:id="@+id/tab_ll"
    android:layout_width="match_parent"
    android:orientation="horizontal"
    android:layout_height="50dp">
    <com.android.tiancb.wxgradient.NavigationItemView
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        app:item_icon="@mipmap/ic_launcher"
        app:item_text="主页"
        app:item_text_size="12sp"
        />
    <com.android.tiancb.wxgradient.NavigationItemView
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        app:item_icon="@mipmap/ic_launcher"
        app:item_text="通讯录"
        app:item_text_size="12sp"
        />
    <com.android.tiancb.wxgradient.NavigationItemView
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        app:item_icon="@mipmap/ic_launcher"
        app:item_text="朋友圈"
        app:item_text_size="12sp"
        />
    <com.android.tiancb.wxgradient.NavigationItemView
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        app:item_icon="@mipmap/ic_launcher"
        app:item_text="我的"
        app:item_text_size="12sp"
        app:item_color="#00ff00"
        />
</LinearLayout>
</LinearLayout>

2.自定义属性文件

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="navigation_item">
        <attr name="item_icon" format="reference"/>
        <attr name="item_color" format="color"/>
        <attr name="item_text" format="string"/>
        <attr name="item_text_size" format="dimension"/>
    </declare-styleable>
</resources>

3.自定义view

package com.android.tiancb.wxgradient;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by tiancb on 16/1/14.
 */


public class NavigationItemView extends View {
    private String mText;
    private Bitmap mIcon;
    private int mColor = 0xFFff0000;//渐变的颜色
    private int mTextColor = 0x88000000;//字体颜色
    private float mTextSize;
    private Paint mTextPaint;
    private Rect mTextBounds;
    private Rect mIconRect;
    private Rect mTextRect;

    private float itemAlpha;

    public void setItemAlpha(float itemAlpha) {
        this.itemAlpha = itemAlpha;
        invalidate();
    }

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

    public NavigationItemView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initAttrs(context, attrs);
        initPaint();
        initTextRect();
    }

    public NavigationItemView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(context, attrs);
    }


    //初始化自定义属性
    private void initAttrs(Context context, AttributeSet attrs) {
        try {
            //这是一种方式   另一种是 监听系统布局文件的加载过程————framework层里面的方式
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.navigation_item);
            mText = typedArray.getString(R.styleable.navigation_item_item_text);
            BitmapDrawable bitmapDrawable = (BitmapDrawable) typedArray.getDrawable(R.styleable.navigation_item_item_icon);
            mIcon = bitmapDrawable.getBitmap();
            mColor = typedArray.getColor(R.styleable.navigation_item_item_color, 0xFFff0000);
            mTextSize = typedArray.getDimension(R.styleable.navigation_item_item_text_size, 10);
            typedArray.recycle();
        }catch (Exception e){
            e.printStackTrace();
        }

    }


    private void initPaint() {
        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setColor(mColor);
        mTextPaint.setTextSize(mTextSize);
    }

    //计算文字所在的位置(也就是我们文本的宽高)
    private void initTextRect() {
        mTextBounds = new Rect();
        mTextPaint.getTextBounds(mText, 0, mText.length(), mTextBounds);
    }
    //计算图片和文字载屏幕当中所在的区域

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        int bitmapWidth, bitmapHeight;
        bitmapWidth = bitmapHeight = (int) (h * 0.6);
        setIconRect(w, h, bitmapWidth, bitmapHeight);
        setTextRect(w, h, bitmapWidth, bitmapHeight);
    }

    //计算图片位置的区域
    private void setIconRect(int w, int h, int bitmapWidth, int bitmapHeight) {
        int left = (w - bitmapWidth) / 2;
        int right = left + bitmapWidth;
        int top = (h - bitmapHeight - mTextBounds.height()) / 2;
        int bottom = top + bitmapHeight;
        mIconRect = new Rect(left, top, right, bottom);
    }
    //计算文本位置区域
    private void setTextRect(int w, int h, int bitmapWidth, int bitmapHeight) {
        int textWidth = mTextBounds.width();
        int textHeight = mTextBounds.height();
        int left = (w - textWidth) / 2;
        int right = left + textWidth;
        int top = mIconRect.bottom;
        int bottom = top + textHeight;
        mTextRect = new Rect(left, top, right, bottom);
    }
    //绘制图片和文本

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 1.清空画板
        canvasClear(canvas);
        //2.绘制图片(绘制背景图片和绘制前景图片)
        canvasBitmaps(canvas);
        //3.绘制文字(绘制背景文本和绘制前景文本)
        canvasText(canvas);
    }
    private void canvasClear(Canvas canvas){
        canvas.drawBitmap(mIcon,null,mIconRect,null);

//        bgPaint.setTextAlign(Paint.Align.LEFT);
//        //设置画笔颜色
        mTextPaint.setColor(mTextColor);
        canvas.drawText(mText,getMeasuredWidth() / 2 - mTextBounds.width() / 2, mTextRect.bottom, mTextPaint);
    }
    private void canvasBitmaps(Canvas canvas){
        int alpha = (int) Math.ceil(255 * itemAlpha);
        //二级缓存 创建缓存图片(背景图)
        Bitmap mBgBitmap = Bitmap.createBitmap(getMeasuredWidth(),getMeasuredHeight(), Bitmap.Config.ARGB_8888);
        //缓存画布
        Canvas bgCanvas = new Canvas(mBgBitmap);
        // 创建画笔
        Paint bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        //设置画笔颜色
        bgPaint.setColor(mColor);
        //防抖动
        bgPaint.setDither(true);
        //设置绘制图片的透明度
        bgPaint.setAlpha(alpha);
        //绘制背景图片(绘制背景区域)
        bgCanvas.drawRect(mIconRect,bgPaint);
        //绘制前景图  设置图层覆盖类型
        bgPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        //恢复透明度
        bgPaint.setAlpha(255);
        bgCanvas.drawBitmap(mIcon,null,mIconRect,bgPaint);
        //最后将我们的缓存画布的内容绘制到当前的自定义的View的画布上面
        canvas.drawBitmap(mBgBitmap,0,0,null);
    }
    //绘制文本
    private void canvasText(Canvas canvas) {
        //文本叠加
        int alpha = (int) Math.ceil(255 * itemAlpha);
        mTextPaint.setColor(mColor);
        mTextPaint.setAlpha(alpha);
//        绘制背景图片(绘制背景区域)
        canvas.drawText(mText,getMeasuredWidth() / 2 - mTextBounds.width() / 2, mTextRect.bottom, mTextPaint);
    }
}

4.实现界面(主界面)

这里写代码片package com.android.tiancb.wxgradient;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.widget.LinearLayout;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends FragmentActivity {
    ViewPager viewPager ;
    LinearLayout linearLayout;
    List<TabFragment> fragments;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tab);
        viewPager = (ViewPager) findViewById(R.id.viewpager);
        linearLayout = (LinearLayout) findViewById(R.id.tab_ll);
        fragments = new ArrayList<>();
        List<String> titleList = new ArrayList<>();
        titleList.add("主页");
        titleList.add("通讯录");
        titleList.add("朋友圈");
        titleList.add("我的");
        for (String string : titleList){
            TabFragment tabFragment = new TabFragment();
            Bundle bundle = new Bundle();
            bundle.putString("title",string);
            tabFragment.setArguments(bundle);
            fragments.add(tabFragment);
        }
        NavigationAdaper navigationAdaper = new NavigationAdaper(getSupportFragmentManager());
        viewPager.setAdapter(navigationAdaper);
        viewPager.setCurrentItem(0);
        //初始化tab
        NavigationItemView leftView = (NavigationItemView) linearLayout.getChildAt(0);
        leftView.setItemAlpha(1);
//        viewPager.setOnPageChangeListener();用下面的方法代替
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                if (positionOffset > 0){
                    NavigationItemView leftView = (NavigationItemView) linearLayout.getChildAt(position);
                    leftView.setItemAlpha(1 - positionOffset);
                    NavigationItemView rightView = (NavigationItemView)linearLayout.getChildAt(position+1);
                    rightView.setItemAlpha(positionOffset);
                }
            }

            @Override
            public void onPageSelected(int position) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }
    private class NavigationAdaper extends FragmentPagerAdapter {
        public NavigationAdaper(FragmentManager fragmentManager){
            super(fragmentManager);
        };
        @Override
        public Fragment getItem(int position) {

            return fragments.get(position);
        }

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

5.另外还有个fragment界面

package com.android.tiancb.wxgradient;


import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

/**
 * Created by tiancb on 16/1/14.
 */
public class TabFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater,  ViewGroup container,  Bundle savedInstanceState) {
        TextView textView = new TextView(getActivity());
        String title = getArguments().getString("title");
        textView.setText(title);
        textView.setTextSize(50);
        textView.setTextColor(Color.BLACK);
        return textView;
    }
}

源码下载点这里

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章