【译】Android主题动态切换开源库Prism基本原理2-搭配ViewPager使用
2015-08-17 11:51
399 查看
Android主题动态切换开源库Prism基本原理2-搭配ViewPager使用
原文链接 : Prism Fundamentals Part 2原文作者 : Mark Allison
译文出自 : 开发技术前线 www.devtf.cn。未经允许,不得转载!
翻译者 : Desmond1121
在之前的一章中我介绍了用
Prism实例将UI组件链接起来并通过调用
setColour(int colour)切换颜色主题。那么你也可以看到,使用
Setter和
Filter可以让事情(切换主题)变得多么简单,省去了很多冗杂的代码。现在我们来看看加入
Trigger以后会发生什么有趣的事情!
首先我们在工程中添加
prism-viewpager的依赖库,
build.gradle示例如下:
apply plugin: 'com.android.application' android { compileSdkVersion 22 buildToolsVersion "23.0.0 rc3" defaultConfig { applicationId "com.stylingandroid.prism.sample.viewpager" minSdkVersion 7 targetSdkVersion 22 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile 'com.android.support:appcompat-v7:22.2.0' compile 'com.android.support:design:22.2.0' compile 'com.stylingandroid.prism:prism:1.0.1' compile 'com.stylingandroid.prism:prism-viewpager:1.0.1' }
Trigger是Prism触发颜色主题变换时必须的组件。我们首先来看
ViewPagerTrigger搭配
ViewPager时是怎么随着用户输入而触发颜色主题变换的。为了实现颜色变换,
ViewPager的
Adapter需要为它的每一个页面位置提供颜色属性,
ColourProvider接口提供了这个功能(或者是
ColorProvider,如果你不介意使用它带来的些许性能损失的话)。
/* ColourProvider.java */ public interface ColourProvider { @ColorInt int getColour(int position); int getCount(); } /* ColorProvider.java */ public interface ColorProvider { @ColorInt int getColor(int position); int getCount(); }
如果你使用过
PagerTitleStrip或者新的Android设计库中的
TabLayout的话,你不会对为
ViewPager的每个页面提供标题这件事感到陌生。而使用
ColourProvider接口仅仅就是将 为每个页面提供标题变成了 为每个页面提供颜色值而已。当继承
Adapter的时候你不需要提供
getCount()方法,因为这个方法在
Adapter中已经定义了。你所需要做的就是像下面这些代码一样实现你的
Adapter:
public class RainbowPagerAdapter extends FragmentPagerAdapter implements ColourProvider { private static final Rainbow[] COLOURS = { Rainbow.Red, Rainbow.Orange, Rainbow.Yellow, Rainbow.Green, Rainbow.Blue, Rainbow.Indigo, Rainbow.Violet }; private final Context context; public RainbowPagerAdapter(Context context, FragmentManager fragmentManager) { super(fragmentManager); this.context = context; } @Override public Fragment getItem(int position) { Rainbow colour = COLOURS[position]; return ColourFragment.newInstance(context, getPageTitle(position), colour.getColour()); } @Override public void destroyItem(ViewGroup container, int position, Object object) { FragmentManager manager = ((Fragment) object).getFragmentManager(); FragmentTransaction trans = manager.beginTransaction(); trans.remove((Fragment) object); trans.commit(); super.destroyItem(container, position, object); } @Override public int getCount() { return COLOURS.length; } @Override public CharSequence getPageTitle(int position) { return COLOURS[position].name(); } /* 重写ColourProvider中的方法 */ @Override public int getColour(int position) { return COLOURS[position].getColour(); } /* 提供颜色值的枚举 */ private enum Rainbow { Red(Color.rgb(0xFF, 0x00, 0x00)), Orange(Color.rgb(0xFF, 0x7F, 0x00)), Yellow(Color.rgb(0xCF, 0xCF, 0x00)), Green(Color.rgb(0x00, 0xAF, 0x00)), Blue(Color.rgb(0x00, 0x00, 0xFF)), Indigo(Color.rgb(0x4B, 0x00, 0x82)), Violet(Color.rgb(0x7F, 0x00, 0xFF)); private final int colour; Rainbow(int colour) { this.colour = colour; } public int getColour() { return colour; } } }
当我们拥有一个实现
ColourProvider接口的
Adapter后我们就可以将它和Prism的
ViewPagerTrigger一起使用了:
public class MainActivity extends AppCompatActivity { private static final float TINT_FACTOR_50_PERCENT = 0.5f; private DrawerLayout drawerLayout; private View navHeader; private AppBarLayout appBar; private Toolbar toolbar; private TabLayout tabLayout; private ViewPager viewPager; private FloatingActionButton fab; private Prism prism = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* 获取View实例 */ drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); navHeader = findViewById(R.id.nav_header); appBar = (AppBarLayout) findViewById(R.id.app_bar); toolbar = (Toolbar) findViewById(R.id.toolbar); tabLayout = (TabLayout) findViewById(R.id.tab_layout); viewPager = (ViewPager) findViewById(R.id.viewpager); fab = (FloatingActionButton) findViewById(R.id.fab); setupToolbar(); setupViewPager(); } @Override protected void onDestroy() { if (prism != null) { prism.destroy(); } super.onDestroy(); } private void setupToolbar() { setSupportActionBar(toolbar); ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setHomeAsUpIndicator(R.drawable.ic_menu); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setTitle(R.string.app_title); } } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: drawerLayout.openDrawer(GravityCompat.START); return true; default: return super.onOptionsItemSelected(item); } } private void setupViewPager() { RainbowPagerAdapter adapter = new RainbowPagerAdapter(this, getSupportFragmentManager()); viewPager.setAdapter(adapter); Filter tint = new TintFilter(TINT_FACTOR_50_PERCENT); Trigger trigger = ViewPagerTrigger.newInstance(viewPager, adapter); prism = Prism.Builder.newInstance() .add(trigger) .background(appBar) .background(getWindow()) .background(navHeader) .background(fab, tint) .colour(viewPager, tint) .build(); tabLayout.setupWithViewPager(viewPager); viewPager.setCurrentItem(0); } }
在
setupViewPager()中我们首先创建一个
RainbowPagerAdapter并应用到
ViewPager中。之后新建了一个
TintFilter,它能够让我们的
FloatingActionButton的颜色更加亮一点。然后新建一个与
ViewPager和
Adapter实例相关联的Trigger。
在做好上述准备工作之后,我们开始建立
Prism实例。与上次唯一不同的是我们为
Prism绑定了更多组件,以及添加了刚才新建的Trigger。你可能注意到我们为
ViewPager实例直接设置了颜色,实际上它的作用是设置当
ViewPager滑到两边极限时的“溢出颜色”(这个函数很巧妙,因为在不同的系统版本中处理
ViewPager“溢出颜色”的手段不一样,但Prism会在内部就帮你处理好这些逻辑!)。
之后我们将
TabLayout与
ViewPager绑定到一起(这是
TabLayout设计中要求的,而不是
Prism的逻辑需要),之后将
ViewPager的初始页面设置成了第一页。
简简单单的几行代码就能够让我们在滑动页面的时候改变主题颜色,看一下Demo吧:
可能有细腻的程序员会发现颜色转换并不是跳跃式的,它会有一个渐变的过程,而且渐变过程是跟随着你的拖拽过程的!
这里面所有的例子都会在源码Github中的示例代码 中看到。
相关文章推荐
- 解决 android 的R文件不能生成 R cannot be resolved to a variable
- 在Mac下 重置Android Studio
- 在AndroidMainfest中锁定屏幕方向
- android跟随系统切换语言
- Android studio change package name
- [Android]GreenDao(1)--项目配置
- Android中visibility属性VISIBLE、INVISIBLE、GONE的区别
- Android中Context详解 ---- 你所不知道的Context
- Android学习笔记--获取传感器信息
- Android开发者必知的5个开源库
- android里面Canvas,save()与restore()。
- Android——APK 在32bit/64bit平台 动态库问题
- Android Studio 视频教程地址
- 使用android不能分享资源的问题
- Toast使用方法
- Android触摸事件分发与响应
- Android 开源项目第一篇——个性化控件(View)篇
- android studio编译aidl文件出现问题
- Android流式布局的简单实现
- MPAndroidChart API用法