转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/17201587

介绍

在android应用中,多屏滑动是一种很常见的风格,博主之前也写过一些多屏滑动的demo,比如滚动banner(http://blog.csdn.net/singwhatiwanna/article/details/8875241)和仿tabhost的控件。这次给大家介绍一种效果更好的风格:带滚动条的多屏滑动,类似于google play里面的风格。如果你看过我之前写的banner,你就会发现那个banner是原生的,没有采用viewpager啥的,所以代码很长,如果采用ViewPager,代码就会短很多,但是使用ViewPager也有弊端:需要导入android-support-v4.jar、细节无法控制。不过现在情况已经不一样了,android-support-v4中提供了很多实用的功能,以至于现在新建一个android工程默认都会导入这个jar包。那我们就也采用viewpager来做滑动吧。另外一个概念就是Fragment和FragmentActivity,Fragment是一个特殊的类,有着和activity一致的生命周期和view一致的界面,也就是Fragment就等于具有生命周期的View,但是,要注意的是:Fragment并不是View,它和View没有继承关系。使用Fragment的好处是:Fragment可以重用,而且每个Fragment可以在内部处理自己的业务就像activity一样,这样模块间耦合较低,比把所有的业务都写在一个activity内部逻辑要清晰很多。还有就是,由于每个模块的业务都在Fragment内部来实现,这样activity只要管理好几个Fragment就行了,不需要做和业务相关的事情,最后,Fragment可以用来做不同分辨率机型的适配。Fragment在sdk(android 3.0及更高)和android-support-v4里面都有,但是由于兼容性的问题,我们只能使用android-support-v4里面的Fragment,除非你想你的apk只跑在3.0以后的android手机上,FragmentActivity的情况和Fragment类似。关于Fragment和FragmentActivity,其实有一些基本的用法需要了解一下,但是考虑到Fragment不是本文的重点,所以这里就不介绍了,另外,本文只用Fragment做了一个简单的界面,大家应该一看就懂,好了,言归正传。

IndicatorFragmentActivity的实现过程

1 新建一个工程,目录结构如下:

2 实现ui包下的三个文件

ViewPagerCompat.java:这是一个ViewPager的加强类,主要是为了解决滑动冲突的问题。不然的话,在ViewPager内部加入ListView等可滑动控件,两者之间会产生干扰。

在这里想多说一下,关于此类问题,解决办法是:重写父控件的onInterceptTouchEvent函数,在move的时候根据需要返回true,比如左右滑动返回true,其他情况均返回false。这样,当左右滑动的时候,由于onInterceptTouchEvent返回了true,父控件就能处理,其他情况,事件将传递到listview中,listview自身可以处理上下滑动。

public class ViewPagerCompat extends ViewPager {

    //mViewTouchMode表示ViewPager是否全权控制滑动事件,默认为false,即不控制
private boolean mViewTouchMode = false; public ViewPagerCompat(Context context, AttributeSet attrs) {
super(context, attrs);
} public void setViewTouchMode(boolean b) {
if (b && !isFakeDragging()) {
//全权控制滑动事件
beginFakeDrag();
} else if (!b && isFakeDragging()) {
//终止控制滑动事件
endFakeDrag();
}
mViewTouchMode = b;
} /**
* 在mViewTouchMode为true的时候,ViewPager不拦截点击事件,点击事件将由子View处理
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (mViewTouchMode) {
return false;
}
return super.onInterceptTouchEvent(event);
} @Override
public boolean onTouchEvent(MotionEvent ev) {
try {
return super.onTouchEvent(ev);
} catch (Exception e) {
return false;
}
} /**
* 在mViewTouchMode为true或者滑动方向不是左右的时候,ViewPager将放弃控制点击事件,
* 这样做有利于在ViewPager中加入ListView等可以滑动的控件,否则两者之间的滑动将会有冲突
*/
@Override
public boolean arrowScroll(int direction) {
if (mViewTouchMode) return false;
if (direction != FOCUS_LEFT && direction != FOCUS_RIGHT) return false;
return super.arrowScroll(direction);
} }

下面两个文件代码有点多,没有粘出来,后面附有下载地址,大家可以下载下来看看,代码都做了注释的。有什么疑问欢迎交流。

TitleIndicator.java:这个一个带滚动条的选项卡,会随着viewpager的滑动而滑动,其实现思想是这样的:每个选项卡是一个view,根据需要可以add多个view也就是多个选项卡进来,选项卡下部还有一个滚动条,滚动条是用canvas画出来的。所有的invalidate方法均会触发onDraw,当页面滚动的时候,会有一个滚动距离,然后onDraw被触发后,就会在新位置重新画上滚动条(其实就是画线)。

IndicatorFragmentActivity.java:这是IndicatorFragmentActivity的主界面,用于管理上述两个view,对子类提供protected abstract int supplyTabs(List<TabInfo> tabs)接口来生成页面。

下面主要介绍下如何使用这个IndicatorFragmentActivity。

如何使用?

请按如下步骤:

1 新建一个类继承IndicatorFragmentActivity,然后实现supplyTabs抽象方法,提供生成选项卡所需的数据

public class MainActivity extends IndicatorFragmentActivity {

    public static final int FRAGMENT_ONE = 0;
public static final int FRAGMENT_TWO = 1;
public static final int FRAGMENT_THREE = 2; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
} //在这里提供数据来进行初始化
@Override
protected int supplyTabs(List<TabInfo> tabs) {
tabs.add(new TabInfo(FRAGMENT_ONE, getString(R.string.fragment_one),
FragmentOne.class));
tabs.add(new TabInfo(FRAGMENT_TWO, getString(R.string.fragment_two),
FragmentTwo.class));
tabs.add(new TabInfo(FRAGMENT_THREE, getString(R.string.fragment_three),
FragmentThree.class)); //返回的下标表示界面初始化的时候所指向的fragment的序号
return FRAGMENT_TWO;
} }

