Android开发——ViewPager、项目相关

原创 2015年11月18日 00:52:26

ViewPager

1.PagerAdapter抽象类

Public Methods
abstract int getCount()
获取适配器中适配数据的个数
abstract boolean isViewFromObject(View view, Object object)
是否复用当前view对象
Object instantiateItem(ViewGroup container, int position)
加载指定位置对象用来显示每个条目,会预加载前后两个位置的条目。参数1:就是ViewPager对象;参数2:位置
void destroyItem(ViewGroup container, int position, Object object)
移除指定位置的条目。参数1:就是ViewPager对象;参数2:位置;参数3:就是当前的Item中添加的对象

2.ViewPager小知识

2.1 轮播图自动切换下一张的实现方法

(1)建立线程,通过while(true)无限循环,循环体每一次设置ViewPager.setCurrentPager()是下一页即可。通过标记来结束无限循环。

(2)通过handler机制,执行一个延时的任务postDelayed,任务中的逻辑即修改指向当前页索引值的变量指向下一页并且发送一个空消息,然后再在handleMessage()方法中更新ViewPager当前页并且再次执行此延迟的任务,即可无限的循环轮播图。结束任务通过handler的removeCallbacksAndMessages(null)方法,移除Handler中维护的任务

项目相关

1.屏幕适配

记住:效果图设计原则

(1)小图————(按照800x480[5:3]效果图去设计)放到大屏幕手机1280x720[16:9]中会与多少的变形,不过完全看不出来

(2)大图————(平铺满手机的一张图片)单独截取,分别给这两个比例屏幕的手机分别制作一张大图

1.1 图片适配

特点:不同像素密度的手机,加载不同资源文件夹下的图片

注意:如果以下5文件夹某个下没有图片时,对应屏幕的手机加载图片时将会使用更大分辨率文件下的图片

<1>.ldpi————low:320x240屏幕手机加载的图片

<2>.mdpi————middle:480x320屏幕手机加载的图片

<3>.hdpi————high:800x480屏幕手机加载的图片

<4>.xhdpi————xhigh:1280x720屏幕手机加载的图片

<5>.xxhdpi————xxhigh:1920x1080屏幕手机加载的图片

像素密度;每一英寸上面分布像素点的个数

计算样例:5英寸1280x720手机像素密度————Math.sqrt(1280*1280+720*720)/5(单位:dpi ppi)

适配规则:适配不同资源文件夹下的图片是根据手机屏幕像素密度值来确定的,像素密度值根据下表越接近谁就适配哪个资源文件夹的图片


1.2 dimens.xml适配

特点:不同像素密度的手机,加载不同dimens.xml文件

注意:dp能进行完全适配吗?答案是不能,一般在xhdpi手机中不能达到预想效果,所以这里我们需要进行dimens适配

知识点:dp与px的转换公式如下图:计算举例————xhdpi的1dp=2px;ldpi的1dp=0.75px


使用方法:在res目录下创建【values-1280x720】目录,创建demens.xml文件,并且把需要进行demens适配的控件值设置为demens文件索引值,这样既可在不同分辨率下加载不同values目录下的demens.xml文件

1.3 布局layout适配

特点:不同像素密度的手机,加载不同的布局文件)给不同的手机,写一套完全不同的布局

使用方法:在res目录下创建【layout-1280x720】目录,然后再创建相应的布局文件,这样在不同手机分辨率下就会加载相应的布局文件

1.4 Java代码适配

特点:获取屏幕的宽高像素值,然后根据不同屏幕宽高像素的比例,如屏幕宽度的一半这种,分配给控件,来达到屏幕适配效果

1.5 权重适配

特点:剩余空间的分配规则(按照百分比分配空间,类似java代码适配)

2.三种常用项目布局结构

2.1 tabhost+activity(过时)

注:可能会维护相关项目

