Android实用视图动画及工具系列之七:可定制Tab标签栏,ViewPaper和Fragment滑动标签视图
来源:互联网 发布:js跳转指定页面 编辑:程序博客网 时间:2024/05/16 19:27
实现效果
功能说明
本视图工具根据PagerSlidingTabStrip改编优化,修复了部分Bug和增加了更多自定义选项,让PagerSlidingTabStrip变得更漂亮实用。关于PagerSlidingTabStrip,它是配合ViewPager使用的导航栏,如上图所示,最顶部导航栏部分,导航跟着页面切换而滚动,而且指示器还会随着标题的长度而动态的变化长度。
本视图工具适用于新手及新学习Android的码友们,老玩家当然也可以看看,这个还是挺简单挺实用的,在后面会简略介绍实现方法及源代码,同时博客的最后还提供源代码和图片等资源github下载地址。
--------------------------------------------------------------------------------------------------------------------
PagerSlidingTabStrip是在Github上的一个开源项目,项目地址:
https://github.com/astuetz/PagerSlidingTabStrip
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
这篇文章只讲解Tab标签栏部分,如果需要了解gif中的头部滑动隐藏,请看Blog:
http://blog.csdn.net/jaikydota163/article/details/52098878
--------------------------------------------------------------------------------------------------------------------
实现步骤
步骤一:认识需要自定义的属性
在编写下面的代码前,我们先来认识下这个视图可以设置的一些属性,通过改变这些属性来让我们更好的使用它来完成自己想要的风格:
pstsIndicatorColor:滑动指示器颜色
pstsUnderlineColor:视图的底部的全宽线的颜色
pstsDividerColor:选项卡之间的分隔线的颜色
pstsIndicatorHeight:滑动指标高度
pstsUnderlineHeight:视图的底部高度的全宽线
pstsDividerPadding:顶部和分频器的底部填充
pstsTabPaddingLeftRight:左,每个选项卡的右填充
pstsScrollOffset:所选选项卡的滚动偏移量
pstsTabBackground:每个标签的背景可拉伸,应该是一个StateListDrawable
pstsShouldExpand:如果设置为true,每个选项卡被赋予了相同的权重,默认为false
pstsTextAllCaps:如果为true,所有的选项卡标题将是大写,默认为true
pstsUnderlineColor:视图的底部的全宽线的颜色
pstsDividerColor:选项卡之间的分隔线的颜色
pstsIndicatorHeight:滑动指标高度
pstsUnderlineHeight:视图的底部高度的全宽线
pstsDividerPadding:顶部和分频器的底部填充
pstsTabPaddingLeftRight:左,每个选项卡的右填充
pstsScrollOffset:所选选项卡的滚动偏移量
pstsTabBackground:每个标签的背景可拉伸,应该是一个StateListDrawable
pstsShouldExpand:如果设置为true,每个选项卡被赋予了相同的权重,默认为false
pstsTextAllCaps:如果为true,所有的选项卡标题将是大写,默认为true
pstsTabTextSize:标签文字的大小尺寸,单位为SP
pstsTabTextSelectedColor:当前被选中的标签文本颜色
整个Demo项目的结构如下:
步骤二:添加基本布局和属性
在colors.xml中添加如下颜色:
<color name="background_tab_pressed">#6633B5E5</color>
在项目中的values文件下新建attrs.xml文件,添加属性如下:
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="PagerSlidingTabStrip"> <attr name="pstsIndicatorColor" format="color" /> <attr name="pstsUnderlineColor" format="color" /> <attr name="pstsDividerColor" format="color" /> <attr name="pstsIndicatorHeight" format="dimension" /> <attr name="pstsUnderlineHeight" format="dimension" /> <attr name="pstsDividerPadding" format="dimension" /> <attr name="pstsTabPaddingLeftRight" format="dimension" /> <attr name="pstsScrollOffset" format="dimension" /> <attr name="pstsTabTextSize" format="dimension" /> <attr name="pstsTabBackground" format="reference" /> <attr name="pstsShouldExpand" format="boolean" /> <attr name="pstsTextAllCaps" format="boolean" /> <attr name="pstsTabTextSelectedColor" format="color" /> </declare-styleable></resources>在项目中的drawable文件下新建在slidetabs_background_tab.xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_shortAnimTime"> <item android:drawable="@color/background_tab_pressed" android:state_pressed="true"/> <item android:drawable="@color/background_tab_pressed" android:state_focused="true"/> <item android:drawable="@android:color/transparent"/></selector>
package com.jaiky.test.paperslidetab;import android.annotation.SuppressLint;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Paint.Style;import android.graphics.Typeface;import android.os.Build;import android.os.Parcel;import android.os.Parcelable;import android.support.v4.view.ViewPager;import android.support.v4.view.ViewPager.OnPageChangeListener;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.util.TypedValue;import android.view.Gravity;import android.view.View;import android.view.ViewTreeObserver.OnGlobalLayoutListener;import android.widget.HorizontalScrollView;import android.widget.ImageButton;import android.widget.LinearLayout;import android.widget.TextView;import java.util.Locale;public class PagerSlidingTabStrip extends HorizontalScrollView { public interface IconTabProvider { public int getPageIconResId(int position); } // @formatter:off private static final int[] ATTRS = new int[]{ android.R.attr.textSize, android.R.attr.textColor }; // @formatter:on private LinearLayout.LayoutParams defaultTabLayoutParams; private LinearLayout.LayoutParams expandedTabLayoutParams; private final PageListener pageListener = new PageListener(); public OnPageChangeListener delegatePageListener; private LinearLayout tabsContainer; private ViewPager pager; private int tabCount; //选中position private int selectedPostion = 0; private int currentPosition = 0; private float currentPositionOffset = 0f; private Paint rectPaint; private Paint dividerPaint; private int indicatorColor = 0xFF666666; private int underlineColor = 0x1A000000; private int dividerColor = 0x1A000000; private boolean shouldExpand = false; private boolean textAllCaps = true; private int scrollOffset = 52; private int indicatorHeight = 8; private int underlineHeight = 2; private int dividerPadding = 12; private int tabPadding = 24; private int dividerWidth = 1; private int tabTextSize = 12; private int tabTextColor = 0xFF666666; private int tabTextSelectedColor = 0xFF28a6ff; private Typeface tabTypeface = null; private int tabTypefaceStyle = Typeface.BOLD; private int lastScrollX = 0; private int tabBackgroundResId = R.drawable.slidetabs_background_tab; private Locale locale; public PagerSlidingTabStrip(Context context) { this(context, null); } public PagerSlidingTabStrip(Context context, AttributeSet attrs) { this(context, attrs, 0); } public PagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setFillViewport(true); setWillNotDraw(false); tabsContainer = new LinearLayout(context); tabsContainer.setOrientation(LinearLayout.HORIZONTAL); tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); addView(tabsContainer); DisplayMetrics dm = getResources().getDisplayMetrics(); scrollOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm); indicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm); underlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm); dividerPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm); tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm); dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm); tabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm); // get system attrs (android:textSize and android:textColor) TypedArray a = context.obtainStyledAttributes(attrs, ATTRS); tabTextSize = a.getDimensionPixelSize(0, tabTextSize); tabTextColor = a.getColor(1, tabTextColor); a.recycle(); // get custom attrs a = context.obtainStyledAttributes(attrs, R.styleable.PagerSlidingTabStrip); indicatorColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsIndicatorColor, indicatorColor); underlineColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsUnderlineColor, underlineColor); dividerColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsDividerColor, dividerColor); tabTextSelectedColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsTabTextSelectedColor, tabTextSelectedColor); indicatorHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsIndicatorHeight, indicatorHeight); underlineHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsUnderlineHeight, underlineHeight); dividerPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsDividerPadding, dividerPadding); tabPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTabPaddingLeftRight, tabPadding); tabBackgroundResId = a.getResourceId(R.styleable.PagerSlidingTabStrip_pstsTabBackground, tabBackgroundResId); shouldExpand = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsShouldExpand, shouldExpand); scrollOffset = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsScrollOffset, scrollOffset); textAllCaps = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsTextAllCaps, textAllCaps); tabTextSize = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTabTextSize, tabTextSize); a.recycle(); rectPaint = new Paint(); rectPaint.setAntiAlias(true); rectPaint.setStyle(Style.FILL); dividerPaint = new Paint(); dividerPaint.setAntiAlias(true); dividerPaint.setStrokeWidth(dividerWidth); defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); expandedTabLayoutParams = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f); if (locale == null) { locale = getResources().getConfiguration().locale; } } public void setViewPager(ViewPager pager) { this.pager = pager; if (pager.getAdapter() == null) { throw new IllegalStateException("ViewPager does not have adapter instance."); } pager.setOnPageChangeListener(pageListener); notifyDataSetChanged(); } public void setOnPageChangeListener(OnPageChangeListener listener) { this.delegatePageListener = listener; } public void notifyDataSetChanged() { tabsContainer.removeAllViews(); tabCount = pager.getAdapter().getCount(); for (int i = 0; i < tabCount; i++) { if (pager.getAdapter() instanceof IconTabProvider) { addIconTab(i, ((IconTabProvider) pager.getAdapter()).getPageIconResId(i)); } else { addTextTab(i, pager.getAdapter().getPageTitle(i).toString()); } } updateTabStyles(); getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @SuppressWarnings("deprecation") @SuppressLint("NewApi") @Override public void onGlobalLayout() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { getViewTreeObserver().removeGlobalOnLayoutListener(this); } else { getViewTreeObserver().removeOnGlobalLayoutListener(this); } currentPosition = pager.getCurrentItem(); scrollToChild(currentPosition, 0); } }); } private void addTextTab(final int position, String title) { TextView tab = new TextView(getContext()); tab.setText(title); tab.setGravity(Gravity.CENTER); tab.setSingleLine(); addTab(position, tab); } private void addIconTab(final int position, int resId) { ImageButton tab = new ImageButton(getContext()); tab.setImageResource(resId); addTab(position, tab); } private void addTab(final int position, View tab) { tab.setFocusable(true); tab.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { pager.setCurrentItem(position); } }); tab.setPadding(tabPadding, 0, tabPadding, 0); tabsContainer.addView(tab, position, shouldExpand ? expandedTabLayoutParams : defaultTabLayoutParams); } private void updateTabStyles() { for (int i = 0; i < tabCount; i++) { View v = tabsContainer.getChildAt(i); v.setBackgroundResource(tabBackgroundResId); if (v instanceof TextView) { TextView tab = (TextView) v; tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize); tab.setTypeface(tabTypeface, tabTypefaceStyle); if (selectedPostion == i) { tab.setTextColor(tabTextSelectedColor); } else { tab.setTextColor(tabTextColor); } // setAllCaps() is only available from API 14, so the upper case is made manually if we are on a // pre-ICS-build if (textAllCaps) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { tab.setAllCaps(true); } else { tab.setText(tab.getText().toString().toUpperCase(locale)); } } } } } private void scrollToChild(int position, int offset) { if (tabCount == 0) { return; } int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset; if (position > 0 || offset > 0) { newScrollX -= scrollOffset; } if (newScrollX != lastScrollX) { lastScrollX = newScrollX; scrollTo(newScrollX, 0); } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (isInEditMode() || tabCount == 0) { return; } final int height = getHeight(); // draw indicator line rectPaint.setColor(indicatorColor); // default: line below current tab View currentTab = tabsContainer.getChildAt(currentPosition); float lineLeft = currentTab.getLeft(); float lineRight = currentTab.getRight(); // if there is an offset, start interpolating left and right coordinates between current and next tab if (currentPositionOffset > 0f && currentPosition < tabCount - 1) { View nextTab = tabsContainer.getChildAt(currentPosition + 1); final float nextTabLeft = nextTab.getLeft(); final float nextTabRight = nextTab.getRight(); lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft); lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight); } canvas.drawRect(lineLeft, height - indicatorHeight, lineRight, height, rectPaint); // draw underline rectPaint.setColor(underlineColor); canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint); // draw divider dividerPaint.setColor(dividerColor); for (int i = 0; i < tabCount - 1; i++) { View tab = tabsContainer.getChildAt(i); canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint); } } private class PageListener implements OnPageChangeListener { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { currentPosition = position; currentPositionOffset = positionOffset; scrollToChild(position, (int) (positionOffset * tabsContainer.getChildAt(position).getWidth())); invalidate(); if (delegatePageListener != null) { delegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels); } } @Override public void onPageScrollStateChanged(int state) { if (state == ViewPager.SCROLL_STATE_IDLE) { scrollToChild(pager.getCurrentItem(), 0); } if (delegatePageListener != null) { delegatePageListener.onPageScrollStateChanged(state); } } @Override public void onPageSelected(int position) { if (delegatePageListener != null) { delegatePageListener.onPageSelected(position); } selectedPostion = position; updateTabStyles(); } } public void setIndicatorColor(int indicatorColor) { this.indicatorColor = indicatorColor; invalidate(); } public void setIndicatorColorResource(int resId) { this.indicatorColor = getResources().getColor(resId); invalidate(); } public int getIndicatorColor() { return this.indicatorColor; } public void setIndicatorHeight(int indicatorLineHeightPx) { this.indicatorHeight = indicatorLineHeightPx; invalidate(); } public int getIndicatorHeight() { return indicatorHeight; } public void setUnderlineColor(int underlineColor) { this.underlineColor = underlineColor; invalidate(); } public void setUnderlineColorResource(int resId) { this.underlineColor = getResources().getColor(resId); invalidate(); } public int getUnderlineColor() { return underlineColor; } public void setDividerColor(int dividerColor) { this.dividerColor = dividerColor; invalidate(); } public void setDividerColorResource(int resId) { this.dividerColor = getResources().getColor(resId); invalidate(); } public int getDividerColor() { return dividerColor; } public void setUnderlineHeight(int underlineHeightPx) { this.underlineHeight = underlineHeightPx; invalidate(); } public int getUnderlineHeight() { return underlineHeight; } public void setDividerPadding(int dividerPaddingPx) { this.dividerPadding = dividerPaddingPx; invalidate(); } public int getDividerPadding() { return dividerPadding; } public void setScrollOffset(int scrollOffsetPx) { this.scrollOffset = scrollOffsetPx; invalidate(); } public int getScrollOffset() { return scrollOffset; } public void setShouldExpand(boolean shouldExpand) { this.shouldExpand = shouldExpand; requestLayout(); } public boolean getShouldExpand() { return shouldExpand; } public boolean isTextAllCaps() { return textAllCaps; } public void setAllCaps(boolean textAllCaps) { this.textAllCaps = textAllCaps; } public void setTextSize(int textSizePx) { this.tabTextSize = textSizePx; updateTabStyles(); } public int getTextSize() { return tabTextSize; } public void setTextColor(int textColor) { this.tabTextColor = textColor; updateTabStyles(); } public void setTextColorResource(int resId) { this.tabTextColor = getResources().getColor(resId); updateTabStyles(); } public int getTextColor() { return tabTextColor; } public void setTypeface(Typeface typeface, int style) { this.tabTypeface = typeface; this.tabTypefaceStyle = style; updateTabStyles(); } public void setTabBackground(int resId) { this.tabBackgroundResId = resId; } public int getTabBackground() { return tabBackgroundResId; } public void setTabPaddingLeftRight(int paddingPx) { this.tabPadding = paddingPx; updateTabStyles(); } public int getTabPaddingLeftRight() { return tabPadding; } @Override public void onRestoreInstanceState(Parcelable state) { SavedState savedState = (SavedState) state; super.onRestoreInstanceState(savedState.getSuperState()); currentPosition = savedState.currentPosition; requestLayout(); } @Override public Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); SavedState savedState = new SavedState(superState); savedState.currentPosition = currentPosition; return savedState; } static class SavedState extends BaseSavedState { int currentPosition; public SavedState(Parcelable superState) { super(superState); } private SavedState(Parcel in) { super(in); currentPosition = in.readInt(); } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeInt(currentPosition); } public static final Creator<SavedState> CREATOR = new Creator<SavedState>() { @Override public SavedState createFromParcel(Parcel in) { return new SavedState(in); } @Override public SavedState[] newArray(int size) { return new SavedState[size]; } }; }}
步骤三:Demo测试修改布局和主类
在layout文件夹下新建测试用test_fragment.xml内容如下:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/tvShow" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:text="TAB1" android:gravity="center"/></LinearLayout>
修改activity_main.xml内容如下(注意自定义控件包名):
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/activity_main" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.jaiky.test.paperslidetab.MainActivity"> <com.jaiky.test.paperslidetab.PagerSlidingTabStrip android:id="@+id/pstTab" android:layout_width="match_parent" android:layout_height="45dp" android:background="#ffffff" app:pstsDividerPadding="15dp" app:pstsIndicatorColor="#28a6ff" app:pstsIndicatorHeight="2dp" app:pstsShouldExpand="true" app:pstsTabTextSize="14sp" app:pstsUnderlineHeight="1dp" /> <android.support.v4.view.ViewPager android:id="@+id/vpTabPager" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" > </android.support.v4.view.ViewPager></LinearLayout>新建TestFragment类内容如下(注意包名):
package com.jaiky.test.paperslidetab;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v4.app.Fragment;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;/** * Author by Jaiky, Email jaikydota@163.com, Date on 1/5/2016. * PS: Not easy to write code, please indicate. */public class TestFragment extends Fragment { TextView tvShow; int postion; int color; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.test_fragment, container, false); tvShow = (TextView) view.findViewById(R.id.tvShow); tvShow.setText("TAB" + (postion + 1)); tvShow.setBackgroundColor(color); return view; } public void setInfo(int postion, int color) { this.postion = postion; this.color = color; }}
修改MainActiivty类内容如下(注意包名):
package com.jaiky.test.paperslidetab;import android.graphics.Color;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;public class MainActivity extends AppCompatActivity { private ViewPager vpTabPager; PagerSlidingTabStrip pstTab; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); vpTabPager = (ViewPager) findViewById(R.id.vpTabPager); vpTabPager.setAdapter(new myPagerAdapter(getSupportFragmentManager())); pstTab = (PagerSlidingTabStrip) findViewById(R.id.pstTab); pstTab.setViewPager(vpTabPager); //如何需要设置viewpaper的页面监听,如下,不要设置viewpaper.setOnPageChangeListener pstTab.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { } @Override public void onPageScrollStateChanged(int state) { } }); } class myPagerAdapter extends FragmentPagerAdapter { String[] title = {"TAB1", "TAB2", "TAB3"}; TestFragment fragment1; TestFragment fragment2; TestFragment fragment3; public myPagerAdapter(android.support.v4.app.FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { switch (position) { case 0: fragment1 = new TestFragment(); fragment1.setInfo(0, Color.parseColor("#845621")); return fragment1; case 1: fragment2 = new TestFragment(); fragment2.setInfo(1, Color.parseColor("#E45621")); return fragment2; case 2: fragment3 = new TestFragment(); fragment3.setInfo(2, Color.parseColor("#445621")); return fragment3; default: return null; } } @Override public int getCount() { return title.length; } @Override public CharSequence getPageTitle(int position) { return title[position]; } }}
--------------------------------------------------------------------------------------------------------------------
获取源代码及资源文件:
https://github.com/jaikydota/Android-PagerSlidingTabStrip
--------------------------------------------------------------------------------------------------------------------
声明
欢迎转载,但请保留文章原始出处
作者:Jaiky_杰哥
出处:http://blog.csdn.net/jaikydota163/article/details/52098875
7 0
- Android实用视图动画及工具系列之七:可定制Tab标签栏,ViewPaper和Fragment滑动标签视图
- Android实用视图动画及工具系列之八:带头部的Viewpaper,结合头部的Fragment切换效果
- Android实用视图动画及工具系列之一:简单的载入视图和载入动画
- Android实用视图动画及工具系列之二:Toast对话框和加载载入对话框
- Android实用视图动画及工具系列之三:表情加载动画和失败加载动画,人物加载动画
- Android实用视图动画及工具系列之四:多状态CheckBox,可设置大小尺寸和设置不可用的复选框
- Android实用视图动画及工具系列之十:漂亮的发布动画,仿新浪首页加号发布微博动画框
- Android实用视图动画及工具系列之十:漂亮的发布动画,仿新浪首页加号发布微博动画框
- Android实用视图动画及工具系列之九:漂亮的图片选择器,高性能防崩溃图片选择工具
- Android实用视图动画及工具系列之五:底部回复对话框,仿QQ空间微信朋友圈回复对话框
- Android实用视图动画及工具系列之六:通用表情栏,仿QQ微信聊天弹出表情选框
- (转)Android实用视图动画及工具系列之六:通用表情栏,仿QQ微信聊天弹出表情选框
- 标签栏视图控制器(Tab Bar Controller)
- android自定义视图之扇形标签栏
- JFTabView 标签滑动视图封装
- Android ViewPager和Fragment实现顶部导航界面滑动效果、标签下的tab位置
- Android中的视图标签
- 一个案例教你简单地玩转ViewPager(二)之ViewPaper+TabLayout+Fragment顶部标签界面滑动
- 一类数据多种存储(虑将频繁查询的数据加载到内存或者内存数据库。如果一类数据,即要在内存中存储一份,又要在数据库中存储一)
- Android实用视图动画及工具系列之五:底部回复对话框,仿QQ空间微信朋友圈回复对话框
- C++中Defaulted 函数
- 一个小小程序员的爬坑笔记
- Android实用视图动画及工具系列之六:通用表情栏,仿QQ微信聊天弹出表情选框
- Android实用视图动画及工具系列之七:可定制Tab标签栏,ViewPaper和Fragment滑动标签视图
- 2016 google host地址
- Android实用视图动画及工具系列之八:带头部的Viewpaper,结合头部的Fragment切换效果
- java学习之路 之 面向对象编程-面向对象-第一个小项目P1-FAACS
- Android实用视图动画及工具系列之九:漂亮的图片选择器,高性能防崩溃图片选择工具
- HDU - 5787 K-wolf Number 数位DP
- 利用Office 365 定制企业合同管理平台,实现企业合同管理新篇章!
- Android实用视图动画及工具系列之十:漂亮的发布动画,仿新浪首页加号发布微博动画框
- 函数的定义声明 用法 形参实参 return关键字