2 为每个选项卡提供fragment类

最简单的fragment,啥都不做,就加载一个layout然后初始化一个listview。其实我的demo里有3个界面一样的fragment,但是博主为了偷懒,直接写了一个BaseFragment,让它们3个都继承这个BaseFragment,反正界面都一样嘛。

public class BaseFragment extends Fragment {
protected View mMainView;
protected static ArrayList<Map<String, Object>> mlistItems;
protected Context mContext; static {
mlistItems = new ArrayList<Map<String, Object>>();
for (int i = 0; i < 20; i++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", "name#" + i);
map.put("sex", i % 2 == 0 ? "male" : "female");
mlistItems.add(map);
}
} public BaseFragment() {
super();
} @Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mContext = activity.getApplicationContext();
} @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mMainView = inflater.inflate(R.layout.fragment_one, container, false);
ListView listView = (ListView) mMainView.findViewById(R.id.list);
SimpleAdapter adapter = new SimpleAdapter(mContext, mlistItems,
R.layout.listview_item, new String[] {
"name", "sex"
}, new int[] {
R.id.name, R.id.download
});
listView.setAdapter(adapter);
return mMainView;
} }

这样就ok了,是不是挺简单的,也就是说,如果你想要这种效果的话,只要导入ui包里面的3个类,然后再按上述2个步骤去做就行了,效果也是很好的。另外就是选项卡的颜色以及滚动条的颜色都是可以调的,而且每个选项卡上面是支持显示其他标识的,比如一个小红点啥的,就类似于那种有新消息的状态。有什么问题,欢迎大家在下面留言和我交流。

代码下载:等待上传

