带你实现开发者头条APP(四)---首页优化(加入design包)
2016-04-24 22:33
507 查看
一 、前言
上次模仿开发者头条首页实现了一个版本,给345大神,我的产品经理一看,又被鄙视了一把,说还在用老的技术,于是乎这三天把整个design包研究了一遍,然后把首页的代码几乎重写了一遍。。。。顺便用上了android studio,方便大家导入。。。效果图如下:
从gif动态效果图中我们可以看出,跟上次没有啥变化,唯一变化的就是列表上拉的时候会隐藏标题栏。。。其实里面的代码几乎重写了一遍,用了Android Design Support Library。
Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android Design Support Library,在这个support库里面,Google给我们提供了更加规范的MD设计风格的控件。最重要的是,Android Design Support Library的兼容性更广,直接可以向下兼容到Android 2.2。这不得不说是一个良心之作。
二、Toolbar+TabLayout 实现 标题栏+三个切换Tab
标题栏我之前引用的一个布局文件,现在改成了Toolbar。一个控件就够了。三个切换的Tab之前用的三个TextView,现在换成了TabLayout。
换了之后有哪些优点:
1).跟的上时代,逼格提高,更加规范的MD设计风格
2).控件变少了,现在一个功能一个控件就够
3).点击Tab文字变色,还有指示器的滑动在xml加个属性就行。
4).隐藏显示标题栏很方便。只需要在布局文件中改动就行.
[b]1.布局文件[/b]
最外层是CoordinatorLayout,里面主要就分两块,AppBarLayout+ViewPager(AppBarLayout里面包含标题栏的Toolbar+TabLayout,ViewPager用来切换Fragment显示)
为了使得Toolbar有滑动效果,必须做到如下三点:
1. CoordinatorLayout作为布局的父布局容器。
2. 给需要滑动的组件设置 app:layout_scrollFlags=”scroll|enterAlways” 属性。
3. 滑动的组件必须是AppBarLayout顶部组件。
4. 给滑动的组件设置app:layout_behavior属性
5.ViewPager显示的Fragment里面不能是ListView,必须是RecyclerView。
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/coordinatorLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:id="@+id/appBarLayout" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/launcher_item_select" app:layout_scrollFlags="scroll|enterAlways" app:titleTextAppearance="@style/ansenTextTitleAppearance"> </android.support.v7.widget.Toolbar> <android.support.design.widget.TabLayout android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:background="@color/main_color" app:tabIndicatorColor="@color/white_normal" app:tabIndicatorHeight="2dp" app:tabSelectedTextColor="@color/main_title_text_select" app:tabTextAppearance="@style/AnsenTabLayoutTextAppearance" app:tabTextColor="@color/main_title_text_normal"/> </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </android.support.design.widget.CoordinatorLayout>
[b]2.代码实现 MainFragment.java[/b]
1).初始化Toolbar,加载menu布局,实现标题栏的自定义。给NavigationIcon设置点击事件等。下面贴出代码实现,还有menu布局文件我就不贴出来了。那个也没啥技术含量。
Toolbar toolbar = (Toolbar) rootView.findViewById(R.id.toolbar); toolbar.inflateMenu(R.menu.ansen_toolbar_menu); toolbar.setNavigationIcon(R.mipmap.ic_menu_white); toolbar.setTitle("关注公众号[Android开发者666]"); toolbar.setTitleTextColor(getResources().getColor(android.R.color.white)); toolbar.setNavigationOnClickListener(onClickListener);
NavigationIcon监听函数,回调到MainActivity去。
private View.OnClickListener onClickListener=new View.OnClickListener(){ @Override public void onClick(View view) { if(drawerListener!=null){ drawerListener.open(); } } };
MainActivity.java
首先写了一个用来回调的接口
public interface MainDrawerListener{ public void open();//打开Drawer }
初始化Fragment的时候把MainDrawerListener对象传递过去 这样才能实现回调
mainFragment=new MainFragment(drawerListener);
private MainDrawerListener drawerListener=new MainDrawerListener() { @Override public void open() { mDrawerLayout.openDrawer(Gravity.LEFT); } };
2).给ViewPager设置Fragment适配器,给TabLayout绑定ViewPager,这样ViewPager滑动的时候或者选择tab的时候都会切换fragment。
vPager = (ViewPager) rootView.findViewById(R.id.viewPager); vPager.setOffscreenPageLimit(2);//设置缓存页数 vPager.setCurrentItem(0); FragmentAdapter pagerAdapter = new FragmentAdapter(getActivity().getSupportFragmentManager()); SelectedFragment selectedFragment=new SelectedFragment(); SubscribeFragment subscribeFragment=new SubscribeFragment(); FindFragment findFragment=new FindFragment(); pagerAdapter.addFragment(selectedFragment,"精选"); pagerAdapter.addFragment(subscribeFragment,"订阅"); pagerAdapter.addFragment(findFragment,"发现"); vPager.setAdapter(pagerAdapter); TabLayout tabLayout = (TabLayout) rootView.findViewById(R.id.tabLayout); tabLayout.setupWithViewPager(vPager);
三 、分析TabLayout切换源码
我们调用TabLayout的setupWithViewPager(ViewPager viewPager)方法的时候就是设置切换监听的时候。public void setupWithViewPager(ViewPager viewPager) { PagerAdapter adapter = viewPager.getAdapter(); if(adapter == null) { throw new IllegalArgumentException("ViewPager does not have a PagerAdapter set"); } else { this.setTabsFromPagerAdapter(adapter); viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(this)); this.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager)); } }
从上面代码中我们可以看到主要设置了两个监听函数。先说第一个。
在TabLayout里面有一个静态类TabLayoutOnPageChangeListener,用来处理ViewPager改变状态(切换或者增加)监听,看过我第三篇文章的同学对ViewPager的状态改变监听应该很熟悉了。
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(this));
TabLayoutOnPageChangeListener实现了ViewPagerde 的OnPageChangeListener接口,在onPageSelected方法中调用了当前选中的某个Tab的select方法。
public void onPageSelected(int position) { TabLayout tabLayout = (TabLayout)this.mTabLayoutRef.get(); if(tabLayout != null) { tabLayout.getTabAt(position).select(); } }
然后继续跟踪TabLayout.Tab类的select() 看看如何实现的。我们可以看到又调用了父类(TabLayout)的selectTab。
public void select() { this.mParent.selectTab(this); }
然后跟踪selectTab方法,这里大家可以看到参数是某个具体Tab对象,首先判断是不是当前tab,如果不是设置选择当前的tab,开启tab滑动动画。
void selectTab(TabLayout.Tab tab) { if(this.mSelectedTab == tab) { if(this.mSelectedTab != null) { if(this.mOnTabSelectedListener != null) { this.mOnTabSelectedListener.onTabReselected(this.mSelectedTab); } this.animateToTab(tab.getPosition()); } } else { int newPosition = tab != null?tab.getPosition():-1; this.setSelectedTabView(newPosition); if((this.mSelectedTab == null || this.mSelectedTab.getPosition() == -1) && newPosition != -1) { this.setScrollPosition(newPosition, 0.0F, true); } else { this.animateToTab(newPosition); } if(this.mSelectedTab != null && this.mOnTabSelectedListener != null) { this.mOnTabSelectedListener.onTabUnselected(this.mSelectedTab); } this.mSelectedTab = tab; if(this.mSelectedTab != null && this.mOnTabSelectedListener != null) { this.mOnTabSelectedListener.onTabSelected(this.mSelectedTab); } } }
上面的代码我就不一一解释了,直接看最下面那两行代码。调用tab的选择方法。
if(this.mSelectedTab != null && this.mOnTabSelectedListener != null) { this.mOnTabSelectedListener.onTabSelected(this.mSelectedTab); }
选择监听的接口
public interface OnTabSelectedListener { void onTabSelected(TabLayout.Tab var1); void onTabUnselected(TabLayout.Tab var1); void onTabReselected(TabLayout.Tab var1); }
在TabLayout内部实现了OnTabSelectedListener接口,在onTabSelected方法中调用了ViewPager的setCurrentItem(),这个方法大家应该都熟悉吧,我就不多做解释了。
public static class ViewPagerOnTabSelectedListener implements TabLayout.OnTabSelectedListener { private final ViewPager mViewPager; public ViewPagerOnTabSelectedListener(ViewPager viewPager) { this.mViewPager = viewPager; } public void onTabSelected(TabLayout.Tab tab) { this.mViewPager.setCurrentItem(tab.getPosition()); } public void onTabUnselected(TabLayout.Tab tab) { } public void onTabReselected(TabLayout.Tab tab) { } }
上面说到了第一种监听,就是ViewPager滑动的时候如何切换item,如果切换tab。现在来说第二种情况,就是点击选择tab的时候。如何切换的。继续回到TabLayout的setupWithViewPager(ViewPager viewPager)方法。
this.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager));
看到ViewPagerOnTabSelectedListener类是不是很熟悉,其实就是第一种方法最后调用的那个类。。。。。因为点击某个tab的时候,tab切换的代码已经运行,所以我们这里只需要设置下ViewPager当前选中的item就行。
从源码分析的文章第一次写,不知道这样写出来大家看的懂么,还有不对的地方也欢迎大家提出,可以给我评论哦,我会第一时间回复大家。
四 、透剧
本来打算顺便写下RecyclerView的实现的,但是发现内容已经不少了,那就留着下篇文章吧,下篇文章打算左滑里面的布局用NavigationView实现。然后加上RecyclerView吧。五 、源码下载
点击下载源码六 、相关文章阅读
带你实现开发者头条(一) 启动页实现带你实现开发者头条(二) 实现左滑菜单
带你实现开发者头条APP(三) 首页实现
带你实现开发者头条APP(四) 首页优化(加入design包)
带你实现开发者头条APP(五)–RecyclerView下拉刷新上拉加载
各位看官如果觉得文章不错,帮忙点个赞吧,对于你来说是举手之劳,但对于我来说这就是坚持下去的动力。
推荐下自己创建的Android开发 QQ群: 202928390欢迎大家的加入.
如果你想第一时间看我们的后期文章,扫码关注公众号,每周不定期推送Android开发实战教程文章,你还等什么,赶快关注吧,学好技术,出任ceo,赢取白富美。。。。
Android开发666 - 安卓开发技术分享 扫描二维码加关注
相关文章推荐
- 识设计大师(Logo Design Studio) v3.1.0.0 零售版 下载
- 基于Bootstrap实现Material Design风格表单插件 附源码下载
- iOS应用中使用Toolbar工具栏方式切换视图的方法详解
- Android TabLayout(选项卡布局)简单用法实例分析
- 【MaterialEditText】 Material Design 的 EditText 3ff8
- Android 5.0新特性ToolBar
- TabLayout 与 FragmentTabHost
- 使用tablayout 打造高度不一样的tab
- 开源硬件的价值评估
- 基于Bootstrap实现Material Design风格表单插件 附源码下载
- 《Design patterns》读书笔记
- Eclipse中批量改变文件的默认打开方式
- CPU显卡内存与3DMAX渲染的关系
- Design Pattern 新解
- 39_03_Linux集群系列之十三——高可用集群之corosync基础概念及安装配置(笔记)
- 20个漂亮的单页传单设计欣赏
- 转 C ++书单
- 单例分享(循环引用及内存占用解决)
- 。「设计营商周」每年均吸引来自设计、商界、中小企及教育界等全球优秀的设计精英汇聚香港
- 「设计营商周论坛」,非常荣幸邀请到多位国际知名大师级讲者出席