小东子的个人技术专栏

重点关注Android、Java、智能硬件、JavaEE、react-native,Swift,微信小程序


  • 首页

  • 归档

  • 标签
小东子的个人技术专栏

Android 打开网络pdf文件

发表于 2016-12-10   |   字数统计: 758(字)   |   阅读时长: 4(分)

之前写过一篇Android打开本地pdf文件的文章,最后总结的时候说,后面一定要拓展库,让其也能打开网络的的pdf文件。今天终于可以兑现承诺了。frok一份代码https://github.com/JoanZapata/android-pdfview,开始改造一番。

1.基本思路:

  • 打来网络pdf 思路整体还是来源与图片的加载。
  • android中加载网络图片的框架有很多个。如image-laoder, fresco、glide等,首先都是从内存中找图片,如果内存中没有,接着从本地找,本地没有在从网络下载。
  • android中加载pdf也是类似,首先从本地找pdf文件,如果本地存在该pdf文件,直接打开,如果本地不存在,将该pdf文件下载到本地在打开。
  • 下载文件用到了retrofit2的库,已经封装到android_pdf中了。

2.依赖android_pdf库方法

2.1 在项目的gradle中增加如下代码:

1
compile 'com.lidong.pdf:android_pdf:1.0.1'

2.2 一句代码就可以加载网络pdf。

1
pdfView.fileFromLocalStorage(this,this,this,fileUrl,fileName); //设置pdf文件地址

2.3对fileFromLocalStorage(this,this,this,fileUrl,fileName)的解析

/**

1
2
3
4
5
6
7
8
9
10
11
12
13
* 加载pdf文件
* @param onPageChangeListener
* @param onLoadCompleteListener
* @param onDrawListener
* @param fileUrl
* @param fileName
*/
public void fileFromLocalStorage(
final OnPageChangeListener onPageChangeListener,
final OnLoadCompleteListener onLoadCompleteListener,
final OnDrawListener onDrawListener,
String fileUrl,
final String fileName)
  1. OnPageChangeListener onPageChangeListener :翻页回调
  2. OnLoadCompleteListener onLoadCompleteListener:加载完成的回调
  3. OnDrawListener:页面绘制的回调
  4. String fileUrl : 文件的网络地址
  5. String fileName 文件名称

3.使用android_pdf库方法

3.1写一个布局文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.lidong.pdf.androidpdf.MainActivity">
<com.lidong.pdf.PDFView
android:id="@+id/pdfView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>

3.2在MainActivity中加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import android.graphics.Canvas;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import com.lidong.pdf.PDFView;
import com.lidong.pdf.api.ApiManager;
import com.lidong.pdf.listener.OnDrawListener;
import com.lidong.pdf.listener.OnLoadCompleteListener;
import com.lidong.pdf.listener.OnPageChangeListener;
import com.lidong.pdf.util.FileUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import okhttp3.ResponseBody;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
public class MainActivity extends AppCompatActivity implements OnPageChangeListener
,OnLoadCompleteListener, OnDrawListener {
private PDFView pdfView ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pdfView = (PDFView) findViewById( R.id.pdfView );
displayFromFile1("填写所要打开的pdf地址");
}
/**
* 获取打开网络的pdf文件
* @param fileUrl
* @param fileName
*/
private void displayFromFile1( String fileUrl ,String fileName) {
showProgress(); pdfView.fileFromLocalStorage(this,this,this,fileUrl,fileName); //设置pdf文件地址
}
/**
* 翻页回调
* @param page
* @param pageCount
*/
@Override
public void onPageChanged(int page, int pageCount) {
Toast.makeText( MainActivity.this , "page= " + page +
" pageCount= " + pageCount , Toast.LENGTH_SHORT).show();
}
/**
* 加载完成回调
* @param nbPages 总共的页数
*/
@Override
public void loadComplete(int nbPages) {
Toast.makeText( MainActivity.this , "加载完成" + nbPages , Toast.LENGTH_SHORT).show();
hideProgress();
}
@Override
public void onLayerDrawn(Canvas canvas, float pageWidth, float pageHeight, int displayedPage) {
// Toast.makeText( MainActivity.this , "pageWidth= " + pageWidth + "
// pageHeight= " + pageHeight + " displayedPage=" + displayedPage , Toast.LENGTH_SHORT).show();
}
/**
* 显示对话框
*/
private void showProgress(){
LoadingUIHelper.showDialogForLoading(this,"报告加载中,请等待。。。",false);
}
/**
* 关闭等待框
*/
private void hideProgress(){
LoadingUIHelper.hideDialogForLoading();
}

