title: 带你实现开发者头条APP(三) 首页实现

tags: 轮播广告,ViewPager切换,圆形图片

grammar_cjkRuby: true

一.前言

今天实现开发者头条APP的首页。是本系列的第三篇文章,效果图如下:

从gif动态效果图中我们可以看出,最外层有三个tab(精选,订阅,发现),在精选界面顶部有一个轮播的图片广告,广告下面是一个精选文章列表。

二.外层三个tab实现

我这里用Viewpager实现的,可以左右滑动,灵活的隐藏下面fragment的显示隐藏。

1.布局文件

布局文件比较简单,上面包涵三个TextView的RelativeLayout + 下面的ViewPager

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white_normal"> <RelativeLayout
android:id="@+id/ll_title"
android:layout_width="match_parent"
android:layout_height="44dp" > <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/main_color"
android:orientation="horizontal" > <TextView
android:id="@+id/tv_selected"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:gravity="center_horizontal"
android:text="精选"
android:textColor="@drawable/main_title_txt_sel" /> <TextView
android:id="@+id/tv_subscribe"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:gravity="center_horizontal"
android:text="订阅"
android:textColor="@drawable/main_title_txt_sel" /> <TextView
android:id="@+id/tv_find"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:gravity="center_horizontal"
android:text="发现"
android:textColor="@drawable/main_title_txt_sel" />
</LinearLayout> <View
android:id="@+id/view_indicator"
android:layout_width="15dp"
android:layout_height="2dp"
android:layout_alignParentBottom="true"
android:background="@color/white_normal" />
</RelativeLayout> <android.support.v4.view.ViewPager
android:id="@+id/viewpager_home"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/ll_title"/>
</RelativeLayout>

2.初始化三个Fragment 并且填充到ViewPager,给ViewPager设置改变监听。

		vPager = (ViewPager) rootView.findViewById(R.id.viewpager_home);

		SelectedFragment selectedFragment=new SelectedFragment();
SubscribeFragment subscribeFragment=new SubscribeFragment();
FindFragment findFragment=new FindFragment(); list.add(selectedFragment);
list.add(subscribeFragment);
list.add(findFragment); adapter = new FragmentAdapter(getActivity().getSupportFragmentManager(),list);
vPager.setAdapter(adapter);
vPager.setOffscreenPageLimit(2);
vPager.setCurrentItem(0);
vPager.setOnPageChangeListener(pageChangeListener);

3.FragmentAdapter.java

继承FragmentStatePagerAdapter,Viewpager填充适配器,实现起来很简单。

/**
* ViewPager适配器
* @author ansen
* @create time 2016-04-18
*/
public class FragmentAdapter extends FragmentStatePagerAdapter {
private List<Fragment> list; public FragmentAdapter(FragmentManager fm, List<Fragment> list) {
super(fm);
this.list = list;
} public FragmentAdapter(FragmentManager fm) {
super(fm);
} @Override
public Fragment getItem(int arg0) {
return list.get(arg0);
} @Override
public int getCount() {
return list.size();
}
}

4.指示器初始化

当我们Viewpager滑动的时候需要滑动指示器,并且指示器的宽度占屏幕的三分之一,所以我们需要在activity创建的时候给指示器赋值哦,并且移动到起始位置。

 private void initCursorPosition(){
LayoutParams layoutParams=viewIndicator.getLayoutParams();
layoutParams.width=screenWidth/3;
viewIndicator.setLayoutParams(layoutParams); TranslateAnimation animation = new TranslateAnimation(-screenWidth/3,0,0,0);
animation.setFillAfter(true);
viewIndicator.startAnimation(animation);
}

5.Viewpager切换时应该做什么?

1).移动指示器

2).改变文字颜色

3).设置当前选中,指示器移动的时候需要用到。

    private OnPageChangeListener pageChangeListener=new OnPageChangeListener() {
@Override
public void onPageSelected(int index){
translateAnimation(index);//移动指示器
changeTextColor(index);//改变文字颜色
currentIndex=index;//设置当前选中
} @Override
public void onPageScrolled(int arg0, float arg1, int arg2) {} @Override
public void onPageScrollStateChanged(int arg0) {}
};

6.指示器移动方法translateAnimation

传入一个下标判断当前位置,然后判断上次的位置,知道从哪里移动到哪个位置,然后开启android自带的移动动画。

	private void translateAnimation(int index){
TranslateAnimation animation = null;
switch (index){
case 0://订阅->精选
animation=new TranslateAnimation((screenWidth/3),0,0,0);
break;
case 1://
if(0==currentIndex){//精选->订阅
animation=new TranslateAnimation(0,screenWidth/3,0,0);
}else if(2==currentIndex){//发现->订阅
animation=new TranslateAnimation((screenWidth/3)*2,screenWidth/3,0,0);
}
break;
case 2://订阅-》发现
animation=new TranslateAnimation(screenWidth/3,(screenWidth/3)*2,0,0);
break;
}
animation.setFillAfter(true);
animation.setDuration(300);
viewIndicator.startAnimation(animation);
}