使用ViewPager+Fragment来实现带滚动条的多屏滑动-IndicatorFragmentActivity的更多相关文章

  1. [置顶] xamarin Tablayout+Viewpager+Fragment顶部导航栏

    最近几天不忙,所以把项目中的顶部导航栏的实现归集一下.android中使用TabLayout+ViewPager+Fragment制作顶部导航非常常见,代码实现也比较简单.当然我这个导航栏是基于xam ...

  2. ViewPager+Fragment取消预加载(延迟加载)(转)

    原文:http://www.2cto.com/kf/201501/368954.html 在项目中,都或多或少地使用的Tab布局,所以大都会用到ViewPager+Fragment,但是Fragmen ...

  3. Android中ViewPager+Fragment取消(禁止)预加载延迟加载(懒加载)问题解决方案

    转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53205878本文出自[DylanAndroid的博客] Android中Vie ...

  4. Android - ViewPager+Fragment初始化问题

    Android应用开发中,经常会用到ViewPager + Fragment,虽然效果不错,但随之而来的还有一些问题,下面就说说其中的初始化问题. ViewPager初始化时会预加载前后的2个页面,即 ...

  5. Android ViewPager Fragment使用懒加载提升性能

     Android ViewPager Fragment使用懒加载提升性能 Fragment在如今的Android开发中越来越普遍,但是当ViewPager结合Fragment时候,由于Androi ...

  6. ViewPager -- Fragment 切换卡顿 性能优化

    当ViewPager切换到当前的Fragment时,Fragment会加载布局并显示内容,如果用户这时快速切换ViewPager,即 Fragment需要加载UI内容,而又频繁地切换Fragment, ...

  7. viewpager viewpager+fragment

    内页面  不单写页面   viewpager+布局 import java.util.ArrayList; import java.util.List; import android.os.Bundl ...

  8. 【原创】【ViewPager+Fragment】ViewPager中切换界面Fragment被销毁的问题分析

    ViewPager中切换界面Fragment被销毁的问题分析   1.使用场景 ViewPager+Fragment实现界面切换,界面数量>=3   2.Fragment生命周期以及与Activ ...

  9. 转:ViewPager+Fragment基本使用方法(附源码)

    ViewPager+Fragment可以做出多页面滑动效果,让我们的应用程序界面操作起来更加灵活 对于ViewPager和Fragment组件还不熟悉的朋友,可以先看看相关的资料 首先在activit ...

随机推荐

  1. 2015 UESTC Winter Training #4【Regionals 2008 :: Asia - Tehran】

    2015 UESTC Winter Training #4 Regionals 2008 :: Asia - Tehran 比赛开始时电脑死活也连不上WIFI,导致花了近1个小时才解决_(:зゝ∠)_ ...

  2. web第一节课 sql 数据库连接 查询

    1.数据库连接语句 <connectionStrings> <add name="yhotel" connectionString="Database= ...

  3. C#_DBHelper_SQL数据库操作类.

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data; ...

  4. \r \n有什么区别

    '\r'是回车,'\n'是换行,前者使光标到行首,后者使光标下移一格.通常用的Enter是两个加起来.下面转一篇文章. 回车和换行 今天,我总算搞清楚“回车”(carriage return)和“换行 ...

  5. PHP常用代码大全

    1.连接MYSQL数据库代码 <?php $connec=mysql_connect("localhost","root","root" ...

  6. Code First研究学习1_Reverse Enginner Code First

    最近因为公司需要,自己开始研究Code First,之前还是听说过这个,也知道是代码优先的意思!至于具体怎么的代码优先,我的理解如下! 在听说code  first的时候,心里也就觉得怪了,是怎么将M ...

  7. C#方法的使用

    static void Main(string[] arr) { , ); Console.WriteLine(max); Console.ReadKey(); } /// <summary&g ...

  8. apache_fileupload实现文件上传_上传多个文件

    1.导包 核心类: DiskFileItemFactory – 设置磁盘空间,保存临时文件.只是一个具类. ServletFileUpload  - 文件上传的核心类,此类接收request,并解析r ...

  9. 高放的c++学习笔记之函数基础

    局部变量 函数里面的局部变量有普通的局部变量和局部静态变量两种. 普通局部变量变量就是正常定义在函数体内部的变量,如果返回局部变量的地址,以便于函数调用结束后还继续访问此变量的话,编译器会报warni ...

  10. Backbone学习笔记

    model model的get和set是对model.attributes进行操作,并不是直接对model进行操作 collection collection.set()会触发相应的add,remov ...