代码地址


效果实现:
这里写图片描述

代码已经奉上,请大家伙给点建议。一起交流(1561281670)

小东子的个人技术专栏

微信小程序网络请求的封装与填坑之路

发表于 2016-11-15   |   字数统计: 557(字)   |   阅读时长: 3(分)

以前写过一篇关于微信小程序上拉加载,上拉刷新的文章,今天写的是关于小程序网络请求的封装。
在这里首先声明一个小程序文档的bug,导致大伙们在请求的时候,服务器收到不到参数的问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
示例代码:
wx.request({
url: 'test.php', //仅为示例,并非真实的接口地址
data: {
x: '' ,
y: ''
},
header: {
'Content-Type': 'application/json'
},
success: function(res) {
console.log(res.data)
}
})

其中header 中的Content-Type,应该用小写content-type才能让服务器收到参数。让我折腾的好久,改了服务器仍然不行,原来是这个问题。参数在request payload中,服务器不能收到,使用如下转换之后

1
2
3
4
5
6
7
function json2Form(json) {
var str = [];
for(var p in json){
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(json[p]));
}
return str.join("&");
}

这里写图片描述

最终还是认为是content-type的问题。最后改小写就ok,觉得微信这么牛逼的团队,犯了一个很低级 的错误,把我开发者折腾的爬了。不说,上代码吧。

1 、Http请求的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import util from 'util.js';
/**
* url 请求地址
* success 成功的回调
* fail 失败的回调
*/
function _get( url, success, fail ) {
console.log( "------start---_get----" );
wx.request( {
url: url,
header: {
// 'Content-Type': 'application/json'
},
success: function( res ) {
success( res );
},
fail: function( res ) {
fail( res );
}
});
console.log( "----end-----_get----" );
}
/**
* url 请求地址
* success 成功的回调
* fail 失败的回调
*/
function _post_from(url,data, success, fail ) {
console.log( "----_post--start-------" );
wx.request( {
url: url,
header: {
'content-type': 'application/x-www-form-urlencoded',
},
method:'POST',
data:{data: data},
success: function( res ) {
success( res );
},
fail: function( res ) {
fail( res );
}
});
console.log( "----end-----_get----" );
}
/**
* url 请求地址
* success 成功的回调
* fail 失败的回调
*/
function _post_json(url,data, success, fail ) {
console.log( "----_post--start-------" );
wx.request( {
url: url,
header: {
'content-type': 'application/json',
},
method:'POST',
data:data,
success: function( res ) {
success( res );
},
fail: function( res ) {
fail( res );
}
});
console.log( "----end----_post-----" );
}
module.exports = {
_get: _get,
_post:_post,
_post_json:_post_json
}

2、测试用例

2.1 get请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//GET方式
let map = new Map();
map.set( 'receiveId', '0010000022464' );
let d = json_util.mapToJson( util.tokenAndKo( map ) );
console.log( d );
var url1 = api.getBaseUrl() + 'SearchTaskByReceiveId?data='+d;
network_util._get( url1,d,
function( res ) {
console.log( res );
that.setData({
taskEntrys:res.data.taskEntrys
});
}, function( res ) {
console.log( res );
});

2.2 POST请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Post方式
let map = new Map();
map.set( 'receiveId', '0010000022464' );
let d = json_util.mapToJson( util.tokenAndKo( map ) );
console.log( d );
var url1 = api.getBaseUrl() + 'SearchTaskByReceiveId';
network_util._post( url1,d,
function( res ) {
console.log( res );
that.setData({
taskEntrys:res.data.taskEntrys
});
}, function( res ) {
console.log( res );
});

效果这里写图片描述

这里写图片描述

小东子的个人技术专栏

Android 打开本地pdf文件

发表于 2016-10-12   |   字数统计: 822(字)   |   阅读时长: 4(分)

Android 中打开pdf文件也是一种很常见的场景,但是上网找了好多资料,有用WebView加载的,但是要用vpn才能搞,最后发现一个库挺不错的,再次分享给大家
android-pdfview。下面主要说一下该库的使用方法。

1. 该库的下载地址

https://github.com/JoanZapata/android-pdfview

2. android-pdfview的简单介绍

PDFView是这个库中最核心的类,用于加载pdf文件,PDFView是的实现是继承于SurfaceView来实现的。主要用到了建造者模式来设置相关的属性。

  • fromFile(file) //设置pdf文件地址
  • fromAsset(assetFileName) //设置pdf文件地址
  • defaultPage(1) //设置默认显示第1页
  • onPageChange(this) //设置翻页监听
  • onLoad(this) //设置加载监听
  • onDraw(this) //绘图监听
  • showMinimap(false) //pdf放大的时候,是否在屏幕的右上角生成小地图
  • swipeVertical( false ) //pdf文档翻页是否是垂直翻页,默认是左右滑动翻页
  • enableSwipe(true) //是否允许翻页,默认是允许翻页
  • pages() //把2 , 3 , 4 , 5 过滤掉
  • load();