7.获取屏幕宽高

我这边把方法写在activity里面,在工作中大家最好把他放到工具类里面。

	private void getScreenSize(Activity context) {
DisplayMetrics dm = new DisplayMetrics();
context.getWindowManager().getDefaultDisplay().getMetrics(dm);
screenWidth = dm.widthPixels;
screenHeight = dm.heightPixels;
}

三."精选" Fragment实现

从整体来看,就是一个ListView,顶部轮播是ListView的头部。头部轮播也是用的ViewPager实现,起始这里跟我们第一篇文章讲的开发者头条APP启动页实现原理很相似。然后再加一个定时器隔一段时间设置ViewPager的当前页面即可。

说明:我们这里的图片用的是静态的,一个商业APP轮播图片肯定是从服务器获取的,开发者头条app就是从服务器获取。

1.头布局文件

就是一个ViewPager+装载点点点的LinearLayout 然后外层布局设置一个高度200dp

<?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" > <RelativeLayout
android:layout_width="wrap_content"
android:layout_height="200dp" > <android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" /> <TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp"
android:layout_marginLeft="5dp"
android:text="公众号:ansen_666" /> <RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" > <LinearLayout
android:id="@+id/viewGroup"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="5dp"
android:gravity="center_horizontal"
android:orientation="horizontal"/>
</RelativeLayout>
</RelativeLayout>
</LinearLayout>

2.可滑动的静态图片实现

初始化轮播的Viewpager,初始化点点点View,并且加入线性布局,最后把整个布局加入ListView头部。

viewPager = (ViewPager)headView.findViewById(R.id.viewpager);
selectedPagerAdapter=new SelectedPagerAdapter(getActivity(),carousePagerSelectView);
viewPager.setOffscreenPageLimit(2);
viewPager.setCurrentItem(0);
viewPager.setOnPageChangeListener(onPageChangeListener);
viewPager.setAdapter(selectedPagerAdapter); ViewGroup group = (ViewGroup) headView.findViewById(R.id.viewGroup);// 初始化底部显示控件
tips = new ImageView[3];
for (int i = 0; i < tips.length; i++){
ImageView imageView = new ImageView(getActivity());
if (i == 0) {
imageView.setBackgroundResource(R.drawable.page_indicator_focused);
} else {
imageView.setBackgroundResource(R.drawable.page_indicator_unfocused);
} tips[i] = imageView;
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
layoutParams.leftMargin = 10;// 设置点点点view的左边距
layoutParams.rightMargin = 10;// 设置点点点view的右边距
group.addView(imageView, layoutParams);
}
listView=(ListView) rootView.findViewById(R.id.list);
listView.addHeaderView(headView);

3.如何实现轮播效果

我这边是用Timer+Handler实现,Timer用来计时,Handler用来更新UI。

注意事项:

1).在轮播的时候需要判断是否已经最后一页

2).更新UI需要在主线程。

	private Timer timer;
private final int CAROUSEL_TIME = 3000;//滚动间隔
timer = new Timer(true);//初始化计时器
timer.schedule(task, 0, CAROUSEL_TIME);//延时0ms后执行,3000ms执行一次
	TimerTask task = new TimerTask() {
public void run() {
handler.sendEmptyMessage(CAROUSEL_TIME);
}
};
	private Handler handler=new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case CAROUSEL_TIME:
if(currentIndex>=tips.length-1){//已经滚动到最后,从第一页开始
viewPager.setCurrentItem(0);
}else{//开始下一页
viewPager.setCurrentItem(currentIndex+1);
}
break;
}
};
};

4.其他

还有精品列表ListView列表的适配器,还有三个Tab点击改变文字颜色,还有显示圆形头像自定义的View,还有其他的一些布局文件的代码我就不一一贴出来了。。。有需要的自行下载源码.

四.源码下载

点击下载源码

五.相关文章

带你实现开发者头条(一) 启动页实现

带你实现开发者头条(二) 实现左滑菜单

**推荐下自己创建的Android开发 QQ群: 202928390欢迎大家的加入. **

如果你想第一时间看我们的后期文章,扫码关注公众号,每周不定期推送Android开发实战教程文章,你还等什么,赶快关注吧,学好技术,出任ceo,赢取白富美。。。。

      Android开发666 - 安卓开发技术分享
扫描二维码加关注

