android开发之高仿微信6.0+滑动Tab
来源:互联网 发布:魔女之泉3 知乎 编辑:程序博客网 时间:2024/06/06 02:37
上篇博文【android开发之Fragment利用Bundle保存状态】用到滑动切换底部Tab,由于上篇博文的重点是保存Fragment状态,并没有说明,今天来解释一下。
关于高仿微信6.0滑动Tab网上有很多,大部分情况下是自定义View,在OnDraw()进行绘制,本博客的Tab没有自定义View,只是android官方提供的控件进行组合【查看微信布局源码也是这样做的】,性能和实用性请各位同学自测。
微信布局如下图:
按着微信布局进行分析,每个Tab就是一个RelativeLayout,那么我们就可以继承RelativeLayout,添加子控件ImageView和Textview;由于需要实现滑动变色,所以实现双层ImageView和TextView,分别设置绿色图标和灰色图标;
自定义属性attrs.xml:
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="WeiXinTabLayoutStyleable"> <attr name="tabChecked" format="boolean" /> <attr name="tabTitle" format="string" /> <attr name="tabTitleSize" format="dimension" /> <attr name="tabTitleColor" format="color" /> <attr name="tabIcon" format="reference" /> <attr name="tabIconOver" format="reference" /> <attr name="tabLableColor" format="color" /> <attr name="tabLableText" format="string" /> <attr name="tabLableTextSize" format="dimension" /> <attr name="tabLablebackground" format="color"/></declare-styleable></resources>
代码以及讲解如下:
package cc.mn.tab;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Color;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.widget.ImageView;import android.widget.RelativeLayout;import android.widget.TextView;/** * User: 山野书生(1203596603@qq.com) * Date: 2015-11-27 * Time: 19:32 * Version 1.0 */public class TabView extends RelativeLayout{ private Context mContext; //标题 private TextView titleTextView; private String titleText; private int titleColor; private static final int titleTextViewID = 10001; private int titleNolColor = Color.GRAY; //第二层标题 private TextView titleOverTextView; private static final int titleOverTextViewID = 100011; //图标 private ImageView iconImageView; private static final int iconImageViewID = 10002; private Drawable tabIcon; //第二层图标 private ImageView iconOverImageView; private static final int iconOverImageViewID = 100022; private Drawable tabIconOver; //是否已经被选中 private boolean isChecked = true; //透明度 private float mAlpha = 1f; private String tag = TabView.class.getSimpleName(); public TabView(Context context) { this(context, null); } public TabView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public TabView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //获取自定义属性 TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.WeiXinTabLayoutStyleable); //是否是选中状态 isChecked = ta.getBoolean(R.styleable.WeiXinTabLayoutStyleable_tabChecked, false); //标题的颜色,内容 titleColor = ta.getColor(R.styleable.WeiXinTabLayoutStyleable_tabTitleColor, Color.GRAY); titleText = ta.getString(R.styleable.WeiXinTabLayoutStyleable_tabTitle); //图标图片 tabIcon = ta.getDrawable(R.styleable.WeiXinTabLayoutStyleable_tabIcon); tabIconOver = ta.getDrawable(R.styleable.WeiXinTabLayoutStyleable_tabIconOver); ta.recycle(); mContext = context; initViews(); } /** * 初始化控件 * */ private void initViews(){ RelativeLayout.LayoutParams titleLayoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); titleLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); titleLayoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE); //第二层标题 titleOverTextView = new TextView(mContext); titleOverTextView.setId(titleOverTextViewID); titleOverTextView.setLayoutParams(titleLayoutParams); this.addView(titleOverTextView); //标题 titleTextView = new TextView(mContext); titleTextView.setId(titleTextViewID); titleTextView.setLayoutParams(titleLayoutParams); this.addView(titleTextView); //图标LayoutParams RelativeLayout.LayoutParams iconLayoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); iconLayoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE); iconLayoutParams.addRule(RelativeLayout.ABOVE, titleTextViewID); //第二层图标 iconOverImageView = new ImageView(mContext); iconOverImageView.setId(iconOverImageViewID); iconOverImageView.setLayoutParams(iconLayoutParams); this.addView(iconOverImageView); //图标 iconImageView = new ImageView(mContext); iconImageView.setId(iconImageViewID); iconImageView.setLayoutParams(iconLayoutParams); this.addView(iconImageView); //设置数据,并刷新 refreshData(); } /** * 设置选中状态 * */ public void setChecked(boolean isChecked) { this.isChecked = isChecked; setCheckedData(); } /** * 滑动时改变颜色 * */ public void onScrolling(float alpha){ mAlpha = alpha; onScrollSetData(); } /** * 设置图标 * */ private void setTabIconData(){ iconImageView.setImageDrawable(tabIcon); if(isChecked){ iconImageView.setAlpha(1-mAlpha); } else { iconImageView.setAlpha(mAlpha); } } /** * 设置第二层图标 * */ private void setTabIconOverData(){ iconOverImageView.setImageDrawable(tabIconOver); if(isChecked){ iconOverImageView.setAlpha(mAlpha); } else { iconOverImageView.setAlpha(1-mAlpha); } } /** * 滑动时设置图标透明度以及文字透明度 * */ private void onScrollSetData(){ //设置图标透明度 iconImageView.setAlpha(1-mAlpha); iconOverImageView.setAlpha(mAlpha); //设置标题透明度 titleTextView.setAlpha(1-mAlpha); titleOverTextView.setAlpha(mAlpha); } /** * 设置标题数据 * */ private void setTitleData(){ titleTextView.setText(titleText); titleTextView.setTextColor(titleNolColor); if(isChecked){ titleTextView.setAlpha(1-mAlpha); } else { titleTextView.setAlpha(mAlpha); } } /** * 设置第二层标题数据 * */ private void setTitleOverData(){ titleOverTextView.setText(titleText); titleOverTextView.setTextColor(titleColor); if(isChecked){ titleOverTextView.setAlpha(mAlpha); } else { titleOverTextView.setAlpha(1-mAlpha); } } /** * 选中之后重新设置数据 * */ private void setCheckedData(){ refreshData(); } /** * 设置完数据之后刷新 * */ private void refreshData(){ mAlpha = 1.0f; setTitleData(); setTitleOverData(); setTabIconData(); setTabIconOverData(); } public String getTitleText() { return titleText; } public void setTitleText(String titleText) { this.titleText = titleText; } public Drawable getTabIcon() { return tabIcon; } public void setTabIcon(Drawable tabIcon) { this.tabIcon = tabIcon; } public boolean isChecked() { return isChecked; } public ImageView getIconImageView() { return iconImageView; }}关键代码:
/** * 设置图标 * */ private void setTabIconData(){ iconImageView.setImageDrawable(tabIcon); if(isChecked){ iconImageView.setAlpha(1-mAlpha); } else { iconImageView.setAlpha(mAlpha); } } /** * 设置第二层图标 * */ private void setTabIconOverData(){ iconOverImageView.setImageDrawable(tabIconOver); if(isChecked){ iconOverImageView.setAlpha(mAlpha); } else { iconOverImageView.setAlpha(1-mAlpha); } } /** * 滑动时设置图标透明度以及文字透明度 * */ private void onScrollSetData(){ //设置图标透明度 iconImageView.setAlpha(1-mAlpha); iconOverImageView.setAlpha(mAlpha); //设置标题透明度 titleTextView.setAlpha(1-mAlpha); titleOverTextView.setAlpha(mAlpha); }
滑动的时候会调用ViewPager.OnPageChangeListener()里的方法
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
//positionOffset滑动的百分比;
根据百分比设置Alpha值,完成颜色渐变
Ok,这样我们就初步完成了TabView,按着微信的布局,我们还需要一个Linearlayout,接下来,我们继续实现,新建TabGroupView继承LinearLayout,代码以及讲解如下:
package cc.mn.tab;import android.content.Context;import android.util.AttributeSet;import android.view.View;import android.widget.LinearLayout;import java.util.ArrayList;import java.util.List;/** * User: 山野书生(1203596603@qq.com) * Date: 2015-11-27 * Time: 20:35 * Version 1.0 */public class TabGroupView extends LinearLayout { private OnItemClickListener onItemClickListener; private List<TabView> tabLayouts; private String tag = TabGroupView.class.getSimpleName(); public TabGroupView(Context context) { this(context, null); } public TabGroupView(Context context, AttributeSet attrs) { super(context, attrs); tabLayouts = new ArrayList<>(); this.setOrientation(HORIZONTAL); //设置默认为水平布局 } /** * 选中某一个 * */ public void setCurrentItem(int item){ changeItem(); TabView tabLayout = tabLayouts.get(item); tabLayout.setChecked(true); } /** * @param position 当前界面索引 * @param positionOffset 滑动的百分比 * */ public void onPageScrolling(int position, float positionOffset) { if(positionOffset>0){ TabView tabLayout = tabLayouts.get(position); tabLayout.onScrolling(1-positionOffset); if(position+1 < tabLayouts.size()){ TabView nextTabLayout = tabLayouts.get(position+1); nextTabLayout.onScrolling(positionOffset); } } } /** * 设置监听器 * */ private void initListener(){ int count = this.getChildCount(); for(int i=0; i<count; i++){ final TabView tabLayout = (TabView)this.getChildAt(i); tabLayouts.add(tabLayout); final int finalI = i; tabLayout.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { changeItem(); //清除选中状态 tabLayout.setChecked(true); if(onItemClickListener!=null){ onItemClickListener.onClick(finalI, tabLayout); } } }); } } /** * 清除选中状态 * */ private void changeItem(){ for(TabView tabLayout:tabLayouts){ tabLayout.setChecked(false); } } /** * 设置每个Item的监听事件 * */ public void setOnItemClickListener(OnItemClickListener onItemClickListener) { this.onItemClickListener = onItemClickListener; initListener(); } /** * 点击事件 * */ public interface OnItemClickListener{ void onClick(int position, TabView tabLayout); } /** * 设置只能水平布局 * */ @Override public void setOrientation(int orientation) { super.setOrientation(HORIZONTAL); }}Ok,高仿微信滑动Tab完成,开始应用;
首先布局文件:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" > <cc.mn.tab.TabGroupView android:layout_width="match_parent" android:layout_height="55dp" android:background="@color/text" android:layout_alignParentBottom="true" android:id="@+id/group_tab_layout" android:paddingTop="5dp" android:paddingBottom="5dp" > <cc.mn.tab.TabView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:id="@+id/tab_main" app:tabTitle="微信" app:tabTitleColor="@color/tab_bg_green" app:tabIcon="@mipmap/chats" app:tabIconOver="@mipmap/chats_green" app:tabLablebackground="@color/item_tab_bg" app:tabChecked="true" /> <cc.mn.tab.TabView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" app:tabTitle="通讯录" app:tabTitleColor="@color/tab_bg_green" app:tabLableColor="@color/text" app:tabIcon="@mipmap/contacts" app:tabIconOver="@mipmap/contacts_green" /> <cc.mn.tab.TabView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:id="@+id/tab_friedns" app:tabTitle="发现" app:tabTitleColor="@color/tab_bg_green" app:tabIcon="@mipmap/discover" app:tabIconOver="@mipmap/discover_green" /> <cc.mn.tab.TabView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" app:tabTitle="我" app:tabTitleColor="@color/tab_bg_green" app:tabIcon="@mipmap/about_me" app:tabIconOver="@mipmap/about_me_green" /> </cc.mn.tab.TabGroupView> <android.support.v4.view.ViewPager android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/group_tab_layout" android:id="@+id/view_pager" /></RelativeLayout>
在Activity应用:
package cc.mntabdemo;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentPagerAdapter;import android.support.v4.view.ViewPager;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import java.util.ArrayList;import java.util.List;import cc.mn.tab.TabGroupView;import cc.mn.tab.TabView;public class MainActivity extends AppCompatActivity implements TabGroupView.OnItemClickListener{ private TabGroupView group_tab_layout; private ViewPager view_pager; private List<ContentFragment> list = new ArrayList<>(); private int mPosition = 0; private String tag = MainActivity.class.getSimpleName(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); list.add(new ContentFragment("微信")); list.add(new ContentFragment("通讯录")); list.add(new ContentFragment("发现")); list.add(new ContentFragment("我")); view_pager = (ViewPager)findViewById(R.id.view_pager); group_tab_layout = (TabGroupView)findViewById(R.id.group_tab_layout); group_tab_layout.setOnItemClickListener(this); view_pager.setAdapter(pagerAdapter); view_pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { group_tab_layout.onPageScrolling(position, positionOffset); } @Override public void onPageSelected(int position) { mPosition = position; group_tab_layout.setCurrentItem(mPosition); } @Override public void onPageScrollStateChanged(int state) { //状态 } }); } //创建适配器 private FragmentPagerAdapter pagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public Fragment getItem(int position) { return list.get(position); } @Override public int getCount() { return list.size(); } }; @Override public void onClick(int position, TabView tabLayout) { Log.i(tag, "选中的tablayout=" + position); view_pager.setCurrentItem(position, false); //取消动画 } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); }}运行截图:
OK,基本与微信一样,性能和实用性请同学们自测,代码;最新代码添加了BadgeView,下篇博文进行讲解!
关于TabView也可以通过代码进行添加,像Tabhost的一样使用。
0 0
- android开发之高仿微信6.0+滑动Tab
- Android开发学习之使用ViewPager+PagerTabStrip制作可滑动的Tab
- Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab
- Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab
- Android开发学习之使用ViewPager+PagerTabStrip制作可滑动的Tab
- Android开发学习之使用ViewPager+PagerTabStrip制作可滑动的Tab
- Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab
- android滑动TAB页面
- Android UI 详解之ActionBar+ViewPager+Fragment 实现滑动Tab
- android之滑动悬浮tab&无限循环的viewPager
- android开发之滑动手势翻图 滑动手势监听
- android开发之滑动手势翻图 滑动手势监听
- android开发之滑动手势翻图 滑动手势监听
- Android开发之滑动选择菜单(仿QQ滑动删除)
- Android开发之SlidingDrawer(滑动式抽屉)
- android开发之定制ViewPager滑动事件
- Android开发之仿滑动解锁
- Android之Tab分页标签的实现方法一-----可滑动的Tab的3种方式
- 面向对象的mysqli基础
- 关于嵌入文本框设置只读后,后台获取不到值--解决办法
- 如何在JavaWeb程序中使用自定义标签(tag、tld两种)
- spring注解或依赖注入模拟MVC结构案例<五>
- 广义表-(没有测试过)
- android开发之高仿微信6.0+滑动Tab
- httpClient使用文档整理
- 计算机专业推荐国际会议
- UVa 10935 卡片游戏
- Quora上关于P, NP, NP-complete, and NP-hard问题的解答
- UIScrollView的setContentOffset方法
- iOS之UIcollectionView
- 【前端开发】 5分钟创建 Mock Server
- 浅析iOS的@property属性