3. 在项目的build.gradle添加这个依赖

1
compile 'com.joanzapata.pdfview:android-pdfview:1.0.4@aar'

4.写一个布局文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.lidong.pdf.androidpdf.MainActivity">
<com.joanzapata.pdfview.PDFView
android:id="@+id/pdfView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>

5.Activity的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package com.lidong.pdf.androidpdf;
import android.graphics.Canvas;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.ViewTreeObserver;
import android.widget.Toast;
import com.joanzapata.pdfview.PDFView;
import com.joanzapata.pdfview.listener.OnDrawListener;
import com.joanzapata.pdfview.listener.OnLoadCompleteListener;
import com.joanzapata.pdfview.listener.OnPageChangeListener;
import java.io.File;
public class MainActivity extends AppCompatActivity implements OnPageChangeListener
,OnLoadCompleteListener, OnDrawListener {
private PDFView pdfView ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pdfView = (PDFView) findViewById( R.id.pdfView );
//从assets目录读取pdf
displayFromAssets("0010000022464002F__李东.pdf");
//从文件中读取pdf
// displayFromFile( new File( "fileName"));
}
private void displayFromAssets(String assetFileName ) {
pdfView.fromAsset(assetFileName) //设置pdf文件地址
.defaultPage(1) //设置默认显示第1页
.onPageChange(this) //设置翻页监听
.onLoad(this) //设置加载监听
.onDraw(this) //绘图监听
.showMinimap(false) //pdf放大的时候,是否在屏幕的右上角生成小地图
.swipeVertical( false ) //pdf文档翻页是否是垂直翻页,默认是左右滑动翻页
.enableSwipe(true) //是否允许翻页,默认是允许翻页
// .pages() //把 5 过滤掉
.load();
}
private void displayFromFile( File file ) {
pdfView.fromFile(file) //设置pdf文件地址
.defaultPage(6) //设置默认显示第1页
.onPageChange(this) //设置翻页监听
.onLoad(this) //设置加载监听
.onDraw(this) //绘图监听
.showMinimap(false) //pdf放大的时候,是否在屏幕的右上角生成小地图
.swipeVertical( false ) //pdf文档翻页是否是垂直翻页,默认是左右滑动翻页
.enableSwipe(true) //是否允许翻页,默认是允许翻
// .pages( 2 ,5 ) //把2 5 过滤掉
.load();
}
/**
* 翻页回调
* @param page
* @param pageCount
*/
@Override
public void onPageChanged(int page, int pageCount) {
Toast.makeText( MainActivity.this , "page= " + page +
" pageCount= " + pageCount , Toast.LENGTH_SHORT).show();
}
/**
* 加载完成回调
* @param nbPages 总共的页数
*/
@Override
public void loadComplete(int nbPages) {
Toast.makeText( MainActivity.this , "加载完成" + nbPages , Toast.LENGTH_SHORT).show();
}
@Override
public void onLayerDrawn(Canvas canvas, float pageWidth, float pageHeight, int displayedPage) {
// Toast.makeText( MainActivity.this , "pageWidth= " + pageWidth + "
// pageHeight= " + pageHeight + " displayedPage=" + displayedPage , Toast.LENGTH_SHORT).show();
}
}

效果实现:
这里写图片描述
这里写图片描述

今天主要是简单使用一下,后面准备将该库进行拓展,是打开网络的pdf文件的功能。

小东子的个人技术专栏

快速定位解决Android内存泄漏

发表于 2016-09-05   |   字数统计: 2,404(字)   |   阅读时长: 9(分)

此文章来源于APP架构师这个公众号

今天的主题是Android开发中的内存泄漏,之所以说这个是因为前几天做了项目中的内存泄漏排查与解决,在这里总结一下,被提供一种快速定位解决Android内存泄漏的方案,希望大家看完有所收获。

1 奠基之石——内存泄漏概述

