版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
...wd......wd......wd...Android移动终端开发大作业作业要求1人一组,独立完成。按照个人兴趣方向,自选题目,完成系统。在规定的时间里完成系统主体功能,程序对比稳定的运行。手机界面要求简洁、美观,功能不能过于简单,应具备一定的实用性。至少要3个Activity以上。必须使用自定义Listview,要使用Sqlite数据库或API调用与数据解析〔API可使用聚合数据〔s:///〕、APIStore〔://apistore.baidu/〕或apix〔:///〕提供的API,如有能力也可自行开发服务器端〕。欢送好的创意作品、实用作品,评分时会适当加分。需提交设计报告,设计报告格式见附件,按附件顺序装订〔包括评分表〕大作业成绩从工作量、功能点、创新性、实用性、报告的字数、质量及标准度等方面的成绩构成本卷须知压缩包内作业内容包括两局部:作业工程文件夹,工程必须能够调试通过,android平台选择选择2.2或是2.3.3。作业设计说明,word文件。可以借鉴网络上的代码,但不可全部照搬。不许相互抄袭,一旦发现成绩为零。附件1:学号0121309341617成绩Android平台移动应用开发大作业题目基于Android的新闻浏览软件的设计与实现学院信息工程学院专业信息工程班级信息1303姓名杏允升指导教师秦珀石2015年12月10日TOC\o"1-3"\h\u26428一、331306二、概述414812三、关键技术521607四、概要设计628337五、系统实现716643六、心得体会8概述Android应用平台新闻客户端软件是基于Android手机平台,采用Java语言,从网络上的开放的新闻接口获取数据,设计出针对使用Android平台的手机新闻客户端资讯实时掌控的手机应用程序。Android平台新闻客户端软件的开发可以进一步扩大时事新闻的覆盖面,让广阔公众能够随时随地方便且快捷地获取最新的新闻资讯信息,了解新闻时事,本软件的广泛使用,尤其是在传授知识、普及教育方面起着非常重要的作用。目前市场研究机构Worldpanel发布了全球主要的国家智能手机操作系统在去年Q4内的分布报告,报告指出了谷歌的Android继续保持着增长的势态,但是增幅已经明显放缓了。而在另一个方面,苹果iOS操作系统在全球只能手机市场上均有下滑,个别国家的降幅甚至高达10.3%。最新统计数据中显示,Android操作系统将继续领跑全球市场,包括美国、澳大利亚、中国、意大利、英国、德国、西班牙等所占的市场比例都已经超出50%,并且还将继续呈现上涨的趋势。而在苹果iOS操作系统方面,最大的市场份额所占比的国家依旧是美国,数值为43.9%;紧随美国的那么是澳大利亚,数值为35.2%;而在中国方面,市场份额也从21.2%下降到了19%;在意大利,iOS所占的市场份额更是从23.1%猛降至12.8%。从上面的数据可以看出,Android手机软件的开发具有巨大的开展前景,在Android系统上开发出一款手机新闻客户端软件所支持的用户量也是相对比于其他系统多出很多的。谷歌的移动平台主管安迪·鲁宾(AndyRubin)表示,跟软件开发合作对象的密切接触正在进展中。Google与开放手机联盟联合开发了Android操作系统,这个联盟由摩托罗拉、高通、宏达电、中国移动和T-Mobile等在内的多家无线应用和技术的领军企业组成。Google通过与设备制造商、开发商、运营商和其他有关各方结成深层次的合作关系,希望借助建设开放式、标准化的移动移动软件平台,在移动产业内形成一个开放性的生态系统,这将是开发Android软件的一个契机,Android平台的开发在将来必定大放异彩。关键技术使用ViewPager里面添加多张图片配合线程延时实现轮播图的自没有通过ScheduledExecutorService或Timer定期执行某个任务实现,而是简单的通过handler发送消息去完成一次滚动,在完成一次滚动后发送另外一个delay的滚动消息,如此循环实现。自动滚动局部核心代码如下:至于ViewPager嵌套引起子ViewPager无法触摸问题是通过在子ViewPager的onTouchEvent中添加制止父控件对touchevent做intercept解决的。ViewPager滑动速度的设置是通过反射的方式重新设置ViewPager的Scroller,改变Scroller的startScroll的间隔时间完成的。调用setScrollDurationFactor(double)即可。2、使用(1)引入公共库引入AndroidAutoScrollViewPager@Github作为你工程的library(若何拉取代码及添加公共库)。(2)调用仅需简单两步:布局定义代替一般的ViewPager定义b.启动ViewPager自动滚动startAutoScroll()启动自动滚动stopAutoScroll()停顿自动滚动3、设置setInterval(long)设置自动滚动的间隔时间,单位为毫秒setDirection(int)设置自动滚动的方向,默认向右setCycle(boolean)是否自动循环轮播,默认为truesetScrollDurationFactor(double)设置ViewPager滑动动画间隔时间的倍率,到达减慢动画或改变动画速度的效果setStopScrollWhenTouch(boolean)当手指碰到ViewPager时是否停顿自动滚动,默认为truesetSlideBorderMode(int)滑动到第一个或最后一个Item的处理方式,支持没有任何操作、轮播以及传递到父View三种模式setBorderAnimation(boolean)设置循环滚动时滑动到从边缘滚动到下一个是否需要动画,默认为true4、其他〔1〕指示器,圆形或是方形指示器请配合ViewPagerIndicator使用〔2〕无限循环,如果希望在最后一张继续播放第一张而不是退回到第一张,请参考AutoScrollViewPagerSingleDemo.java,注意这个特性不能和ViewPagerIndicator使用2)使用viewpager结合ViewPageIndicator进展新闻类别的分类切换,可点击切换也可以滑动切换。1.ViewPagerIndicator的Library查看ViewpagerIndicator的Library代码,可以看到此工程的设计思想:
首先定义了一个PageIndicator接口,它里面定义了最重要和基本的indicator表现出的一些方法:
1.1首先一个indicator必须要与一个ViewPager关联在一起,所以它提供了一个setViewPager方法。
1.2它扩展了ViewPager.OnPageChangeListener接口,表示接收了ViewPager的Pager改变时的监听处理,
这也是为什么为ViewPager设置OnPageChangeListener监听器时不能设置在ViewPager上而必须设置在
indicator上的原因。
1.3还有一个notifyDataSetChanged通知方法,表示为这个ViewPager提供View(一般是Fragment)的
Adapter里面的数据集发生变化时,执行的动作,这里可增加相关的逻辑。2.ViewpagerIndicator的实现类
然后再看下ViewpagerIndicator的实现类,共有6个,由6个类分别实现,它们分别为:
2.1小圆圈类型的
2.2带图标类型的
2.3小横线类型的,距离屏幕最下边端有一定的距离。
2.4标签类型的〔Tab〕
2.5标题类型的,与标签类型的有点像,但它当前的标题页的左/右边的标题会卷起,即往两端缩进去。
2.6屏幕底部小横线类型的,并且会占满整行。
3.ViewpagerIndicator随附带的Demo
Demo工程的设计
工程由一个ListSamples的ListActivity入口,它主要用作组装所有的子indicator的列表。
TestFragment.java,所有ViewPager上真正显示的视图。
TestFragmentAdapter.java,所有ViewPager里的Adapter,为ViewPager生成TestFragment。
Samplexxx.java,所有的indicator的显示,一个类显示一种使用方法或特性2)使用viewpager结合ViewPageIndicator进展新闻类别的分类切换,可点击切换也可以滑动切换。3)使用Gson对新闻数据的json字符串进展解析显示到listview上需要使用jar包fastjson或gson这两个jar包。//Gson的使用方式Gsongson=newGson();Stringstr=ReadAssetsFile.readtext(this,"json_ss");//this当前类,"json_ss"需要解析的文件名UserMessageuserMessage=gson.fromJson(str,UserMessage.class);//需要解析的json文件最外层类名//fastjson的使用方法Stringjson=ReadAssetsFile.readtxt(this,"json_h");UserMessageuser=JSON.parseObject(json,UserMessage.class);自己扩展4)使用Universal-Image-Loader对图片进展缓存加载Android上最让人头疼的莫过于从网络获取图片、显示、回收,任何一个环节有问题都可能直接OOM,这个工程或许能帮到你。UniversalImageLoaderforAndroid的目的是为了实现异步的网络图片加载、缓存及显示,支持多线程异步加载。它最初来源于FedorVlasov的工程,且自此之后,经过大规模的重构和改良。特性列举:多线程下载图片,图片可以来源于网络,文件系统,工程文件夹assets中以及drawable中等支持随意的配置ImageLoader,例如线程池,图片下载器,内存缓存策略,硬盘缓存策略,图片显示选项以及其他的一些配置支持图片的内存缓存,文件系统缓存或者SD卡缓存支持图片下载过程的监听根据控件(ImageView)的大小对Bitmap进展裁剪,减少Bitmap占用过多的内存较好的控制图片的加载过程,例如暂停图片加载,重新开场加载图片,一般使用在ListView,GridView中,滑动过程中暂停加载图片,停顿滑动的时候去加载图片提供在较慢的网络下对图片进展加载使用过程:创立默认的ImageLoader,所有的操作都由ImageLoader控制。该类使用单例设计模式,所以如果要获取该类的实力,需要调用getInstance()方法。在使用ImageLoader显示图片之前,你首先要初始化它的配置,调用ImageLoaderConfiguration的init()方法,然后你就可以实现各种的显示了。自定义配置imageloader,就像你已经知道的,首先,你需要使用ImageLoaderConfiguration对象来初始化ImageLoader。由于ImageLoader是单例,所以在程序开场的时候只需要初始化一次就好了。建议你在Activity的onCreate〔〕方法中初始化。如果一个ImageLoader已经初始化过,再次初始化不会有任何效果。下面我们通过ImageLoaderConfiguration.Builder创立一个设置得到imageLoader使用过程:图像操作是否参与缓存以及图像效果的配置操作DisplayImageOptions以下是所有默认配置参数根据需求可以自定义配置〔2〕图片加载监听器在这里吧可以设置加载时的动画或者进度条之类的东西这里〔3〕简单设置就可以给ImageView添加图片了对于本地的图片,在其绝对地址前面要参加"file://"。网络图片就直接写路径了。缓存的清理:缓存的清理可以按需求来定,可以再每个Activity的生命周期函数onDestroy中清理也可以单独设置让用户自行清理。GirdView,ListView加载图片:相信大局部人都是使用GridView,ListView来显示大量的图片,而当我们快速滑动GridView,ListView,我们希望能停顿图片的加载,而在GridView,ListView停顿滑动的时候加载当前界面的图片,这个框架当然也提供这个功能,使用起来也很简单,它提供了PauseOnScrollListener这个类来控制ListView,GridView滑动过程中停顿去加载图片,该类使用的是代理模式第一个参数就是我们的图片加载对象ImageLoader,第二个是控制是否在滑动过程中暂停加载图片,如果需要暂停传true就行了,第三个参数控制猛的滑动界面的时候图片是否加载概要设计Json数据的一些返回参数名称 类型 说明 error_code int 返回码 reason string 返回说明 result string 返回结果集 title string 新闻标题 content string 新闻摘要内容 img_width string 图片宽度 full_title string 完整标题 pdate string 发布时间 src string 新闻来源 img_length string 图片高度 img string 图片链接 url string 新闻链接 pdate_src string 发布完整时间三、系统实现代码1:package.xinwen;importcom.thinkland.sdk.android.JuheSDKInitializer;importandroid.app.Application;importandroid.content.Context;importandroid.os.Handler;importandroid.os.Looper;/***@应用程序的入口*/publicclassBaseApplicationextendsApplication{ privatestaticContextmContext; privatestaticThreadmMainThread; privatestaticintmMainThreadId; privatestaticHandlermMainThreadHandler; privatestaticLoopermMainThreadLooper; @Override publicvoidonCreate(){ super.onCreate(); JuheSDKInitializer.initialize(getApplicationContext()); //在应用程序入口提供全局的工具 //上下文 mContext=this; //主线程和子线程 mMainThread=Thread.currentThread();// mMainThreadId=mMainThread.getId(); //当前应用程序进程ID// mMainThreadId=android.os.Process.myPid(); //线程idmyTid(); mMainThreadId=android.os.Process.myTid(); //用户idmyUid(); //主线程handler mMainThreadHandler=newHandler(); mMainThreadLooper=getMainLooper(); } publicstaticContextgetContext(){ returnmContext; } publicstaticThreadgetMainThread(){ returnmMainThread; } publicstaticintgetMainThreadId(){ returnmMainThreadId; } publicstaticHandlergetMainThreadHandler(){ returnmMainThreadHandler; } publicstaticLoopergetMainThreadLooper(){ returnmMainThreadLooper; }}package.xinwen;importcom.thinkland.sdk.android.JuheSDKInitializer;importandroid.app.Application;importandroid.content.Context;importandroid.os.Handler;importandroid.os.Looper;/***@应用程序的入口*/publicclassBaseApplicationextendsApplication{ privatestaticContextmContext; privatestaticThreadmMainThread; privatestaticintmMainThreadId; privatestaticHandlermMainThreadHandler; privatestaticLoopermMainThreadLooper; @Override publicvoidonCreate(){ super.onCreate(); JuheSDKInitializer.initialize(getApplicationContext()); //在应用程序入口提供全局的工具 //上下文 mContext=this; //主线程和子线程 mMainThread=Thread.currentThread();// mMainThreadId=mMainThread.getId(); //当前应用程序进程ID// mMainThreadId=android.os.Process.myPid(); //线程idmyTid(); mMainThreadId=android.os.Process.myTid(); //用户idmyUid(); //主线程handler mMainThreadHandler=newHandler(); mMainThreadLooper=getMainLooper(); } publicstaticContextgetContext(){ returnmContext; } publicstaticThreadgetMainThread(){ returnmMainThread; } publicstaticintgetMainThreadId(){ returnmMainThreadId; } publicstaticHandlergetMainThreadHandler(){ returnmMainThreadHandler; } publicstaticLoopergetMainThreadLooper(){ returnmMainThreadLooper; }}代码2:/**Copyright(C)2013AndreasStuetz<andreas.stuetz@gmail>**LicensedundertheApacheLicense,Version2.0(the"License");*youmaynotusethisfileexceptincompliancewiththeLicense.*YoumayobtainacopyoftheLicenseat**:///licenses/LICENSE-2.0**Unlessrequiredbyapplicablelaworagreedtoinwriting,software*distributedundertheLicenseisdistributedonan"ASIS"BASIS,*WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.*SeetheLicenseforthespecificlanguagegoverningpermissionsand*limitationsundertheLicense.*/packageorg.xinwen.indicator.lib;importandroid.annotation.SuppressLint;importandroid.content.Context;importandroid.content.res.TypedArray;importandroid.graphics.Canvas;importandroid.graphics.Paint;importandroid.graphics.Paint.Style;importandroid.graphics.Typeface;importandroid.os.Build;importandroid.os.Parcel;importandroid.os.Parcelable;importandroid.support.v4.view.ViewPager;importandroid.support.v4.view.ViewPager.OnPageChangeListener;importandroid.util.AttributeSet;importandroid.util.DisplayMetrics;importandroid.util.TypedValue;importandroid.view.Gravity;importandroid.view.View;importandroid.view.ViewTreeObserver.OnGlobalLayoutListener;importandroid.widget.HorizontalScrollView;importandroid.widget.ImageButton;importandroid.widget.LinearLayout;importandroid.widget.TextView;importjava.util.Locale;importorg.itheima51.indicator.lib.R;publicclassTabSlidingIndicatorextendsHorizontalScrollView{ publicinterfaceIconTabProvider { publicintgetPageIconResId(intposition); } //@formatter:off privatestaticfinalint[]ATTRS=newint[]{ android.R.attr.textSize, android.R.attr.textColor}; //@formatter:on privateLinearLayout.LayoutParams defaultTabLayoutParams; privateLinearLayout.LayoutParams expandedTabLayoutParams; privatefinalPageListener pageListener =newPageListener(); publicOnPageChangeListener delegatePageListener; privateLinearLayout tabsContainer; privateViewPager pager; privateint tabCount; privateint currentPosition =0; privatefloat currentPositionOffset =0f; privatePaint rectPaint; privatePaint dividerPaint; privateint indicatorColor =0xFF666666; privateint underlineColor =0x1A000000; privateint dividerColor =0x1A000000; privateboolean shouldExpand =false; privateboolean textAllCaps =true; privateint scrollOffset =52; privateint indicatorHeight =8; privateint underlineHeight =2; privateint dividerPadding =12; privateint tabPadding =24; privateint dividerWidth =1; privateint tabTextSize =12; privateint tabTextColor =0xFF666666; privateint tabNormalTextColor =0xFF666666; privateint tabSelectedTextColor =0xFFFF0000; privateTypeface tabTypeface =null; privateint tabTypefaceStyle =Typeface.BOLD; privateint lastScrollX =0; privateint tabBackgroundResId =R.drawable.background_tab; privateLocale locale; publicTabSlidingIndicator(Contextcontext){ this(context,null); } publicTabSlidingIndicator(Contextcontext,AttributeSetattrs){ this(context,attrs,0); } publicTabSlidingIndicator(Contextcontext,AttributeSetattrs,intdefStyle){ super(context,attrs,defStyle); setFillViewport(true); setWillNotDraw(false); tabsContainer=newLinearLayout(context); tabsContainer.setOrientation(LinearLayout.HORIZONTAL); tabsContainer.setLayoutParams(newLayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT)); addView(tabsContainer); DisplayMetricsdm=getResources().getDisplayMetrics(); scrollOffset=(int)TypedValue.applyDimension(TypedValuePLEX_UNIT_DIP,scrollOffset,dm); indicatorHeight=(int)TypedValue.applyDimension(TypedValuePLEX_UNIT_DIP,indicatorHeight,dm); underlineHeight=(int)TypedValue.applyDimension(TypedValuePLEX_UNIT_DIP,underlineHeight,dm); dividerPadding=(int)TypedValue.applyDimension(TypedValuePLEX_UNIT_DIP,dividerPadding,dm); tabPadding=(int)TypedValue.applyDimension(TypedValuePLEX_UNIT_DIP,tabPadding,dm); dividerWidth=(int)TypedValue.applyDimension(TypedValuePLEX_UNIT_DIP,dividerWidth,dm); tabTextSize=(int)TypedValue.applyDimension(TypedValuePLEX_UNIT_SP,tabTextSize,dm); //getsystemattrs(android:textSizeandandroid:textColor) TypedArraya=context.obtainStyledAttributes(attrs,ATTRS); tabTextSize=a.getDimensionPixelSize(0,tabTextSize); tabTextColor=a.getColor(1,tabTextColor); a.recycle(); //getcustomattrs a=context.obtainStyledAttributes(attrs,R.styleable.TabSlidingIndicator); indicatorColor=a.getColor(R.styleable.TabSlidingIndicator_pstsIndicatorColor,indicatorColor); underlineColor=a.getColor(R.styleable.TabSlidingIndicator_pstsUnderlineColor,underlineColor); dividerColor=a.getColor(R.styleable.TabSlidingIndicator_pstsDividerColor,dividerColor); indicatorHeight=a.getDimensionPixelSize(R.styleable.TabSlidingIndicator_pstsIndicatorHeight,indicatorHeight); underlineHeight=a.getDimensionPixelSize(R.styleable.TabSlidingIndicator_pstsUnderlineHeight,underlineHeight); dividerPadding=a.getDimensionPixelSize(R.styleable.TabSlidingIndicator_pstsDividerPadding,dividerPadding); tabPadding=a.getDimensionPixelSize(R.styleable.TabSlidingIndicator_pstsTabPaddingLeftRight,tabPadding); tabBackgroundResId=a.getResourceId(R.styleable.TabSlidingIndicator_pstsTabBackground,tabBackgroundResId); shouldExpand=a.getBoolean(R.styleable.TabSlidingIndicator_pstsShouldExpand,shouldExpand); scrollOffset=a.getDimensionPixelSize(R.styleable.TabSlidingIndicator_pstsScrollOffset,scrollOffset); textAllCaps=a.getBoolean(R.styleable.TabSlidingIndicator_pstsTextAllCaps,textAllCaps); a.recycle(); rectPaint=newPaint(); rectPaint.setAntiAlias(true); rectPaint.setStyle(Style.FILL); dividerPaint=newPaint(); dividerPaint.setAntiAlias(true); dividerPaint.setStrokeWidth(dividerWidth); defaultTabLayoutParams=newLinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.MATCH_PARENT); expandedTabLayoutParams=newLinearLayout.LayoutParams(0,LayoutParams.MATCH_PARENT,1.0f); if(locale==null) { locale=getResources().getConfiguration().locale; } } publicvoidsetViewPager(ViewPagerpager) { this.pager=pager; if(pager.getAdapter()==null){thrownewIllegalStateException("ViewPagerdoesnothaveadapterinstance.");} pager.setOnPageChangeListener(pageListener); notifyDataSetChanged(); } publicvoidsetOnPageChangeListener(OnPageChangeListenerlistener) { this.delegatePageListener=listener; } publicvoidnotifyDataSetChanged() { tabsContainer.removeAllViews(); tabCount=pager.getAdapter().getCount(); for(inti=0;i<tabCount;i++) { if(pager.getAdapter()instanceofIconTabProvider) { addIconTab(i,((IconTabProvider)pager.getAdapter()).getPageIconResId(i)); } else { addTextTab(i,pager.getAdapter().getPageTitle(i).toString()); } } updateTabStyles(); getViewTreeObserver().addOnGlobalLayoutListener(newOnGlobalLayoutListener(){ @SuppressWarnings("deprecation") @SuppressLint("NewApi") @Override publicvoidonGlobalLayout() { if(Build.VERSION.SDK_INT<Build.VERSION_CODES.JELLY_BEAN) { getViewTreeObserver().removeGlobalOnLayoutListener(this); } else { getViewTreeObserver().removeOnGlobalLayoutListener(this); } currentPosition=pager.getCurrentItem(); scrollToChild(currentPosition,0); if(pageListener!=null) { pageListener.onPageSelected(currentPosition); } } }); } privatevoidaddTextTab(finalintposition,Stringtitle) { TextViewtab=newTextView(getContext()); tab.setText(title); tab.setGravity(Gravity.CENTER); tab.setSingleLine(); addTab(position,tab); } privatevoidaddIconTab(finalintposition,intresId) { ImageButtontab=newImageButton(getContext()); tab.setImageResource(resId); addTab(position,tab); } privatevoidaddTab(finalintposition,Viewtab) { tab.setFocusable(true); tab.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv) { pager.setCurrentItem(position); } }); tab.setPadding(tabPadding,0,tabPadding,0); tabsContainer.addView(tab,position,shouldExpand?expandedTabLayoutParams:defaultTabLayoutParams); } privatevoidupdateTabStyles() { for(inti=0;i<tabCount;i++) { Viewv=tabsContainer.getChildAt(i); v.setBackgroundResource(tabBackgroundResId); if(vinstanceofTextView) { TextViewtab=(TextView)v; tab.setTextSize(TypedValuePLEX_UNIT_PX,tabTextSize); tab.setTypeface(tabTypeface,tabTypefaceStyle); //tab.setTextColor(tabTextColor); if(this.pager.getCurrentItem()==i) { //选锟斤拷时锟斤拷锟斤拷选锟叫碉拷锟斤拷色 tab.setTextColor(tabSelectedTextColor); } else { //没选锟斤拷时锟斤拷锟斤拷没选锟叫碉拷锟斤拷色 tab.setTextColor(tabNormalTextColor); } //setAllCaps()isonlyavailablefromAPI14,sotheuppercase //ismademanuallyifweareona //pre-ICS-build if(textAllCaps) { if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.ICE_CREAM_SANDWICH) { tab.setAllCaps(true); } else { tab.setText(tab.getText().toString().toUpperCase(locale)); } } } } } privatevoidscrollToChild(intposition,intoffset) { if(tabCount==0){return;} intnewScrollX=tabsContainer.getChildAt(position).getLeft()+offset; if(position>0||offset>0) { newScrollX-=scrollOffset; } if(newScrollX!=lastScrollX) { lastScrollX=newScrollX; scrollTo(newScrollX,0); } } @Override protectedvoidonDraw(Canvascanvas) { super.onDraw(canvas); if(isInEditMode()||tabCount==0){return;} finalintheight=getHeight(); //drawindicatorline rectPaint.setColor(indicatorColor); //default:linebelowcurrenttab ViewcurrentTab=tabsContainer.getChildAt(currentPosition); floatlineLeft=currentTab.getLeft(); floatlineRight=currentTab.getRight(); //ifthereisanoffset,startinterpolatingleftandrightcoordinates //betweencurrentandnexttab if(currentPositionOffset>0f&¤tPosition<tabCount-1) { ViewnextTab=tabsContainer.getChildAt(currentPosition+1); finalfloatnextTabLeft=nextTab.getLeft(); finalfloatnextTabRight=nextTab.getRight(); lineLeft=(currentPositionOffset*nextTabLeft+(1f-currentPositionOffset)*lineLeft); lineRight=(currentPositionOffset*nextTabRight+(1f-currentPositionOffset)*lineRight); } canvas.drawRect(lineLeft,height-indicatorHeight,lineRight,height,rectPaint); //drawunderline rectPaint.setColor(underlineColor); canvas.drawRect(0,height-underlineHeight,tabsContainer.getWidth(),height,rectPaint); //drawdivider dividerPaint.setColor(dividerColor); for(inti=0;i<tabCount-1;i++) { Viewtab=tabsContainer.getChildAt(i); canvas.drawLine(tab.getRight(),dividerPadding,tab.getRight(),height-dividerPadding,dividerPaint); } } privateclassPageListenerimplementsOnPageChangeListener { @Override publicvoidonPageScrolled(intposition,floatpositionOffset,intpositionOffsetPixels) { currentPosition=position; currentPositionOffset=positionOffset; scrollToChild(position,(int)(positionOffset*tabsContainer.getChildAt(position).getWidth())); invalidate(); if(delegatePageListener!=null) { delegatePageListener.onPageScrolled(position,positionOffset,positionOffsetPixels); } } @Override publicvoidonPageScrollStateChanged(intstate) { if(state==ViewPager.SCROLL_STATE_IDLE) { scrollToChild(pager.getCurrentItem(),0); } if(delegatePageListener!=null) { delegatePageListener.onPageScrollStateChanged(state); } } @Override publicvoidonPageSelected(intposition) { if(delegatePageListener!=null) { delegatePageListener.onPageSelected(position); } updateTabStyles(); } } publicvoidsetIndicatorColor(intindicatorColor) { this.indicatorColor=indicatorColor; invalidate(); } publicvoidsetIndicatorColorResource(intresId) { this.indicatorColor=getResources().getColor(resId); invalidate(); } publicintgetIndicatorColor() { returnthis.indicatorColor; } publicvoidsetIndicatorHeight(intindicatorLineHeightPx) { this.indicatorHeight=indicatorLineHeightPx; invalidate(); } publicintgetIndicatorHeight() { returnindicatorHeight; } publicvoidsetUnderlineColor(intunderlineColor) { this.underlineColor=underlineColor; invalidate(); } publicvoidsetUnderlineColorResource(intresId) { this.underlineColor=getResources().getColor(resId); invalidate(); } publicintgetUnderlineColor() { returnunderlineColor; } publicvoidsetDividerColor(intdividerColor) { this.dividerColor=dividerColor; invalidate(); } publicvoidsetDividerColorResource(intresId) { this.dividerColor=getResources().getColor(resId); invalidate(); } publicintgetDividerColor() { returndividerColor; } publicvoidsetUnderlineHeight(intunderlineHeightPx) { this.underlineHeight=underlineHeightPx; invalidate(); } publicintgetUnderlineHeight() { returnunderlineHeight; } publicvoidsetDividerPadding(intdividerPaddingPx) { this.dividerPadding=dividerPaddingPx; invalidate(); } publicintgetDividerPadding() { returndividerPadding; } publicvoidsetScrollOffset(intscrollOffsetPx) { this.scrollOffset=scrollOffsetPx; invalidate(); } publicintgetScrollOffset() { returnscrollOffset; } publicvoidsetShouldExpand(booleanshouldExpand) { this.shouldExpand=shouldExpand; requestLayout(); } publicbooleangetShouldExpand() { returnshouldExpand; } publicbooleanisTextAllCaps() { returntextAllCaps; } publicvoidsetAllCaps(booleantextAllCaps) { this.textAllCaps=textAllCaps; } publicvoidsetTextSize(inttextSizePx) { this.tabTextSize=textSizePx; updateTabStyles(); } publicintgetTextSize() { returntabTextSize; } publicvoidsetTextColor(inttextColor) { this.tabTextColor=textColor; updateTabStyles(); } publicvoidsetTextColor(inttextNormalColor,inttextSelectedColor) { this.tabNormalTextColor=textNormalColor; this.tabSelectedTextColor=textSelectedColor; updateTabStyles(); } publicvoidsetTextColorResource(intresId) { this.tabTextColor=getResources().getColor(resId); updateTabStyles(); } publicintgetTextColor() { returntabTextColor; } publicvoidsetTypeface(Typefacetypeface,intstyle) { this.tabTypeface=typeface; this.tabTypefaceStyle=style; updateTabStyles(); } publicvoidsetTabBackground(intresId) { this.tabBackgroundResId=resId; } publicintgetTabBackground() { returntabBackgroundResId; } publicvoidsetTabPaddingLeftRight(intpaddingPx) { this.tabPadding=paddingPx; updateTabStyles(); } publicintgetTabPaddingLeftRight() { returntabPadding; } @Override publicvoidonRestoreInstanceState(Parcelablestate) { SavedStatesavedState=(SavedState)state; super.onRestoreInstanceState(savedState.getSuperState()); currentPosition=savedState.currentPosition; requestLayout(); } @Override publicParcelableonSaveInstanceState() { ParcelablesuperState=super.onSaveInstanceState(); SavedStatesavedState=newSavedState(superState); savedState.currentPosition=currentPosition; returnsavedState; } staticclassSavedStateextendsBaseSavedState { int currentPosition; publicSavedState(ParcelablesuperState){ super(superState); } privateSavedState(Parcelin){ super(in); currentPosition=in.readInt(); } @Override publicvoidwriteToParcel(Parceldest,intflags) { super.writeToParcel(dest,flags); dest.writeInt(currentPosition); } publicstaticfinalParcelable.Creator<SavedState> CREATOR =newParcelable.Creator<SavedState>(){ @Override publicSavedStatecreateFromParcel(Parcelin) { returnnewSavedState(in); } @Override publicSavedState[]newArray(intsize) { returnnewSavedState[size]; } }; }}代码3:*Copyright(c)2013.wyouflf(wyouflf@gmail)**LicensedundertheApacheLicense,Version2.0(the"License");*youmaynotusethisfileexceptincompliancewiththeLicense.*YoumayobtainacopyoftheLicenseat**:///licenses/LICENSE-2.0*Unlessrequiredbyapplicablelaworagreedtoinwriting,software*distributedundertheLicenseisdistributedonan"ASIS"BASIS,*WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.*SeetheLicenseforthespecificlanguagegoverningpermissionsand*limitationsundertheLicense.*/packagecom.lidroid.xutils;importandroid.content.Context;importandroid.graphics.Bitmap;importandroid.graphics.drawable.BitmapDrawable;importandroid.graphics.drawable.Drawable;importandroid.text.TextUtils;importandroid.view.View;importandroid.view.animation.Animation;importcom.lidroid.xutils.bitmap.BitmapCacheListener;importcom.lidroid.xutils.bitmap.BitmapCommonUtils;importcom.lidroid.xutils.bitmap.BitmapDisplayConfig;importcom.lidroid.xutils.bitmap.BitmapGlobalConfig;importcom.lidroid.xutils.bitmap.callback.BitmapLoadCallBack;importcom.lidroid.xutils.bitmap.callback.BitmapLoadFrom;importcom.lidroid.xutils.bitmap.callback.DefaultBitmapLoadCallBack;importcom.lidroid.xutils.bitmap.core.AsyncDrawable;importcom.lidroid.xutils.bitmap.core.BitmapSize;importcom.lidroid.xutils.bitmap.download.Downloader;importcom.lidroid.xutils.cache.FileNameGenerator;importcom.lidroid.xutils.task.PriorityAsyncTask;importcom.lidroid.xutils.task.PriorityExecutor;importcom.lidroid.xutils.task.TaskHandler;importjava.io.File;importjava.lang.ref.WeakReference;publicclassBitmapUtilsimplementsTaskHandler{privatebooleanpauseTask=false;privatebooleancancelAllTask=false;privatefinalObjectpauseTaskLock=newObject();privateContextcontext;privateBitmapGlobalConfigglobalConfig;privateBitmapDisplayConfigdefaultDisplayConfig;///////////////////////////////////////////////create///////////////////////////////////////////////////publicBitmapUtils(Contextcontext){
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年厂房租赁补充协议
- 2025年分期付款信用协议
- 2025年卫浴产品设计合同
- 中国阿奇霉素肠溶片市场全面调研及行业投资潜力预测报告
- 2025版木材认证机构服务采购合同示范3篇
- 二零二五年度公司股权激励项目财务规划与预算合同3篇
- 2025年度储煤场租赁与煤炭交易结算服务合同3篇
- 2025年度新能源行业竞业限制解除通知
- 2025年度私人车位租赁与车位租赁期限续签合同
- 2025年度车库使用权转让及车位租赁权分配协议
- 2024多级AO工艺污水处理技术规程
- 2024年江苏省盐城市中考数学试卷真题(含答案)
- DZ∕T 0287-2015 矿山地质环境监测技术规程(正式版)
- 2024年合肥市庐阳区中考二模英语试题含答案
- 质检中心制度汇编讨论版样本
- 药娘激素方案
- 提高静脉留置使用率品管圈课件
- GB/T 10739-2023纸、纸板和纸浆试样处理和试验的标准大气条件
- 《心态与思维模式》课件
- C语言程序设计(慕课版 第2版)PPT完整全套教学课件
- 危险化学品企业安全生产标准化课件
评论
0/150
提交评论