![【移动应用开发技术】Android中如何动态替换底部导航栏_第1页](http://file4.renrendoc.com/view/9907b318fc857922600819df5921d9f3/9907b318fc857922600819df5921d9f31.gif)
![【移动应用开发技术】Android中如何动态替换底部导航栏_第2页](http://file4.renrendoc.com/view/9907b318fc857922600819df5921d9f3/9907b318fc857922600819df5921d9f32.gif)
![【移动应用开发技术】Android中如何动态替换底部导航栏_第3页](http://file4.renrendoc.com/view/9907b318fc857922600819df5921d9f3/9907b318fc857922600819df5921d9f33.gif)
![【移动应用开发技术】Android中如何动态替换底部导航栏_第4页](http://file4.renrendoc.com/view/9907b318fc857922600819df5921d9f3/9907b318fc857922600819df5921d9f34.gif)
![【移动应用开发技术】Android中如何动态替换底部导航栏_第5页](http://file4.renrendoc.com/view/9907b318fc857922600819df5921d9f3/9907b318fc857922600819df5921d9f35.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】Android中如何动态替换底部导航栏
Android中如何动态替换底部导航栏?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。具体内容如下1、通常来说,一般情况下,我们的app的BottomTab会有下面几种实现方式。1)、自定义view,然后自己写逻辑去实现互斥。2)、使用RadioGroup+RadioButton去实现底部的Tab。自由度比极高,如果想实现搞复杂度的话可以重写RadioButton。3)、使用googledesign包里面的TabLayout去实现。可上、可下、可以滑动偷懒的话可以根据已有api来设置一些资源,也可以setCustomView()4)、使用googledesign包里面的BottomNavigationView去实现。(1)使用menu设置资源(2)有默认的动画效果(1)使用menu设置资源(2)有默认的动画效果2.本篇介绍的是日常见到的京东,淘宝类似的根据后台下发实现动态替换底部导航资源图片的方法(基于TabLayout实现)既然提到了动态替换肯定意味着要下载资源,所以先讲一下IntentServiceIntentService也是一个service,只不过google帮我们在里面封装并维护了一个HandlerThread,里面的操作都是异步的。当任务执行完后,IntentService会自动停止,不需要我们去手动结束。如果启动IntentService多次,那么每一个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,依次去执行,使用串行的方式,执行完自动结束。onHandlerIntent(Intentintent)是最重要的一个方法@Override
protected
void
onHandleIntent(Intent
intent)
{
if
(intent
!=
null)
{
final
String
action
=
intent.getAction();
if
(ACTION_FOO.equals(action))
{
//
在这里面处理耗时任务,当所有的耗时任务都结束以后,IntentService会自动的finish掉,不需要开发者关心。
}
}
}选择IntentService的原因是因为下面的这几个操作都是耗时操作,所以我们干脆都封装到这service里面,我们只需要在合适的时机去启动这个Service就ok了需要下载资源压缩包因为是动态替换,所以必然涉及到预下载,所以数据格式要先定好(下面是数据格式)。{
"currentInfo":{//当前样式
"id":"111",
"imageZipUrl":你的下载地址,
"tabNamesList":[
"首页1","附近1","发现1","我的1"
],
"tabColorNormal":"B0C4DE",
"tabColorHighlight":"F7B62D",
"startTime":开始时间,
"deadLineTime":结束时间
},
"nextInfo":{//下一次要展示的样式
"id":"111",
"imageZipUrl":你的下载地址,
"tabNamesList":[
"首页2","附近2","发现2","我的2"
],
"tabColorNormal":"B0C4DE",
"tabColorHighlight":"FE6246",
"startTime":开始时间,
"deadLineTime":结束时间
}
}需要存放资源压缩包下载和存放文件的代码(这里使用的是Retrofit进行下载的)
//
下载文件
Response<ResponseBody>
zipFile
=
ServiceGenerator.createService(HomeService.class)
.downloadFileRetrofit(getFileDownLoadUrl(homeTabImageInfoBean,
type))
.execute();
//
得到文件流
ResponseBody
zipBody
=
zipFile.body();
LogUtils.d("DownLoad",
"下载完成");
//
创建一个文件
File
zipDirectory
=
new
File(FilePathUtil.getHuaShengHomeTabZipDirectory(getApplicationContext())
+
createZipFileName(homeTabImageInfoBean,
type));
//
如果文件不存在,则创建文件夹
if
(!zipDirectory.exists())
{
zipDirectory.createNewFile();
}
//
保存文件
FileUtils.writeFile2Disk(zipBody,
zipDirectory);解压资源并删除文件(解压方法由于过长所以写在了文中底部)//
解压文件
并删除文件
if
(ZipUtils.unzipFile(zipDirectory.getAbsolutePath(),
CURRENT.equals(type)
?
FilePathUtil.getHuaShengHomeTabImgCurrentDirectory(getApplicationContext())
:
FilePathUtil.getHuaShengHomeTabImgNextDirectory(getApplicationContext())))
{
//
保存文件解压地址
saveFileDirPath(homeTabImageInfoBean,
type,
CURRENT.equals(type)
?
FilePathUtil.getHuaShengHomeTabImgCurrentDirectory(getApplicationContext())
:
FilePathUtil.getHuaShengHomeTabImgNextDirectory(getApplicationContext()));
LogUtils.d("HomeTabImageDownLoadInt",
"解压完成");
}其实最关键的就是如何创建并获取我们的文件资源重要的就是资源的两种状态切换(选中or不选中),通常我们都是使用drawable来写的<?xml
version="1.0"
encoding="utf-8"?>
<selector
xmlns:android="/apk/res/android">
<item
android:drawable="@mipmap/home_tab_financing_selected"
android:state_selected="true"
/>
<item
android:drawable="@mipmap/home_tab_financing_normal"
/>
</selector>现在我们要根据下载下来的图片(存放在sdcard中)去动态创建drawable这样我们便能里面系统控件的互斥特性下面的三个方法代码很重要//
构建Drawable选择器
private
StateListDrawable
createDrawableSelector(Drawable
checked,
Drawable
unchecked)
{
StateListDrawable
stateList
=
new
StateListDrawable();
int
state_selected
=
android.R.attr.state_selected;
stateList.addState(new
int[]{state_selected},
checked);
stateList.addState(new
int[]{-state_selected},
unchecked);
return
stateList;
}//
构建颜色选择器
private
ColorStateList
createColorSelector(int
checkedColor,
int
uncheckedColor)
{
return
new
ColorStateList(
new
int[][]{new
int[]{android.R.attr.state_selected},
new
int[]{-android.R.attr.state_selected}},
new
int[]{checkedColor,
uncheckedColor});//
将文件转换成Drawable
//
pathName就是图片存放的绝对路径
private
Drawable
getDrawableByFile(String
pathName)
{
return
Drawable.createFromPath(pathName);
}最后就是在TabLayout的tab上设置资源取出TabLayout的所有的Tab,遍历,然后根据特定条件去设置相应的drawable就可以了最后在本文结尾附上上文的压缩相关工具类import
com.blankj.utilcode.util.CloseUtils;
import
com.blankj.utilcode.util.StringUtils;
import
java.io.BufferedInputStream;
import
java.io.BufferedOutputStream;
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
java.io.InputStream;
import
java.io.OutputStream;
import
java.util.ArrayList;
import
java.util.Collection;
import
java.util.Enumeration;
import
java.util.List;
import
java.util.zip.ZipEntry;
import
java.util.zip.ZipFile;
import
java.util.zip.ZipOutputStream;
/**
*
<pre>
*
author:
程龙
*
time
:
2018/12/14
*
desc
:
压缩相关工具类
*
</pre>
*/
public
final
class
ZipUtils
{
private
static
final
int
KB
=
1024;
private
ZipUtils()
{
throw
new
UnsupportedOperationException("u
can't
instantiate
me...");
}
/**
*
批量压缩文件
*
*
@param
resFiles
待压缩文件集合
*
@param
zipFilePath
压缩文件路径
*
@return
{@code
true}:
压缩成功<br>{@code
false}:
压缩失败
*
@throws
IOException
IO错误时抛出
*/
public
static
boolean
zipFiles(Collection<File>
resFiles,
String
zipFilePath)
throws
IOException
{
return
zipFiles(resFiles,
zipFilePath,
null);
}
/**
*
批量压缩文件
*
*
@param
resFiles
待压缩文件集合
*
@param
zipFilePath
压缩文件路径
*
@param
comment
压缩文件的注释
*
@return
{@code
true}:
压缩成功<br>{@code
false}:
压缩失败
*
@throws
IOException
IO错误时抛出
*/
public
static
boolean
zipFiles(Collection<File>
resFiles,
String
zipFilePath,
String
comment)
throws
IOException
{
return
zipFiles(resFiles,
FileUtils.getFileByPath(zipFilePath),
comment);
}
/**
*
批量压缩文件
*
*
@param
resFiles
待压缩文件集合
*
@param
zipFile
压缩文件
*
@return
{@code
true}:
压缩成功<br>{@code
false}:
压缩失败
*
@throws
IOException
IO错误时抛出
*/
public
static
boolean
zipFiles(Collection<File>
resFiles,
File
zipFile)
throws
IOException
{
return
zipFiles(resFiles,
zipFile,
null);
}
/**
*
批量压缩文件
*
*
@param
resFiles
待压缩文件集合
*
@param
zipFile
压缩文件
*
@param
comment
压缩文件的注释
*
@return
{@code
true}:
压缩成功<br>{@code
false}:
压缩失败
*
@throws
IOException
IO错误时抛出
*/
public
static
boolean
zipFiles(Collection<File>
resFiles,
File
zipFile,
String
comment)
throws
IOException
{
if
(resFiles
==
null
||
zipFile
==
null)
return
false;
ZipOutputStream
zos
=
null;
try
{
zos
=
new
ZipOutputStream(new
FileOutputStream(zipFile));
for
(File
resFile
:
resFiles)
{
if
(!zipFile(resFile,
"",
zos,
comment))
return
false;
}
return
true;
}
finally
{
if
(zos
!=
null)
{
zos.finish();
CloseUtils.closeIO(zos);
}
}
}
/**
*
压缩文件
*
*
@param
resFilePath
待压缩文件路径
*
@param
zipFilePath
压缩文件路径
*
@return
{@code
true}:
压缩成功<br>{@code
false}:
压缩失败
*
@throws
IOException
IO错误时抛出
*/
public
static
boolean
zipFile(String
resFilePath,
String
zipFilePath)
throws
IOException
{
return
zipFile(resFilePath,
zipFilePath,
null);
}
/**
*
压缩文件
*
*
@param
resFilePath
待压缩文件路径
*
@param
zipFilePath
压缩文件路径
*
@param
comment
压缩文件的注释
*
@return
{@code
true}:
压缩成功<br>{@code
false}:
压缩失败
*
@throws
IOException
IO错误时抛出
*/
public
static
boolean
zipFile(String
resFilePath,
String
zipFilePath,
String
comment)
throws
IOException
{
return
zipFile(FileUtils.getFileByPath(resFilePath),
FileUtils.getFileByPath(zipFilePath),
comment);
}
/**
*
压缩文件
*
*
@param
resFile
待压缩文件
*
@param
zipFile
压缩文件
*
@return
{@code
true}:
压缩成功<br>{@code
false}:
压缩失败
*
@throws
IOException
IO错误时抛出
*/
public
static
boolean
zipFile(File
resFile,
File
zipFile)
throws
IOException
{
return
zipFile(resFile,
zipFile,
null);
}
/**
*
压缩文件
*
*
@param
resFile
待压缩文件
*
@param
zipFile
压缩文件
*
@param
comment
压缩文件的注释
*
@return
{@code
true}:
压缩成功<br>{@code
false}:
压缩失败
*
@throws
IOException
IO错误时抛出
*/
public
static
boolean
zipFile(File
resFile,
File
zipFile,
String
comment)
throws
IOException
{
if
(resFile
==
null
||
zipFile
==
null)
return
false;
ZipOutputStream
zos
=
null;
try
{
zos
=
new
ZipOutputStream(new
FileOutputStream(zipFile));
return
zipFile(resFile,
"",
zos,
comment);
}
finally
{
if
(zos
!=
null)
{
CloseUtils.closeIO(zos);
}
}
}
/**
*
压缩文件
*
*
@param
resFile
待压缩文件
*
@param
rootPath
相对于压缩文件的路径
*
@param
zos
压缩文件输出流
*
@param
comment
压缩文件的注释
*
@return
{@code
true}:
压缩成功<br>{@code
false}:
压缩失败
*
@throws
IOException
IO错误时抛出
*/
private
static
boolean
zipFile(File
resFile,
String
rootPath,
ZipOutputStream
zos,
String
comment)
throws
IOException
{
rootPath
=
rootPath
+
(isSpace(rootPath)
?
""
:
File.separator)
+
resFile.getName();
if
(resFile.isDirectory())
{
File[]
fileList
=
resFile.listFiles();
//
如果是空文件夹那么创建它,我把'/'换为File.separator测试就不成功,eggPain
if
(fileList
==
null
||
fileList.length
<=
0)
{
ZipEntry
entry
=
new
ZipEntry(rootPath
+
'/');
if
(!StringUtils.isEmpty(comment))
entry.setComment(comment);
zos.putNextEntry(entry);
zos.closeEntry();
}
else
{
for
(File
file
:
fileList)
{
//
如果递归返回false则返回false
if
(!zipFile(file,
rootPath,
zos,
comment))
return
false;
}
}
}
else
{
InputStream
is
=
null;
try
{
is
=
new
BufferedInputStream(new
FileInputStream(resFile));
ZipEntry
entry
=
new
ZipEntry(rootPath);
if
(!StringUtils.isEmpty(comment))
entry.setComment(comment);
zos.putNextEntry(entry);
byte
buffer[]
=
new
byte[KB];
int
len;
while
((len
=
is.read(buffer,
0,
KB))
!=
-1)
{
zos.write(buffer,
0,
len);
}
zos.closeEntry();
}
finally
{
CloseUtils.closeIO(is);
}
}
return
true;
}
/**
*
批量解压文件
*
*
@param
zipFiles
压缩文件集合
*
@param
destDirPath
目标目录路径
*
@return
{@code
true}:
解压成功<br>{@code
false}:
解压失败
*
@throws
IOException
IO错误时抛出
*/
public
static
boolean
unzipFiles(Collection<File>
zipFiles,
String
destDirPath)
throws
IOException
{
return
unzipFiles(zipFiles,
FileUtils.getFileByPath(destDirPath));
}
/**
*
批量解压文件
*
*
@param
zipFiles
压缩文件集合
*
@param
destDir
目标目录
*
@return
{@code
true}:
解压成功<br>{@code
false}:
解压失败
*
@throws
IOException
IO错误时抛出
*/
public
static
boolean
unzipFiles(Collection<File>
zipFiles,
File
destDir)
throws
IOException
{
if
(zipFiles
==
null
||
destDir
==
null)
return
false;
for
(File
zipFile
:
zipFiles)
{
if
(!unzipFile(zipFile,
destDir))
return
false;
}
return
true;
}
/**
*
解压文件
*
*
@param
zipFilePath
待解压文件路径
*
@param
destDirPath
目标目录路径
*
@return
{@code
true}:
解压成功<br>{@code
false}:
解压失败
*
@throws
IOException
IO错误时抛出
*/
public
static
boolean
unzipFile(String
zipFilePath,
String
destDirPath)
throws
IOException
{
//
判断是否存在这个路径,没有的话就创建这个路径
File
tempDir
=
new
File(destDirPath);
if
(!tempDir.exists())
{
tempDir.mkdirs();
}
return
unzipFile(FileUtils.getFileByPath(zipFilePath),
FileUtils.getFileByPath(destDirPath));
}
/**
*
解压文件
*
*
@param
zipFile
待解压文件
*
@param
destDir
目标目录
*
@return
{@code
true}:
解压成功<br>{@code
false}:
解压失败
*
@throws
IOException
IO错误时抛出
*/
public
static
boolean
unzipFile(File
zipFile,
File
destDir)
throws
IOException
{
return
unzipFileByKeyword(zipFile,
destDir,
null)
!=
null;
}
/**
*
解压带有关键字的文件
*
*
@param
zipFilePath
待解压文件路径
*
@param
destDirPath
目标目录路径
*
@param
keyword
关键字
*
@return
返回带有关键字的文件链表
*
@throws
IOException
IO错误时抛出
*/
public
static
List<File>
unzipFileByKeyword(String
zipFilePath,
String
destDirPath,
String
keyword)
throws
IOException
{
return
unzipFileByKeyword(FileUtils.getFileByPath(zipFilePath),
FileUtils.getFileByPath(destDirPath),
keyword);
}
/**
*
解压带有关键字的文件
*
*
@param
zipFile
待解压文件
*
@param
destDir
目标目录
*
@param
keyword
关键字
*
@return
返回带有关键字的文件链表
*
@throws
IOException
IO错误时抛出
*/
public
static
List<File>
unzipFileByKeyword(File
zipFile,
File
destDir,
String
keyword)
throws
IOException
{
if
(zipFile
==
null
||
destDir
==
null)
return
null;
List<File>
files
=
new
ArrayList<>();
ZipFile
zf
=
new
ZipFile(zipFile);
Enumeration<?>
entries
=
zf.entries();
while
(entries.hasMoreElements())
{
ZipEntry
entry
=
((ZipEntry)
entries.nextElement());
String
entryName
=
entry.getName();
if
(StringUtils.isEmpty(keyword)
||
FileUtils.getFileName(entryName).toLowerCase().contains(keyword.toLowerCase()))
{
String
filePath
=
destDir
+
File.separator
+
entryName;
File
file
=
new
File(filePath);
files.add(file);
if
(entry.isDirectory())
{
if
(!FileUtils.createOrExistsDir(file))
return
null;
}
else
{
if
(!FileUtils.createOrExistsFile(file))
return
null;
InputStream
in
=
null;
OutputStream
out
=
null;
try
{
in
=
new
BufferedInputStream(zf.getInputStream(entry));
out
=
new
BufferedOutputStream(new
FileOutputStream(file));
byte
buffer[]
=
new
byte[KB];
int
len;
while
((len
=
in.read(buffer))
!=
-1)
{
out.write(buffer,
0,
len);
}
}
finally
{
CloseUtils.closeIO(in,
out);
}
}
}
}
return
files;
}
/**
*
获取压缩文件中的文件路径链表
*
*
@param
zipFilePath
压缩文件路径
*
@return
压缩文件中的文件路径链表
*
@throws
IOException
IO错误时抛出
*/
public
static
List<String>
getFilesPath(String
zipFilePath)
throws
IOException
{
return
getFilesPath(FileUtils.getFileByPath(zipFilePath));
}
/**
*
获取压缩文件中的文件路径链表
*
*
@param
zipFile
压缩文件
*
@return
压缩文件中的文件路径链表
*
@throws
IOException
IO错误时抛出
*/
public
static
List<String>
getFilesPath(File
zipFile)
throws
IOException
{
if
(zipFile
==
null)
return
null;
List<String>
paths
=
new
ArrayList<>();
Enumeration<?>
entries
=
getEntries(zipFile);
while
(entries.hasMoreElements())
{
paths.add(((ZipEntry)
entries.nextElement()).getName()
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年患者隐私保护协议与策划
- 2025年企业销售人员招聘合同范例
- 2025年企业人员临时借调合同范文
- 2025年居民安置过渡性协议
- 2025年个人流转养殖水面使用权协议
- 2025年共享发展市场拓展协议
- 2025年产业园区企业使用条款协议
- 2025年医疗设备更新协议文本
- 2025年医院食堂后勤服务合同标准格式
- 农业合作社土地使用权入股框架协议
- GB/T 32574-2016抽水蓄能电站检修导则
- 《社会主义市场经济理论(第三版)》第十三章社会主义市场经济标准论
- 变更索赔案例分析
- 过敏性休克的急救及处理流程教材课件(28张)
- DB32-T 3129-2016适合机械化作业的单体钢架塑料大棚 技术规范-(高清现行)
- 《花婆婆》儿童绘本故事
- DB44∕T 2149-2018 森林资源规划设计调查技术规程
- 数据结构英文教学课件:chapter10 Hashing
- 机动车牌证申请表格模板(完整版)
- 《国家电网公司十八项电网反事故措施(试行)》实施细则
- 钢丝网架珍珠岩夹心板安装方法
评论
0/150
提交评论