在介绍内存泄漏之前很有必要提及一下Android系统的垃圾回收机制。Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存回收和垃圾清理代码,对内存泄露和溢出的问题,也不需要像C程序员那样战战兢兢。这是因为在Java虚拟机中,存在自动内存管理和垃圾清扫机制。概括地说,该机制对虚拟机中的内存进行标记,并确定哪些内存需要回收,根据一定的回收策略,自动的回收内存,永不停息(Nerver Stop)的保证虚拟机中的内存空间,防止出现内存泄露和溢出问题。Android系统的垃圾回收是基于可达性分析算法(根搜索算法)的。如下图所示,从GC Roots(每种具体实现对GC Roots有不同的定义)作为起点,向下搜索它们引用的对象,可以生成一棵引用树,树的节点视为可达对象,反之视为不可达。
不可达的对象(如下图中的object5,6,7)会在系统GC的时候被回收,从而释放内存空间。
这里写图片描述
如果所有的对象都可以被顺利回收就没有本文的诞生了,举个简单的例子,我们在开发中经常使用单例模式,单例的静态特性导致其生命周期同应用一样长。有时创建单例时如果我们需要Context对象,如果传入的是Application的Context那么不会有问题。如果传入的是Activity的Context对象,那么当Activity生命周期结束时,该Activity的引用依然被单例持有,所以不会被回收,而单例的生命周期又是跟应用一样长,这个情况就叫做内存泄露(Memory Leak)。它指的是当你不再需要某个实例后,但是这个对象却仍然被引用,防止被垃圾回收(Prevent from being bargage collected)。

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Util {
private Context mContext;
private static Util sInstance;
private Util(Context context) {
this.mContext = context;
}
public static Util getInstance(Context context) {
if (sInstance == null) {
sInstance = new Util(context);
}
return sInstance;
}
}

本杰明 富兰克林曾说:A small leak will sink a great ship.意即:小漏不补沉大船。基于Android系统的设备一般来说内存就不大,特别是早期的Android设备,内存泄漏是很致命的,内存泄漏积攒到一定程度会引发内存溢出(OOM),如果处理不当直接导致程序崩溃退出。

2.了然于胸——常见的内存泄漏

一般来说在开发中我们经常会犯下下面几个错误,导致内存泄漏。这几个都是前人踩坑总结出来的,非常有参考价值,至少我在排查解决内存泄漏的时候是这样的。

2.1、单例造成的内存泄漏

Android的单例模式非常受开发者的喜爱,不过使用的不恰当的话也会造成内存泄漏。因为单例的静态特性使得单例的生命周期和应用的生命周期一样长,这就说明了如果一个对象已经不需要使用了,而单例对象还持有该对象的引用,那么这个对象将不能被正常回收,这就导致了内存泄漏。例子见上面那段代码。

2.2、非静态内部类创建静态实例造成的内存泄漏

有的时候我们可能会在启动频繁的Activity中,为了避免重复创建相同的数据资源,在Activity内部创建了一个非静态内部类的单例,每次启动Activity时都会使用该单例的数据,这样虽然避免了资源的重复创建,不过这种写法却会造成内存泄漏,因为非静态内部类默认会持有外部类的引用,而又使用了该非静态内部类创建了一个静态的实例,该实例的生命周期和应用的一样长,这就导致了该静态实例一直会持有该Activity的引用,导致Activity的内存资源不能正常回收。例子如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class MainActivity extends AppCompatActivity {
private static TestResource mResource = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (mManager == null) {
mManager = new TestResource();
}
//...
}
class TestResource {
//...
}
}

2.3、Handler造成的内存泄漏

Handler的使用造成的内存泄漏问题应该说最为常见了,平时在处理网络任务或者封装一些请求回调等api都应该会借助Handler来处理,我们经常在Activity里面这样定义一个私有的Handler对象并初始化,这种创建Handler的方式会造成内存泄漏,由于mHandler是Handler的非静态匿名内部类的实例,所以它持有外部类Activity的引用,我们知道消息队列是在一个Looper线程中不断轮询处理消息,那么当这个Activity退出时消息队列中还有未处理的消息或者正在处理消息,而消息队列中的Message持有mHandler实例的引用,mHandler又持有Activity的引用,所以导致该Activity的内存资源无法及时回收,引发内存泄漏。

1
2
3
4
5
6
7
8
9
10
11
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
//...
}
};

2.4、资源未关闭造成的内存泄漏

对于使用了BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等资源的使用,应该在Activity销毁时及时关闭或者注销,否则这些资源将不会被回收,造成内存泄漏。

3 神兵利器——检测内存泄漏的常见工具