2.2 fragment数据适配器+RadioGroup

  1. public class HomeActivityFragment extends FragmentActivity {  
  2.   
  3.     private int index = 0;  
  4.     //创建Fragment适配器,并且把每个选择的Item与相应的Fragment界面对象  
  5.     private FragmentPagerAdapter adapter = new FragmentPagerAdapter(getSupportFragmentManager()) {  
  6.   
  7.         @Override  
  8.         public int getCount() {  
  9.             return 5;  
  10.         }  
  11.   
  12.         @Override  
  13.         public Fragment getItem(int position) {  
  14.             Fragment fragment = null;  
  15.             switch (position) {  
  16.             case 0:  
  17.                 fragment = new HomeFrament();  
  18.                 break;  
  19.             case 1:  
  20.                 fragment = new NewCenterFragment();  
  21.                 break;  
  22.             case 2:  
  23.                 fragment = new SmartServiceFragment();  
  24.                 break;  
  25.             case 3:  
  26.                 fragment = new GovaffairsFragment();  
  27.                 break;  
  28.             case 4:  
  29.                 fragment = new SettingFragment();  
  30.                 break;  
  31.             }  
  32.   
  33.             return fragment;  
  34.         }  
  35.     };  
  36.   
  37.     @Override  
  38.     protected void onCreate(Bundle savedInstanceState) {  
  39.         super.onCreate(savedInstanceState);  
  40.         setContentView(R.layout.fragment_content);  
  41.   
  42.         RadioGroup rg_fragment_content = (RadioGroup) findViewById(R.id.rg_content);  
  43.         final RelativeLayout rl_content = (RelativeLayout) findViewById(R.id.vp_content);  
  44.   
  45.         //单选按钮组的点击事件  
  46.         rg_fragment_content.setOnCheckedChangeListener(new OnCheckedChangeListener() {  
  47.   
  48.             @Override  
  49.             public void onCheckedChanged(RadioGroup group, int checkedId) {  
  50.                 switch (checkedId) {  
  51.                 case R.id.rb_home:  
  52.                     index = 0;//设置选择的id,要与Fragment适配器中每个Fragment位置索引值相对应  
  53.                     break;  
  54.                 case R.id.rb_newscenter:  
  55.                     index = 1;  
  56.                     System.out.println(index);  
  57.                     break;  
  58.                 case R.id.rb_smartservice:  
  59.                     index = 2;  
  60.                     break;  
  61.                 case R.id.rb_govaffairs:  
  62.                     index = 3;  
  63.                     break;  
  64.                 case R.id.rb_settings:  
  65.                     index = 4;  
  66.                     break;  
  67.                 }  
  68.   
  69.                 // 其实就是调用fragment数据适配器中的getItem()方法  
  70.                 Fragment fragment = (Fragment) adapter.instantiateItem(rl_content, index);  
  71.   
  72.                 // 根据索引获取framgent后,做替换帧布局的操作,前两个参数没有意义,按照这个值去传递即可  
  73.                 adapter.setPrimaryItem(null0, fragment);  
  74.   
  75.                 // 更新数据,参数也没有意义,传入null即可  
  76.                 adapter.finishUpdate(null);  
  77.             }  
  78.         });  
  79.         rg_fragment_content.check(R.id.rb_home);//选中首页  
  80.     }  
  81. }  

问题:这样设置还有一个错误,显示了一个Fragment,而之前显示的Fragment未消失,两个或者多个Fragment相重叠

解决:在BaseFragment中添加以下方法,该方法将会在FragmentPageAdapter相关方法中被自动调用

  1. public void setMenuVisibility(boolean menuVisible) {  
  2.     if (getView()!=null) {//getView方法返回的是onCreateView的返回值ֵ  
  3.         getView().setVisibility(menuVisible?View.VISIBLE:View.GONE);  
  4.     }  
  5.       
  6.     super.setMenuVisibility(menuVisible);  
  7. }  

2.3 Viewpager+RadioGroups

