Get清风Android移动终端开发大作业

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Android移动终端开发大作业
Android移动终端开发大作业
一、作业要求
●1人一组,独立完成。

●按照个人兴趣方向,自选题目,完成系统。

●在规定的时间里完成系统主体功能,程序比较稳定的运行。

●界面要求简洁、美观,功能不能过于简单,应具备一定的实用性。

●至少要3个Activity以上。


●欢迎好的创意作品、实用作品,评分时会适当加分。

●需提交设计报告,设计报告格式见附件,按附件顺序装订〔包括评分表〕●大作业成绩从工作量、功能点、创新性、实用性、报告的字数、质量及标准
度等方面的成绩构成
二、本卷须知
●压缩包内作业内容包括两局部:
①作业工程文件夹,工程必须能够调试
通过,android平台选择选择2.2或是2.3.3。

②作业设计说明,word文件。

●可以借鉴网络上的代码,但不可全部照搬。

不许相互抄袭,一旦发现成绩为零。

附件1:
学号
成绩
Android平台移动应用开发
大作业
题目基于Android的新闻浏览软件的设计
与实现
学院信息工程学院
专业信息工程
班级信息1303
姓名杏允升
指导教师秦珀石
2021 年12 月10 日
一、 (4)
二、概述 (6)
三、关键技术 (7)
四、概要设计 (13)
五、系统实现 (14)
六、心得体会....................... 错误!未定义书签。

一、概述
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系统上开发出一款新闻客户端软件所支持的用户量也是相比较于其他系统多出很多的。

谷歌的移动平台主管安迪·鲁宾(Andy Rubin)表示,跟软件开发合作对象的密切接触正在进行中。

Google与开放联盟联合开发了 Android操作系统,这个联盟由摩托罗拉、高通、宏达电、中国移动和 T-Mobile
二、关键技术
1) 使用ViewPager里面添加多张图片配合线程延时实现轮播图的自
没有通过ScheduledExecutorService或Timer定期执行某个任务实现,而是简单的通过handler发送消息去完成一次滚动,在完成一次滚动后发送另外一个delay的滚动消息,如此循环实现。

自动滚动局部核心代码如下:
至于ViewPager嵌套引起子ViewPager无法触摸问题是通过在子ViewPager 的onTouchEvent中添加
禁止父控件对touch event做intercept解决的。

ViewPager滑动速度的设置是通过反射的方式重新设置ViewPager的Scroller,改变Scroller的startScroll的间隔时间完成的。

调用setScrollDurationFactor(double)即可。

2、使用
(1) 引入公共库
引入Android Auto Scroll ViewPager@Github作为你工程的library(如何拉取代码及添加公共库)。

(2) 调用
仅需简单两步:
a. 布局定义
代替一般的ViewPager定义
b. 启动ViewPager自动滚动
startAutoScroll() 启动自动滚动
stopAutoScroll() 停止自动滚动
3、设置
setInterval(long) 设置自动滚动的间隔时间,单位为毫秒
setDirection(int) 设置自动滚动的方向,默认向右
setCycle(boolean) 是否自动循环轮播,默认为true setScrollDurationFactor(double) 设置ViewPager滑动动画间隔时间的倍率,到达减慢动画或改变动画速度的效果
setStopScrollWhenTouch(boolean) 当手指碰到ViewPager时是否停止自动滚动,默认为true
setSlideBorderMode(int) 滑动到第一个或最后一个Item的处理方式,支持没有任何操作、轮播以及传递到父View三种模式
setBorderAnimation(boolean) 设置循环滚动时滑动到从边缘滚动到下一个是否需要动画,默认为true
4、其他
〔1〕指示器,圆形或是方形指示器请配合ViewPagerIndicator使用
〔2〕无限循环,如果希望在最后一张继续播放第一张而不是退回到第一张,请参考AutoScrollViewPagerSingleDemo.java,注意这个特性不能和ViewPagerIndicator 使用
2)使用viewpager结合ViewPageIndicator进行新闻类别的分类切换,可点击
切换也可以滑动切换。

1. ViewPager Indicator的Library
查看Viewpager Indicator的Library代码,可以看到此工程的设计思想:
首先定义了一个PageIndicator接口,它里面定义了最重要和根本的in dicator表现出的一些方法:
1.1 首先一个indicator必须要与一个ViewPager关联在一起,所以它提供了一个setViewPager方法。