见到这个标题有经验的开发者可能要吐槽我是标题党了,特别是从Eclipse时代走过来的开发者,以为我一要开始贴那张像**一样的MAT内存模型图或者AndroidStudio中Monitors下的实时内存占用图,又要开始分析那一条条剪不断理还乱的内存引用链,然后费尽九牛二虎之力去查找项目中无数的内存泄漏中的一个。但是,我要告诉你,你错了。其实,以前我看到内存泄漏分析文章的时候也是这样的想法,看着恐怖的MAT内存模型图,觉得内存泄漏的排查和解决简直是Android开发中登峰造极的技能。直到我遇到了她——LeakCanary,我才直到原来内存泄漏的排查和解决可以那么的优雅。LeakCanary是Square开源了一个内存泄露自动探测神器 。这是项目的github仓库地址:https://github.com/square/leakcanary 。使用非常简单,在build.gradle中引入包依赖:

1
2
3
4
5
6
debugCompile 'com.squareup.leakcanary:leakcanary-
android:1.5'
releaseCompile 'com.squareup.leakcanary:leakcanary-
android-no-op:1.5'
testCompile 'com.squareup.leakcanary:leakcanary-
android-no-op:1.5'

在Application中的onCreate方法中增加初始化代码:

1
2
3
4
5
6
7
if (LeakCanary.isInAnalyzerProcess(this)) {
// This process is dedicated to LeakCanary for
// heap analysis.
// You should not init your app in this process.
return;
}
LeakCanary.install(this);

集成后什么都不用做,按照正常测试,当有内存泄漏发生后,应用会通过系统通知栏发出通知,点击通知就可以进入查看内存泄漏的具体信息。在这里举个实践中的例子。把LeakCanary集成到项目中后,等App启动后一会,系统通知到了,点击通知,跳转到泄漏的详情页面进行查看:
这里写图片描述
很明显,WebSiteQueryActivity泄露了。首先,static 的MaskHeadView.fLayout变量引用了FrameLayout.mContext对象,这个对象的引用就是指向了WebSiteQueryActivity的实例,导致了它的泄漏,在第二节中我们说过static对象是内部的static对象是比较容易造成内存泄漏的,检查代码发现,MaskHeadView直接在WebSiteQueryActivity的xml文件中使用了,因此持有WebSiteQueryActivity的实例,因为fLayout对象是静态的,因此它的生命周期与Application同样长,因此WebSiteQueryActivity退出后,它的实例引用依然被fLayout持有,导致它无法被回收从而内存泄露了。仔细检查代码,发现fLayout并没有被外部使用到,应该是之前的开发者手抖加了个static字段上去或者是现在不用了,但是没有去掉,在这里我直接去掉了这个修饰符,在此build代码,这个内存泄漏的现象消失了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//去掉static修饰符,避免static对象引起的内存泄漏
private static FrameLayout fLayout;
public MaskHeadView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context=context;
initView(context);
}
private void initView(Context context2) {
view = LayoutInflater.from(context).inflate(R.layout.
mask_head_view, this);
fLayout=(FrameLayout) view.findViewById(R.id.
mask_container);
}

这只是个极简单的例子,但方法是一样的。顺便提一句,其实无论是MAT工具的内存分析,还是AndroidStudio中自带的分析工具亦或是LeakCanary,原理都是一样的,都是dump java heap出来进行分析,找到泄漏的问题,只是LeakCanary帮我们把分析的工作做了。
曾几何时,你以为内存泄漏分析都是这样的

这里写图片描述

但是现在你会发现其实也可以是酱紫的:
这里写图片描述

小东子的个人技术专栏

android设置toolbar的menu itemTextView颜色

发表于 2016-06-12   |   字数统计: 134(字)   |   阅读时长: 1(分)

大家可以能会修改Toolbar中menu的文字颜色,直接使用style是没有用的,使用theme就可以让你完成想要的效果

1
2
3
4
5
6
7
8
9
<!-- ToolBar -->
<style name="ToolBarStyle" parent="@style/ThemeOverlay.AppCompat.ActionBar">
<item name="android:textColorPrimary">@android:color/white</item>
<item name="android:textColorSecondary">@android:color/white</item>
<item name="android:actionMenuTextColor">@android:color/white</item>
<item name="actionMenuTextColor">@android:color/white</item>
<item name="android:textColor">@color/white</item>
<item name="android:textSize">18sp</item> <!-- 修改字体大小-->
</style>

app:theme=”@style/ToolBarStyle”

1
2
3
4
5
6
7
8
<android.support.v7.widget.Toolbar
android:id="@+id/id_tool_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:navigationIcon="?attr/homeAsUpIndicator"
app:theme="@style/ToolBarStyle">
1…8910
李东

李东

细节决定成败,点滴铸就辉煌

46 文章
18 标签
© 2017 李东
由 Hexo 强力驱动
主题 - NexT.Pisces