android 微信布局 字体,【Android】底部Tab+ViewPager(仿微信界面)

感谢 github的作者:wuyexiong

效果图(图片和文字都有渐变效果)

AAffA0nNPuCLAAAAAElFTkSuQmCC

实现

AAffA0nNPuCLAAAAAElFTkSuQmCC


主要用到自定义一个LinearLayout和ImageView

1.BottomIconView继承自ImageView

BottomIconView的作用是现在Tab中的图标,有根据滑动的偏移值显示渐变的图标。

package jfsl.view.view;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.Rect;

import android.util.AttributeSet;

import android.widget.ImageView;

/**

* 底部Tab图标类,

* 分正常的状态和选中的状态

* 根据滑动的偏移量改变alpha值

* 然后显示出来

*

* 感谢 wuyexiong

* Created by wuyexiong on 4/25/15.

* Modify by JFSL on 2016-11-20 20:05

*/

public class BottomIconView extends ImageView

{

public static final int START_POSITION = 0;

public static final int ALPHA_MAX = 255;

//画笔

private Paint mPaint;

//选中时的图标

private Bitmap mIconSelected;

//未选中时的图标

private Bitmap mIconNormal;

//选中时的矩形(限制绘制范围)

private Rect mRectSelected;

//未选中时的矩形(限制绘制范围)

private Rect mRectNormal;

//当前的alpha值

private int mAlphaCurrent = 0;

public BottomIconView(Context context)

{

super(context);

}

public BottomIconView(Context context,AttributeSet attrs)

{

super(context,attrs);

}

public BottomIconView(Context context,AttributeSet attrs,int defStyleAttr)

{

super(context,attrs,defStyleAttr);

}

/**

* 初始化

*

* @param normal 正常图标的id

* @param selected 选中的图标的id

*/

public final void init(int normal,int selected) throws Exception

{

mIconNormal = createBitmap(normal);

mIconSelected = createBitmap(selected);

//创建不了图片

if(mIconNormal == null || mIconSelected == null)

throw new Exception("icon id can not create1 bitmap");

//根据创建的位图创建对应的矩形

mRectNormal = new Rect(START_POSITION,START_POSITION,mIconNormal.getWidth(),mIconNormal.getHeight());

mRectSelected = new Rect(START_POSITION,START_POSITION,mIconSelected.getWidth(),mIconSelected.getHeight());

//画笔只要实例化就行,没有什么要求

mPaint = new Paint(1);

}

/**

* 根据资源id创建的位图

*

* @param resId 资源id

* @return 创建的位图

*/

private Bitmap createBitmap(int resId)

{

return BitmapFactory.decodeResource(getResources(),resId);

}

@Override

protected void onDraw(Canvas canvas)

{

super.onDraw(canvas);

//画笔为空,直接返回

if(mPaint == null)

return;

//设置当前选中图标的alpha值(逐渐减少)

mPaint.setAlpha(ALPHA_MAX - mAlphaCurrent);

canvas.drawBitmap(mIconNormal,null,mRectNormal,mPaint);

//设置目标图标的alpha值(逐渐减增大)

mPaint.setAlpha(mAlphaCurrent);

canvas.drawBitmap(mIconSelected,null,mRectSelected,mPaint);

}

/**

* 改变alpha值

*

* @param alpha

*/

public final void changeSelectedAlpha(int alpha)

{

mAlphaCurrent = alpha;

invalidate();

}

/**

* ViewPager切换时用到

*

* @param offset 偏移量

*/

public final void transformPage(float offset)

{

changeSelectedAlpha((int)(ALPHA_MAX * (1 - offset)));

}

}

2.底部Tab(BottomIndicator继承自LinearLayout)

package jfsl.view.view;

import android.animation.ArgbEvaluator;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.support.v4.view.PagerAdapter;

import android.support.v4.view.ViewPager;

import android.util.AttributeSet;

import android.view.LayoutInflater;

import android.view.View;

import android.widget.LinearLayout;

import android.widget.TextView;

import jfsl.view.R;

/**

* 底部指示器

* Github上的例子,拿来修改了下

* Created by wuyexiong on 4/25/15.

* @version 1.0

* @aduthor JFSL

* @date 2016/11/14

*/

