带你实现开发者头条APP(三) 首页实现
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(三) 首页实现的更多相关文章
- 带你实现开发者头条APP(四)---首页优化(加入design包)
title: 带你实现开发者头条APP(四)---首页优化(加入design包) tags: design,Toolbar,TabLayout,RecyclerView grammar_cjkRuby ...
- 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载
title: 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载 tags: -RecyclerView,下拉刷新,上拉加载更多 grammar_cjkRuby: true - ...
- 独立的android开发者开发app如何盈利?
对立android开发者开发app如何盈利?android开发日益兴隆,随着google的大力推广和技术及其android培训的支持,android个人开发者或者android独立开发者也都匆匆欲动加 ...
- jq+swiper 实现今日头条App的选项卡效果
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- Selenium实战脚本集(4)--简单的开发者头条客户端
描述 去开发者头条抓取本日的top 10内容,也就是排在前面的10个,需要抓取标题和url 将这些内容保存在数据库,推荐使用sqlite 写个简单的客户端,要求可以展示每日的内容,点击标题后可以打开浏 ...
- margin标记可以带一个、二个、三个、四个参数,各有不同的含义。
margin标记可以带一个.二个.三个.四个参数,各有不同的含义. margin: 20px;(上.下.左.右各20px.) margin: 20px 40px;(上.下20px:左.右40px.) ...
- 带状态论文粗读(三)[引用openstate的相关论文阅读]
一 文章名称:FLOWGUARD: Building Robust Firewalls for Software-Defined Networks 发表时间:2014 期刊来源:--- 解决问题: 一 ...
- android仿今日头条App、多种漂亮加载效果、选择器汇总、记事本App、Kotlin开发等源码
Android精选源码 android漂亮的加载效果 android各种 选择器 汇总源码 Android仿bilibili搜索框效果 Android记事本app.分类,涂鸦.添加图片或者其他附件 仿 ...
- Vue(小案例_vue+axios仿手机app)_首页(底部导航栏+轮播图+九宫格)
---恢复内容开始--- 一.前言 1.底部导航(两种做法) 2.轮播图 ...
随机推荐
- 【AR实验室】mulberryAR : ORBSLAM2+VVSION
本文转载请注明出处 —— polobymulberry-博客园 0x00 - 前言 mulberryAR是我业余时间弄的一个AR引擎,目前主要支持单目视觉SLAM+3D渲染,并且支持iOS端,但是该引 ...
- Visual Studio 2010的MSDN帮助文档离线使用
如果没有在安装vs过程中安装帮助,也可通过Visual Studio帮助菜单中的Manage Help Settings来对帮助进行设置或安装. 可以选择从磁盘安装内容,如果选择从磁盘安装可能会要求提 ...
- .Net多线程编程—并发集合
并发集合 1 为什么使用并发集合? 原因主要有以下几点: System.Collections和System.Collections.Generic名称空间中所提供的经典列表.集合和数组都不是线程安全 ...
- Springmvc数据校验
步骤一:导入四个jar包 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...
- 如何一步一步用DDD设计一个电商网站(四)—— 把商品卖给用户
阅读目录 前言 怎么卖 领域服务的使用 回到现实 结语 一.前言 上篇中我们讲述了“把商品卖给用户”中的商品和用户的初步设计.现在把剩余的“卖”这个动作给做了.这里提醒一下,正常情况下,我们的每一步业 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统 (源码购买说明)
系列目录 升级日志 !!!重大版本更新:于2016-12-20日完成了系统的结构重构并合并简化了T4(这是一次重要的更新,不需要修改现有功能的代码),代码总行数比上个版本又少了1/3.更新了代码生成器 ...
- JavaScript之职责链模式
一.概述 职责链模式(Chain of responsibility),就是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到有 ...
- 9、委托、事件、Lambda
开始 关于委托,肯定是要有问题的. 第一个问题,委托用来干什么? 看.net中的表述:在.net平台下,委托类型用来定义和相应应用程序中的回调.(回调?处理内存中两个实体双向通信的一种技术.) 第 ...
- 关于font-family
在设置页面字体的时候,你会发现在 font-family 属性中会设置好多个字体,想看懂它们都是什么字体吗?不好意思,我不是搞设计的,我也不知道.那么,现在写的东西,只是对于一个前端人员来说,要了解的 ...
- 介绍一款原创的四则运算算式生成器:CalculateIt2
家里小朋友读一年级了,最近每天都有一些10以内的加减法口算练习,作为程序员爸爸,自然也是想办法能够偷懒,让电脑出题,给小朋友做些练习.于是,自己在业余时间开发了一个四则运算算式生成器,名为:Calcu ...