注意:

<1>.在点击单选按钮时通过setCurrentPager()设置ViewPager当前所在页

<2>.取消ViewPager的预加载和滑动的功能,因为我们不需要滑动并且不能再此页面时加载下一页面的数据来消耗流量

实现:

<1>.设置ViewPager中DEFAULT_OFFSCREEN_PAGES值为0,这样就会取消预加载功能

<2>.设置自定义ViewPager,让其不拦截,不处理即可,就是onInterceptTouchEvent和OnTouchEvent()返回都是false

3.实际开发要点

(1)开发一个应用,如果在业务逻辑都没有走通时开发,不可能在短时间内开发一个应用的,产品的需求问题导致了开发延期,而且还可能因为程序员与产品的交流不到位问题,导致开发延期——如产品的需求你无法完成,而且你没有去交流还是死撑。如果已经有IOS部门已经把全部逻辑都走通,你只需照样子在实现一遍,那么可以在2-3周内完成一个应用,写的可以快一些。
(2)公司一定要以解决问题为核心,问题解决完在去管责任的问题

4.图片的三级缓存

步骤:
<1>.从内存中获取,就是从LRU算法维护的内存中获取图片,如果获取到将不再执行之后的获取逻辑
<2>.从内存中获取不到,将尝试从文件中获取,文件中存储图片的图片名一般采用图片文件MD5加密后字符串取前10位。并且获取完毕向LRU内存中存储一份
<3>.从文件中也获取不到,在联网获取,并且向内存和文件中各存储一份

4.1 LruCache<K, V>类

解释:K————存储数据的标识;V————存储数据的类型
特点:如果添加一个数据超出了此对象维护的内存大小,移除最近最少使用的数据,来保证内存大小不超出范围
Public Constructors
LruCache(int maxSize)
参数:LRU算法可操作的最大内存,一般参数值都是运行内存的1/8。构造该对象时必须复写一个sizeOf方法,来告诉系统该减去多大的内存空间
Public Methods
int sizeOf(K key, V value)
protected,计算出存储每条数据的大小。如果是图片的value,可用value.getRowBytes().value.getHeight();计算该图片的大小
final V put(K key, V value)
存储一个数据到LRU算法维护的内存中
final V get(K key)
获取LRU算法中维护的一个数据

4.2 Executors类

注:线程池相关类,可以自动维护线程到线程池
Public Methods
static ExecutorService newFixedThreadPool(int nThreads)
初始化线程池,并且线程池中可用线程的个数,并且线程个数计算公式是(2*cpu数+1)

4.3 ExecutorService接口

Public Methods
abstract void execute(Runnable command)
运行一个子线程,并且把该子线程维护到线程池中

5.AsyncTask<Params, Progress, Result>抽象类

作用:异步任务,可以把需要异步执行的任务逻辑定义在该类中

Protected Methods
void onPreExecute()
protected.请求网络,耗时操作的预备方法,可以把初始化进度条的操作定义在该方法中。在主线程中运行
abstract Result doInBackground(Params... params)
protected.耗时操作,请求网络或者访问数据库。此方法参数类型是第一个泛型的类型,返回值类型是第三个泛型的类型。在子线程中执行
void onPostExecute(Result result)

protected.耗时操作以后调用的方法,该方法的参数就是接受的doInBackground()方法的返回值。此方法参数类型是第三个泛型的类型。在主线程中执行。

static void execute(Runnable runnable)
把异步任务所需参数传入该对象中

6.新闻项目知识点

(1)内容页和菜单页布局不写死,而预设成一个FrameLayout布局的原因是考虑到项目的扩展性,只是起到占位的作用,可以以后随意添加任意Fragment来替换

(2)考虑到每个页面都有界面展示效果并且都需要向网络获取数据,所以定义一个initView和initData方法,并且定义一个页面的基类