public class BottomIndicator extends LinearLayout

{

public static final int ICON_INDEX_NORMAL = 0;

public static final int ICON_INDEX_SELECTED = 1;

public static final int DEFALUT_SELECTED_ITEM = 0;

public static final String COLOR_TEXT_NORMAL = "#FF999999";

public static final String COLOR_TEXT_SELECTED = "#FF46C01B";

//文字颜色渐变类

private ArgbEvaluator mColorEvaluator;

//正常文本的颜色

private int mTextNormalColor;

//选中时文本的颜色

private int mTextSelectedColor;

//最后的位置

private int mLastPosition;

//选中的位置

private int mSelectedPosition;

//选择的偏移量

private float mSelectionOffset;

//底部tab文本

private String mTitles[] = {"微信","通讯录","发现","我"};

//对应的图标

private int mIconRes[][] = {

{R.drawable.icon_main_home_normal,R.drawable.icon_main_home_selected},

{R.drawable.icon_main_category_normal,R.drawable.icon_main_category_selected},

{R.drawable.icon_main_service_normal,R.drawable.icon_main_service_selected},

{R.drawable.icon_main_mine_normal,R.drawable.icon_main_mine_selected}};

//Item数组

private View[] mItemLayout;

//关联的ViewPager

private ViewPager mViewPager;

public BottomIndicator(Context context)

{

this(context,null);

}

public BottomIndicator(Context context,AttributeSet attrs)

{

this(context,attrs,0);

}

public BottomIndicator(Context context,AttributeSet attrs,int defStyleAttr)

{

super(context,attrs,defStyleAttr);

//初始化

init();

}

/**

* 初始化

*/

private void init()

{

//实例化颜色渐变类

mColorEvaluator = new ArgbEvaluator();

//选中和未选中的文本的颜色

mTextNormalColor = Color.parseColor(COLOR_TEXT_NORMAL);

mTextSelectedColor = Color.parseColor(COLOR_TEXT_SELECTED);

}

public void setViewPager(ViewPager viewPager)

{

//清空所有的view

removeAllViews();

mViewPager = viewPager;

//viewapger数据不为空

if(viewPager != null && viewPager.getAdapter() != null)

{

//设置监听

viewPager.addOnPageChangeListener(new ViewPagerListener());

try

{

populateTabLayout();

}catch(Exception e)

{

e.printStackTrace();

}

}

}

/**

* 生成底部tab

*/

private void populateTabLayout() throws Exception

{

final PagerAdapter adapter = mViewPager.getAdapter();

final OnClickListener tabClickListener = new TabClickListener();

//根据adapter中item 的数量生成数组

mItemLayout = new View[ adapter.getCount() ];

//遍历

for(int i = 0;i < adapter.getCount();i++)

{

final View tabView = LayoutInflater.from(getContext()).inflate(R.layout.item_bottom_tab,this,false);

//找不到对应的布局

if(tabView == null)

throw new IllegalStateException("tabView is null.");

mItemLayout[ i ] = tabView;

//图标

BottomIconView iconView = (BottomIconView)tabView.findViewById(R.id.bottom_tab_icon);

iconView.init(mIconRes[ i ][ ICON_INDEX_NORMAL ],mIconRes[ i ][ ICON_INDEX_SELECTED ]);

//文字

TextView textView = (TextView)tabView.findViewById(R.id.bottom_tab_text);

textView.setText(mTitles[ i ]);

//改变宽度和权重 item平分屏幕

LayoutParams lp = (LayoutParams)tabView.getLayoutParams();

lp.width = 0;

lp.weight = 1;

tabView.setOnClickListener(tabClickListener);

addView(tabView);

if(i == mViewPager.getCurrentItem())

{

iconView.transformPage(DEFALUT_SELECTED_ITEM);

tabView.setSelected(true);

textView.setTextColor(mTextSelectedColor);

}

}

}

/**

* 内部ViewPager监听

* 外面想监听,自定义一个

*/

private class ViewPagerListener implements ViewPager.OnPageChangeListener

{

//状态

private int mScrollState;

@Override

public void onPageScrolled(int position,float positionOffset,int positionOffsetPixels)

{

onViewPagerPageChanged(position,positionOffset);

}

@Override

public void onPageSelected(int position)

{

for(int i = 0;i < getChildCount();i++)

{

//图标

BottomIconView bottomIcon = ((BottomIconView)mItemLayout[ i ].findViewById(R.id.bottom_tab_icon));

bottomIcon.transformPage(position == i ? 0 : 1);

//文本

TextView bottomText = ((TextView)mItemLayout[ i ].findViewById(R.id.bottom_tab_text));

bottomText.setTextColor(position == i ? mTextSelectedColor : mTextNormalColor);

}

if(mScrollState == ViewPager.SCROLL_STATE_IDLE)

{

onViewPagerPageChanged(position,0f);

}

//设置选中项

for(int i = 0, size = getChildCount();i < size;i++)

{

getChildAt(i).setSelected(position == i);

}

}

@Override

public void onPageScrollStateChanged(int state)

{

mScrollState = state;

}

}

/**

* ViewPager的item改变

*

* @param position

* @param positionOffset

*/

private void onViewPagerPageChanged(int position,float positionOffset)

{

mSelectedPosition = position;

mSelectionOffset = positionOffset;

if(positionOffset == 0f && mLastPosition != mSelectedPosition)

{

mLastPosition = mSelectedPosition;

}

invalidate();

}

/**

* 绘制方法

*

* @param canvas

*/

@Override

protected void onDraw(Canvas canvas)

{

super.onDraw(canvas);

final int childCount = getChildCount();

if(childCount > 0)

{

if(mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1))

{

View selectedTab = getChildAt(mSelectedPosition);

View nextTab = getChildAt(mSelectedPosition + 1);

View selectedIconView = ((LinearLayout)selectedTab).getChildAt(0);

View nextIconView = ((LinearLayout)nextTab).getChildAt(0);

View selectedTextView = ((LinearLayout)selectedTab).getChildAt(1);

View nextTextView = ((LinearLayout)nextTab).getChildAt(1);

//draw icon alpha

if(selectedIconView instanceof BottomIconView && nextIconView instanceof BottomIconView)

{

((BottomIconView)selectedIconView).transformPage(mSelectionOffset);

((BottomIconView)nextIconView).transformPage(1 - mSelectionOffset);

}

/**

* 使用ArgbEvaluator类来控制文本的颜色渐变

*/

//draw text color

Integer selectedColor = (Integer)mColorEvaluator.evaluate(mSelectionOffset,

mTextSelectedColor,

mTextNormalColor);

Integer nextColor = (Integer)mColorEvaluator.evaluate(1 - mSelectionOffset,

mTextSelectedColor,

mTextNormalColor);

if(selectedTextView instanceof TextView && nextTextView instanceof TextView)

{

((TextView)selectedTextView).setTextColor(selectedColor);

((TextView)nextTextView).setTextColor(nextColor);

}

}

}

}

