自定義View實現微信主頁漸變效果
阿新 • • 發佈:2019-02-13
直入主題,先看圖
下面看實現原理:
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;
}
}