(3)因为取消了预加载功能,所以应该在每一个Pager的滑动监听事件中请求网络加载数据,就是当页被选中时调用initData()方法

(4)自定义加强ViewPager虽然复写了dispatchTouchEvent()方法,可以返回值依然是super.dispatchTouchEvent(ev),所以只是进行了加强,没有修改底层事件传递的机制,所以事件可以传递到最里面的ImageView控件

(5)点中轮播图时,要停止轮播图的自动滚动;抬起和cancel时要再次开启轮播图的滚动;cancel中开启的原因是因为轮播图切换图片会达到cancel状态,而没有抬起事件

(6)为了不让图片不失帧并且显示完全,应该测量自定义控件图片的大小,然后按照比例显示

项目相关框架

1.侧滑栏SlidingMenu

1.1 SlidingFragmentActivity类

Public Methods
void setBehindContentView(int resourseId)
预设Sliding侧拉栏的布局文件
void setBehindContentView(View view)

从ProgressBar继承的方法,获取进度的最大值

SlidingMenu getSlidingMenu()

获取侧拉栏对象

1.2 SlidingMenu类

Public Methods
void setBehindWidth(int width)
设置侧滑栏宽度,单位像素
void setBehindWidthRes(int res)

设置侧滑栏宽度,通过资源文件索引

void setBehindOffset(int width)

设置内容页的宽度

void setBehindOffsetRes(int resID)

设置内容页的宽度,通过资源文件索引

void setMode(int mode)

设置侧滑栏的模式,就是滑出的方向,值有SlidingMenu.LEFT、SlidingMenu.RIGHT、SlidingMenu.LEFT_RIGHT

void setShadowDrawable(int resID)
设置分割线背景,可以用shape图形
void setShadowWidth(int width)

设置分割线宽度

void setShadowWidthRes(int resId)

设置分割线官渡,通过资源文件索引

void setTouchModeAbove(int touchMode)

设置侧滑栏滑出方式,方式有SlidingMenu.TOUCHMODE_FULLSCREEN(全屏可拖拽)、SlidingMenu.TOUCHMODE_MARGIN(边缘可拖拽)、SlidingMenu.TOUCHMODE_MARGIN(全屏不可拖拽)

void toggle()

弹回侧滑栏

void setSecondaryMenu(View v)

设置第二个侧滑栏,需要设置滑出模式为LEFT_RIGHT

void setSecondaryMenu(int res)

设置第二个侧滑栏,通过资源文件索引,需要设置滑出模式为LEFT_RIGHT

2.常用工具集xUtils

2.1 HttpUtils类

Public Methods
HttpHandler<T> send(HttpMethod method, String url, RequestParams params, RequestCallBack<T> callBack)
发送一个请求。参数1:请求方式,传入请求枚举值;参数2:请求的地址;参数3:请求的参数,请求参数类似键值对;参数4:请求结果的回调
HttpHandler<T> send(HttpMethod method, String url, RequestCallBack<Object> callBack)
发送一个请求。参数1:请求方式,传入请求枚举值;参数2:请求的地址;参数4:请求结果的回调
ResponseStream sendSync(HttpMethod method, String url) 
此方法用用写内部类,直接返回封装数据的对象。参数1:请求的方式;参数2:请求的地址

2.2 RequestParams类

Public Methods
void addBodyParameter(String name,String value)
添加一个请求参数。参数1:参数name;参数2:参数值
void addBodyParameter(List<NameValuePair> nameValuePairs)
添加多个请求参数

2.3 RequestCallBack抽象类

Public Methods
void onSuccess(ResponseInfo<String> responseInfo)
当请求成功时回调此方法,参数:存储了服务端返回数据的对象
void onFailure(HttpException error, String msg)
当请求失败时回调此方法,参数1:请求的错误异常;
void onLoading(long total, long current, boolean isUploading)
在请求过程中将多次回调此方法。参数1:请求数据总大小;参数2:现阶段请求数据量