/**

* Tab的Item点击

*/

private class TabClickListener implements OnClickListener

{

@Override

public void onClick(View v)

{

for(int i = 0;i < getChildCount();i++)

{

if(v == getChildAt(i))

{

mViewPager.setCurrentItem(i,false);

return;

}

}

}

}

}

3.主布局(ViewPager+BottomIndicator)

android:orientation="vertical"

android:layout_width="match_parent"

android:layout_height="match_parent">

android:id="@+id/id_viewPager"

android:layout_width="match_parent"

android:layout_height="0dp"

android:layout_weight="1">

android:id="@+id/id_bottom_indicator"

android:layout_width="match_parent"

android:layout_height="56dp"

android:background="@drawable/bg_tab_bottom">

4.tab item的布局(BottomIconView+TextView)

android:layout_width="match_parent"

android:layout_height="match_parent"

android:gravity="center"

android:background="@null"

android:orientation="vertical">

android:id="@+id/bottom_tab_icon"

android:layout_width="32dp"

android:layout_height="28dp"

android:layout_gravity="center_horizontal"

android:scaleType="fitCenter" />

android:id="@+id/bottom_tab_text"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:gravity="center_horizontal"

android:textSize="12sp" />

5.Tab的背景 layer-list可以将多个图片按照顺序层叠起来