1.2 它扩展了ViewPager.OnPageChangeListener接口,表示接管了ViewPager的Pager改变时的监听处理,
这也是为什么为ViewPager设置OnPageChangeListener 监听器时不能设置在ViewPager上而必须设置在
indicator上的原因。

1.3 还有一个notifyDataSetChanged通知方法,表示为这个Vi ewPager提供View(一般是Fragment)的Adapter 里面的数据集发生变化时,执行的动作,这里可增加相关的逻辑。

2. Viewpager Indicator的实现类
然后再看下Viewpager Indicator的实现类,共有6个,由6个类分别实现,它们分别为:
2.1 小圆圈类型的
2.2 带图标类型的
2.3 小横线类型的,距离屏幕最下边端有一定的距离。

2.4 标签类型的〔Tab〕
2.5 标题类型的,与标签类型的有点像,但它当前的标题页的左/右边的标题会卷起,即往两端缩进去。

2.6 屏幕底部小横线类型的,并且会占满整行。

3. Viewpager Indicator随附带的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的使用方式Gson gson=newGson();String str=ReadAssetsFile.readtext(this,"json_ss");//this当前类,"json_ss"
需要解析的文件名UserMessage userMessage=gson.fromJson(str,UserMessage.class);//需要解析的json文件最外层类名//fastjson的使用方法String json=ReadAssetsFile.readtxt(this,"json_h"); UserMessage user = JSON.parseObject(json,UserMessage.class);
自己扩展
4)使用Universal-Image-Loader对图片进行缓存加载
Android上最让人头疼的莫过于从网络获取图片、显示、回收,任何一个环节有问题都可能直接OOM,这个工程或许能帮到你。

Universal Image Loader for Android的目的是为了实现异步的网络图片加载、缓存及显示,支持多线程异步加载。

它最初来源于Fedor Vlasov的工程,且自此之后,经过大规模的重构和改进。

特性列举:
多线程下载图片,图片可以来源于网络,文件系统,工程文件夹assets中以及drawable中等
支持随意的配置ImageLoader,例如线程池,图片下载器,内存缓存策略,硬盘缓存策略,图片显示选项以及其他的一些配置
支持图片的内存缓存,文件系统缓存或者SD卡缓存
支持图片下载过程的监听
根据控件(ImageView)的大小对Bitmap进行裁剪,减少Bitmap占用过多的内存
较好的控制图片的加载过程,例如暂停图片加载,重新开始加载图片,一般使
用在ListView,GridView中,滑动过程中暂停加载图片,停止滑动的时候去加载图片
提供在较慢的网络下对图片进行加载
使用过程:
创立默认的ImageLoader,所有的操作都由ImageLoader控制。

该类使用单例设计模式,所以如果要获取该类的实力,需要调用getInstance()方法。

在使用ImageLoader显示图片之前,你首先要初始化它的配置,调用ImageLoaderConfiguration的init()方法,然后你就可以实现各种的显示了。