带你实现开发者头条APP(三) 首页实现的更多相关文章

  1. 带你实现开发者头条APP(四)---首页优化(加入design包)

    title: 带你实现开发者头条APP(四)---首页优化(加入design包) tags: design,Toolbar,TabLayout,RecyclerView grammar_cjkRuby ...

  2. 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载

    title: 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载 tags: -RecyclerView,下拉刷新,上拉加载更多 grammar_cjkRuby: true - ...

  3. 独立的android开发者开发app如何盈利?

    对立android开发者开发app如何盈利?android开发日益兴隆,随着google的大力推广和技术及其android培训的支持,android个人开发者或者android独立开发者也都匆匆欲动加 ...

  4. jq+swiper 实现今日头条App的选项卡效果

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  5. Selenium实战脚本集(4)--简单的开发者头条客户端

    描述 去开发者头条抓取本日的top 10内容,也就是排在前面的10个,需要抓取标题和url 将这些内容保存在数据库,推荐使用sqlite 写个简单的客户端,要求可以展示每日的内容,点击标题后可以打开浏 ...

  6. margin标记可以带一个、二个、三个、四个参数,各有不同的含义。

    margin标记可以带一个.二个.三个.四个参数,各有不同的含义. margin: 20px;(上.下.左.右各20px.) margin: 20px 40px;(上.下20px:左.右40px.) ...

  7. 带状态论文粗读(三)[引用openstate的相关论文阅读]

    一 文章名称:FLOWGUARD: Building Robust Firewalls for Software-Defined Networks 发表时间:2014 期刊来源:--- 解决问题: 一 ...

  8. android仿今日头条App、多种漂亮加载效果、选择器汇总、记事本App、Kotlin开发等源码

    Android精选源码 android漂亮的加载效果 android各种 选择器 汇总源码 Android仿bilibili搜索框效果 Android记事本app.分类,涂鸦.添加图片或者其他附件 仿 ...

  9. Vue(小案例_vue+axios仿手机app)_首页(底部导航栏+轮播图+九宫格)

    ---恢复内容开始--- 一.前言                        1.底部导航(两种做法)                                         2.轮播图 ...

随机推荐

  1. 【.net 深呼吸】细说CodeDom(4):类型定义

    上一篇文章中说了命名空间,你猜猜接下来该说啥.是了,命名空间下面就是类型,知道了如何生成命名空间的定义代码,之后就该学会如何声明类型了. CLR的类型通常有这么几种:类.接口.结构.枚举.委托.是这么 ...

  2. SQL Server技术内幕笔记合集

    SQL Server技术内幕笔记合集 发这一篇文章主要是方便大家找到我的笔记入口,方便大家o(∩_∩)o Microsoft SQL Server 6.5 技术内幕 笔记http://www.cnbl ...

  3. ExtJS 4.2 组件介绍

    目录 1. 介绍 1.1 说明 1.2 组件分类 1.3 组件名称 1.4 组件结构 2. 组件的创建方式 2.1 Ext.create()创建 2.2 xtype创建 1. 介绍 1.1 说明 Ex ...

  4. Laravel Composer and ServiceProvider

    Composer and: 创建自定义类库时,按命名空间把文件夹结构组织好 composer.json>autoload>classmap>psr-4 composer dump-a ...

  5. Electron使用与学习--(页面间的通信)

    目录结构: index.js是主进程js. const electron = require('electron') const app = electron.app const BrowserWin ...

  6. ASP.NET MVC5+EF6+EasyUI 后台管理系统(64)-补充WebApi与Unity注入-配置文件

    系列目录 上一篇演示了WebApi利用Unity注入 很多人问我如何用配置文件来配置注入,本节演示如何利用配置文件来注入,道理是一样的,跳转到上一节下载源码一起来动手! 1.打开源码定位到文件Depe ...

  7. angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用

    今天我们要讲的是ng2的路由系统. 例子

  8. python与c互相调用

    虽然python开发效率很高,但作为脚本语言,其性能不高,所以为了兼顾开发效率和性能,通常把性能要求高的模块用c或c++来实现或者在c或c++中运行python脚本来处理逻辑,前者通常是python中 ...

  9. cocos2dx调用浏览器打开网址

    安卓端cocos2dx/platform/android路径下CCApplication.h: virtual void openURL(const char* pszUrl); CCApplicat ...

  10. 张小龙宣布微信小程序1月9日发布,并回答了大家最关心的8个问题

    2016 年 12 月 28 日,张小龙在微信公开课 PRO 版的会场上,宣布了微信小程序的正式发布时间. 微信小程序将于 2017 年 1 月 9 号正式上线. 同时他解释称,小程序就像PC时代的网 ...