背景不能去掉,去掉之后看不到渐变的效果

android:dither="true"

android:shape="rectangle">

android:dither="true"

android:shape="rectangle">

6.测试的Activity

package jfsl.view;

import android.os.Bundle;

import android.support.v4.app.FragmentPagerAdapter;

import android.support.v4.view.ViewPager;

import android.support.v7.app.AppCompatActivity;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

import jfsl.view.adapter.TopViewPagerAdapter;

import jfsl.view.fragment.SimpleFragment;

import jfsl.view.view.BottomIndicator;

public class MainActivity extends AppCompatActivity

{

private ViewPager mViewPager;

private List mTitles = Arrays.asList("Fragment-->微信","Fragment-->通讯录","Fragment-->发现","Fragment-->我");

private List mFragments = new ArrayList<>();

private FragmentPagerAdapter mPagerAdapter;

private BottomIndicator mIndicator;

@Override

protected void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_bottom_tab);

initViews();

initDatas();

initEvent();

}

private void initViews()

{

mViewPager = (ViewPager)findViewById(R.id.id_viewPager);

mIndicator = (BottomIndicator)findViewById(R.id.id_bottom_indicator);

}

private void initDatas()

{

for(String title : mTitles)

{

mFragments.add(SimpleFragment.newInstance(title));

}

mPagerAdapter = new TopViewPagerAdapter(getSupportFragmentManager(),this,mFragments);

mViewPager.setAdapter(mPagerAdapter);

mIndicator.setViewPager(mViewPager);

}

private void initEvent()

{

}

}

7.adapter(ViewPager的Adapter)

package jfsl.view.adapter;

import android.content.Context;

import android.support.v4.app.Fragment;

import android.support.v4.app.FragmentManager;

import android.support.v4.app.FragmentPagerAdapter;

import java.util.List;

import jfsl.view.fragment.SimpleFragment;

/**

* @version 1.0

* @aduthor JFSL

* @date 2016/11/12 0012

*/

public class TopViewPagerAdapter extends FragmentPagerAdapter

{

private Context mContext;

private List mFragments;

public TopViewPagerAdapter(FragmentManager fm,Context context,List fragments)

{

super(fm);

mContext = context;

mFragments = fragments;

}

@Override

public Fragment getItem(int position)

{

return mFragments.get(position);

}

@Override

public int getCount()

{

return mFragments.size();

}

}

8.创建Fragment(根据String创建一个简单的Fragment)

package jfsl.view.fragment;

import android.os.Bundle;

import android.support.annotation.Nullable;

import android.support.v4.app.Fragment;

import android.view.Gravity;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.TextView;

/**测试用的Fragment

* @version 1.0

* @aduthor JFSL

* @date 2016/11/12 0012

*/

public class SimpleFragment extends Fragment

{

public static final String BUNDLE_TITLE = "title";

private String mTitle;

@Nullable

@Override

public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState)

{

Bundle bundle = getArguments();

if(bundle != null)

mTitle = bundle.getString(BUNDLE_TITLE);

TextView textView = new TextView(getActivity());

textView.setText(mTitle);

textView.setGravity(Gravity.CENTER);

return textView;

}

/**

* 获取实例

* @param title

* @return

*/

public static SimpleFragment newInstance(String title)

{

Bundle bundle = new Bundle();

bundle.putString(BUNDLE_TITLE,title);

SimpleFragment fragment = new SimpleFragment();

fragment.setArguments(bundle);

return fragment;

}

}

图标素材( 放在xxhdpi)

AAffA0nNPuCLAAAAAElFTkSuQmCC

AAffA0nNPuCLAAAAAElFTkSuQmCC

AAffA0nNPuCLAAAAAElFTkSuQmCC

AAffA0nNPuCLAAAAAElFTkSuQmCC

AAffA0nNPuCLAAAAAElFTkSuQmCC

AAffA0nNPuCLAAAAAElFTkSuQmCC

AAffA0nNPuCLAAAAAElFTkSuQmCC

AAffA0nNPuCLAAAAAElFTkSuQmCC

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值