得到imageLoader
使用过程:
(1)图像操作是否参与缓存以及图像效果的配置操作
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;
import com.thinkland.sdk.android.JuheSDKInitializer;
import android.app.Application;
text;
import android.os.Handler;
import android.os.Looper;
/**
* @应用程序的入口
*/
public class BaseApplication extends Application {
private static Context mContext;
private static Thread mMainThread;
private static int mMainThreadId;
private static Handler mMainThreadHandler;
private static Looper mMainThreadLooper;
@Override
public void onCreate() {
super.onCreate();
JuheSDKInitializer.initialize(getApplicationContext());
//在应用程序入口提供全局的工具
//上下文
mContext = this;
//主线程和子线程
mMainThread = Thread.currentThread();
// mMainThreadId = mMainThread.getId();
//当前应用程序进程ID
// mMainThreadId = android.os.Process.myPid();
// 线程id myTid();
mMainThreadId = android.os.Process.myTid();
//用户id myUid();
//主线程handler
mMainThreadHandler = new Handler();
mMainThreadLooper = getMainLooper();
}
public static Context getContext(){
return mContext;
}
public static Thread getMainThread(){
return mMainThread;
}
public static int getMainThreadId(){
return mMainThreadId;
}
public static Handler getMainThreadHandler(){ return mMainThreadHandler;
}
public static Looper getMainThreadLooper(){ return mMainThreadLooper;
}
}
package .xinwen;
izer;
import android.app.Application;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
/**
* @应用程序的入口
*/
public class BaseApplication extends Application {
private static Context mContext;
private static Thread mMainThread;
private static int mMainThreadId;
private static Handler mMainThreadHandler;
private static Looper mMainThreadLooper;
@Override
public void onCreate() {
super.onCreate();
JuheSDKInitializer.initialize(getApplicationContext());
//在应用程序入口提供全局的工具
//上下文
mContext = this;
//主线程和子线程
mMainThread = Thread.currentThread();
// mMainThreadId = mMainThread.getId();
//当前应用程序进程ID
// mMainThreadId = android.os.Process.myPid();
// 线程id myTid();
mMainThreadId = android.os.Process.myTid();
//用户id myUid();
//主线程handler
mMainThreadHandler = new Handler();
mMainThreadLooper = getMainLooper();
}
public static Context getContext(){
return mContext;
}
public static Thread getMainThread(){
return mMainThread;
}
public static int getMainThreadId(){
return mMainThreadId;
}
public static Handler getMainThreadHandler(){
return mMainThreadHandler;
}
public static Looper getMainThreadLooper(){
return mMainThreadLooper;
}
}
代码2:
/*
* Copyright (C) 2021 Andreas Stuetz <andreas.stuetz@gmail >
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.xinwen.indicator.lib;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener; import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.Locale;
import org.itheima51.indicator.lib.R;
public class TabSlidingIndicator extends HorizontalScrollView
{
public interface IconTabProvider
{
public int getPageIconResId(int position);
}
// @formatter:off
private static final int[] ATTRS = new int[] {
android.R.attr.textSize,
};
// @formatter:on
private youtParams defaultTabLayoutParams;
private youtParams expandedTabLayoutParams;
private final PageListener pageListener = new PageListener();
public OnPageChangeListener delegatePageListener;
private LinearLayout tabsContainer;
private ViewPager pager;
private int tabCount;
private int currentPosition = 0;
private float currentPositionOffset = 0f;
private Paint rectPaint;
private Paint dividerPaint;
private int indicatorColor = 0xFF666666; private int underlineColor = 0x1A000000; private int dividerColor = 0x1A000000;
private boolean shouldExpand = false; private boolean textAllCaps = true;
private int scrollOffset = 52;
private int indicatorHeight = 8;
private int underlineHeight = 2;
private int dividerPadding = 12;
private int tabPadding = 24;
private int dividerWidth = 1;
private int tabTextSize = 12;
private int tabTextColor = 0xFF666666;
private int tabNormalTextColor = 0xFF666666; private int tabSelectedTextColor = 0xFFFF0000;
private Typeface tabTypeface = null; private int tabTypefaceStyle =
Typeface.BOLD;
private int lastScrollX = 0;
private int tabBackgroundResId =
R.drawable.background_tab;
private Locale locale;
public TabSlidingIndicator(Context context) {
this(context, null);
}
public TabSlidingIndicator(Context context, AttributeSet attrs) { this(context, attrs, 0);
}
public TabSlidingIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setFillViewport(true);
setWillNotDraw(false);
tabsContainer = new LinearLayout(context);
tabsContainer.setOrientation(LinearLayout.HORIZONTAL);
tabsContainer.setLayoutParams(new
LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
addView(tabsContainer);
DisplayMetrics dm = getResources().getDisplayMetrics();
scrollOffset = (int) TypedValue.applyDimension(TypedValue PLEX_UNIT_DIP, scrollOffset, dm);
indicatorHeight = (int) TypedValue.applyDimension(TypedValue PLEX_UNIT_DIP, indicatorHeight, dm);
underlineHeight = (int) TypedValue.applyDimension(TypedValue PLEX_UNIT_DIP, underlineHeight, dm);
dividerPadding = (int) TypedValue.applyDimension(TypedValue PLEX_UNIT_DIP, dividerPadding, dm);
tabPadding = (int) TypedValue.applyDimension(TypedValue
PLEX_UNIT_DIP, tabPadding, dm);
dividerWidth = (int) TypedValue.applyDimension(TypedValue PLEX_UNIT_DIP, dividerWidth, dm);
tabTextSize = (int) TypedValue.applyDimension(TypedValue PLEX_UNIT_SP, tabTextSize, dm);
// get system attrs (android:textSize and android:textColor)
TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
tabTextSize = a.getDimensionPixelSize(0, tabTextSize);
tabTextColor = a.getColor(1, tabTextColor);
a.recycle();
// get custom attrs
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_pstsIndicatorHe ight, indicatorHeight);
underlineHeight =
a.getDimensionPixelSize(R.styleable.TabSlidingIndicator_pstsUnderlineHe ight, underlineHeight);
dividerPadding =
a.getDimensionPixelSize(R.styleable.TabSlidingIndicator_pstsDividerPadd ing, dividerPadding);
tabPadding =
a.getDimensionPixelSize(R.styleable.TabSlidingIndicator_pstsTabPaddingL eftRight, tabPadding);
tabBackgroundResId =
a.getResourceId(R.styleable.TabSlidingIndicator_pstsTabBackground, tabBackgroundResId);
shouldExpand =
a.getBoolean(R.styleable.TabSlidingIndicator_pstsShouldExpand, shouldExpand);
scrollOffset =
a.getDimensionPixelSize(R.styleable.TabSlidingIndicator_pstsScrollOffse t, scrollOffset);
textAllCaps =
a.getBoolean(R.styleable.TabSlidingIndicator_pstsTextAllCaps, textAllCaps);
a.recycle();
rectPaint = new Paint();
rectPaint.setAntiAlias(true);
rectPaint.setStyle(Style.FILL);
dividerPaint = new Paint();
dividerPaint.setAntiAlias(true);
dividerPaint.setStrokeWidth(dividerWidth);
defaultTabLayoutParams = new
youtParams(LayoutParams.WRAP_CONTENT,
LayoutParams.MATCH_PARENT);
expandedTabLayoutParams = new youtParams(0, LayoutParams.MATCH_PARENT, 1.0f);
if (locale == null)
{
locale = getResources().getConfiguration().locale;
}
}
public void setViewPager(ViewPager pager)
{
this.pager = pager;
if (pager.getAdapter() == null) { throw new
IllegalStateException("ViewPager does not have adapter instance."); }
pager.setOnPageChangeListener(pageListener);
notifyDataSetChanged();
}
public void setOnPageChangeListener(OnPageChangeListener listener) {
this.delegatePageListener = listener;
}
public void notifyDataSetChanged()
{
tabsContainer.removeAllViews();
tabCount = pager.getAdapter().getCount();
for (int i = 0; i < tabCount; i++)
{
if (pager.getAdapter() instanceof IconTabProvider)
{
addIconTab(i, ((IconTabProvider)
pager.getAdapter()).getPageIconResId(i));
}
else
{
addTextTab(i,
pager.getAdapter().getPageTitle(i).toString());
}
}
updateTabStyles();
getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
@Override
public void onGlobalLayout()
{
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);
}
}
});
}
private void addTextTab(final int position, String title)
{
TextView tab = new TextView(getContext());
tab.setText(title);
tab.setGravity(Gravity.CENTER);
tab.setSingleLine();
addTab(position, tab);
}
private void addIconTab(final int position, int resId) {
ImageButton tab = new ImageButton(getContext());
tab.setImageResource(resId);
addTab(position, tab);
}
private void addTab(final int position, View tab)
{
tab.setFocusable(true);
tab.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v)
{
pager.setCurrentItem(position);
}
});
tab.setPadding(tabPadding, 0, tabPadding, 0);
tabsContainer.addView(tab, position, shouldExpand ? expandedTabLayoutParams : defaultTabLayoutParams);
}
private void updateTabStyles()
{
for (int i = 0; i < tabCount; i++)
{
View v = tabsContainer.getChildAt(i);
v.setBackgroundResource(tabBackgroundResId);
if (v instanceof TextView)
{
TextView tab = (TextView) v;
tab.setTextSize(TypedValue PLEX_UNIT_PX, tabTextSize);
tab.setTypeface(tabTypeface, tabTypefaceStyle);
// tab.setTextColor(tabTextColor);
if (this.pager.getCurrentItem() == i)
{
// 选锟斤拷时锟斤拷锟斤拷选锟叫碉拷锟斤拷色
tab.setTextColor(tabSelectedTextColor);
}
else
{
// 没选锟斤拷时锟斤拷锟斤拷没选锟叫碉拷锟斤拷色
tab.setTextColor(tabNormalTextColor);
}
// setAllCaps() is only available from API 14, so the upper case
// is made manually if we are on a
// 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));
}
}
}
}
}
private void scrollToChild(int position, int offset)
{
if (tabCount == 0) { return; }
int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset;
if (position > 0 || offset > 0)
{
newScrollX -= scrollOffset;
}
if (newScrollX != lastScrollX)
{
lastScrollX = newScrollX;
scrollTo(newScrollX, 0);
}
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
if (isInEditMode() || tabCount == 0) { return; }
final int height = getHeight();
// draw indicator line
rectPaint.setColor(indicatorColor);
// default: line below current tab
View currentTab = tabsContainer.getChildAt(currentPosition);
float lineLeft = currentTab.getLeft();
float lineRight = currentTab.getRight();
// if there is an offset, start interpolating left and right coordinates // between current and next tab
if (currentPositionOffset > 0f && currentPosition < tabCount - 1) {
View nextTab = tabsContainer.getChildAt(currentPosition + 1);
final float nextTabLeft = nextTab.getLeft();
final float nextTabRight = nextTab.getRight();
lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft);
lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight);
}
canvas.drawRect(lineLeft, height - indicatorHeight, lineRight, height, rectPaint);
// draw underline
rectPaint.setColor(underlineColor);
canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint);
// draw divider
dividerPaint.setColor(dividerColor);
for (int i = 0; i < tabCount - 1; i++)
{
View tab = tabsContainer.getChildAt(i);
canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint);
}
}
private class PageListener implements OnPageChangeListener
{
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
currentPosition = position;
currentPositionOffset = positionOffset;
scrollToChild(position, (int) (positionOffset *
tabsContainer.getChildAt(position).getWidth()));
invalidate();
if (delegatePageListener != null)
{
delegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageScrollStateChanged(int state)
{
if (state == ViewPager.SCROLL_STATE_IDLE)
{
scrollToChild(pager.getCurrentItem(), 0);
}
if (delegatePageListener != null)
{
delegatePageListener.onPageScrollStateChanged(state);
}
}
@Override
public void onPageSelected(int position)
{
if (delegatePageListener != null)
{
delegatePageListener.onPageSelected(position);
}
updateTabStyles();
}
}
public void setIndicatorColor(int indicatorColor)
{
this.indicatorColor = indicatorColor;
invalidate();
}
public void setIndicatorColorResource(int resId)
{
this.indicatorColor = getResources().getColor(resId);
invalidate();
}
public int getIndicatorColor()
{
return this.indicatorColor;
}
public void setIndicatorHeight(int indicatorLineHeightPx) {
this.indicatorHeight = indicatorLineHeightPx;
invalidate();
}
public int getIndicatorHeight()
{
return indicatorHeight;
}
public void setUnderlineColor(int underlineColor)
{
this.underlineColor = underlineColor;
invalidate();
}
public void setUnderlineColorResource(int resId)
{
this.underlineColor = getResources().getColor(resId);
invalidate();
}
public int getUnderlineColor()
{
return underlineColor;
}
public void setDividerColor(int dividerColor)
{
this.dividerColor = dividerColor;
invalidate();
}
public void setDividerColorResource(int resId)
{
this.dividerColor = getResources().getColor(resId);
invalidate();
}
public int getDividerColor()
{
return dividerColor;
}
public void setUnderlineHeight(int underlineHeightPx) {
this.underlineHeight = underlineHeightPx;
invalidate();
}
public int getUnderlineHeight()
{
return underlineHeight;
}
public void setDividerPadding(int dividerPaddingPx) {
this.dividerPadding = dividerPaddingPx;
invalidate();
}
public int getDividerPadding()
{
return dividerPadding;
}
public void setScrollOffset(int scrollOffsetPx)
{
this.scrollOffset = scrollOffsetPx;
invalidate();
}
public int getScrollOffset()
{
return scrollOffset;
}
public void setShouldExpand(boolean shouldExpand) {
this.shouldExpand = shouldExpand;
requestLayout();
}
public boolean getShouldExpand()
{
return shouldExpand;
}
public boolean isTextAllCaps()
{
return textAllCaps;
}
public void setAllCaps(boolean textAllCaps)
{
this.textAllCaps = textAllCaps;
}
public void setTextSize(int textSizePx)
{
this.tabTextSize = textSizePx;
updateTabStyles();
}
public int getTextSize()
{
return tabTextSize;
}
public void setTextColor(int textColor)
{
this.tabTextColor = textColor;
updateTabStyles();
}
public void setTextColor(int textNormalColor, int textSelectedColor) {
this.tabNormalTextColor = textNormalColor;
this.tabSelectedTextColor = textSelectedColor;
updateTabStyles();
}
public void setTextColorResource(int resId)
{
this.tabTextColor = getResources().getColor(resId);
updateTabStyles();
}
public int getTextColor()
{
return tabTextColor;
}
public void setTypeface(Typeface typeface, int style)
{
this.tabTypeface = typeface;
this.tabTypefaceStyle = style;
updateTabStyles();
}
public void setTabBackground(int resId)
{
this.tabBackgroundResId = resId;
}
public int getTabBackground()
{
return tabBackgroundResId;
}
public void setTabPaddingLeftRight(int paddingPx)
{
this.tabPadding = paddingPx;
updateTabStyles();
}
public int getTabPaddingLeftRight()
{
return tabPadding;
}
@Override
public void onRestoreInstanceState(Parcelable state)
{
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
currentPosition = savedState.currentPosition;
requestLayout();
}
@Override
public Parcelable onSaveInstanceState()
{
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPosition = currentPosition;
return savedState;
}
static class SavedState extends BaseSavedState
{
int currentPosition;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPosition = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
super.writeToParcel(dest, flags);
dest.writeInt(currentPosition);
}
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in)
{
return new SavedState(in);
} @Override
public SavedState[] newArray(int size)
{
return new SavedState[size];
}
};
}
}
代码3:
* Copyright (c) 2021. wyouflf (wyouflf@gmail )
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.lidroid.xutils;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.view.View;
import android.view.animation.Animation;
import com.lidroid.xutils.bitmap.BitmapCacheListener;
import com.lidroid.xutils.bitmap.BitmapCommonUtils;
import com.lidroid.xutils.bitmap.BitmapDisplayConfig;
import com.lidroid.xutils.bitmap.BitmapGlobalConfig;
import com.lidroid.xutils.bitmap.callback.BitmapLoadCallBack;
import com.lidroid.xutils.bitmap.callback.BitmapLoadFrom;
import com.lidroid.xutils.bitmap.callback.DefaultBitmapLoadCallBack;
import com.lidroid.xutils.bitmap.core.AsyncDrawable;
import com.lidroid.xutils.bitmap.core.BitmapSize;
import com.lidroid.xutils.bitmap.download.Downloader;
import com.lidroid.xutils.cache.FileNameGenerator;
import com.lidroid.xutils.task.PriorityAsyncTask;
import com.lidroid.xutils.task.PriorityExecutor;
import com.lidroid.xutils.task.TaskHandler;
import java.io.File;
import ng.ref.WeakReference;
public class BitmapUtils implements TaskHandler {
private boolean pauseTask = false;
private boolean cancelAllTask = false;
private final Object pauseTaskLock = new Object();
private Context context;
private BitmapGlobalConfig globalConfig;
private BitmapDisplayConfig defaultDisplayConfig;
/////////////////////////////////////////////// create
///////////////////////////////////////////////////
public BitmapUtils(Context context) {
this(context, null);
}
public BitmapUtils(Context context, String diskCachePath) {
if (context == null) {
throw new IllegalArgumentException("context may not be null"); }
this.context = context.getApplicationContext();
globalConfig = BitmapGlobalConfig.getInstance(this.context, diskCachePath);
defaultDisplayConfig = new BitmapDisplayConfig();
}
public BitmapUtils(Context context, String diskCachePath, int memoryCacheSize) {
this(context, diskCachePath);
globalConfig.setMemoryCacheSize(memoryCacheSize);
}
public BitmapUtils(Context context, String diskCachePath, int memoryCacheSize, int diskCacheSize) {。

相关文档
最新文档