2.4 ViewUtils类

Public Methods
static void inject(Object handler, View view)
注解关联此对象中的View布局
static void inject(Activity activity) 
注解关联一个Activity对象,将自动关联其对应的布局文件

2.5 BitmapUtils类

注:其中维护了三级缓存的机制

Public Methods
void display(ImageView container, String uri)
从uri获取图片,并且显示在指定container控件上

3.Json解析框架Gson

Public Methods
T fromJson(String json, Class<T> classOfT)
解析json数据,返回对应的JavaBean对象。参数1:目标需解析的Json串;参数2:JavaBean对象的字节码文件对象
注意:JavaBean对象中建立原则:数组元素建立集合;对象元素就建立成一个对象;变量名必须与json中的名称相同

4. Tab指针框架

4.1 TabPageIndicator类

注意:为了让TabPageIndicator显示头信息,需要在ViewPager的Adapter适配器对象中创建一个public CharSequence getPageTitle(int position)方法,返回值就是TabPageIndicator显示的头字符。
Public Methods
void setViewPager(ViewPager view)
设置指针关联的ViewPager
void notifyDataSetChanged()
刷新指针,当PagerAdapter变化时需要刷新指针,指针才会变换

版权声明:本文为博主原创文章,未经博主允许不得转载。

学徒浅谈Android开发:第一讲——滑屏效果的实现ViewPager+Fragment

b
  • lz8362
  • lz8362
  • 2014年04月09日 20:53
  • 840

主要介绍和Android开发工具和测试工具相关的开源项目

主要介绍和Android开发工具和测试工具相关的开源项目。 http://www.eoeandroid.com/blog-1153322-48531.html Buck faceboo...

Android开发相关——Retrofit+RxJava+OkHttp(下)使用

上一篇闲扯过后,算是将我为什么会把Retrofit说出来了吧(虽然好像什么都没说),当然还有其他框架,作为一个懒人,我这里就不加以阐述了,还是进入整体,开始进入我们的使用的部分。 还是先上我的Git...

android开发——.so文件相关知识点

一、为什么你需要重点关注.so文件如果项目中使用到了NDK,它将会生成.so文件,因此显然你已经在关注它了。如果只是使用Java语言进行编码,你可能在想不需要关注.so文件了吧,因为Java是跨平台的...

android开发相关——github版本控制

至于为什么要用这个,我还是要吐槽一下的,因为之前我的项目都是传到了码云上的,可是身边朋友一直推荐我使用git来做版本控制;而且之前查的码云上提交代码的安全性之类的问题还没有得到认可;最后就是,当前的企...

Android开发相关——Log日志输出显示不完整以及GsonFormat

不知道大家在开发过程中有没有遇到过这种尴尬,那就是我们想要看打印日志信息的时候,命名日志信息全都得到了,可是当我们在Android Monitor中查看的时候,却在关键的地方戛然而止,那种感觉别提多难...

Android开发相关的优秀Blog推荐——站在巨人的肩膀上

本篇文章主要纪录我在学习过程中,发现的非常给力的CSDNBlog和个人Blog,这些Blog都有一个共同的特点,即内容详实,讲解透彻,也算是给后来的初学者指一条路吧!只要你下定决心跟随强者的脚步,成为...

Android开发——Activity销毁时异步任务的保存和恢复、以及相关的进度条的显示问题

0.  前言在Android开发——Fragment知识整理(二)中我们提到了使用Fragment保存Activity销毁重建时的数据,但是有一个问题是,在异步任务时旋转屏幕,如何处理异步任务呢?如果...

Android开发相关——Retrofit+RxJava+OkHttp(上)闲扯

这篇主要是分析一下我用过的一些框架,借机传达一些个人在开发中的一些小意见,没有兴趣的可以直接跳过。...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android开发——ViewPager、项目相关
举报原因:
原因补充:

(最多只允许输入30个字)