Skip to content

Commit ba9ddf0

Browse files
完善《Android开发遇到的坑》
1 parent 7ff895d commit ba9ddf0

File tree

2 files changed

+183
-3
lines changed

2 files changed

+183
-3
lines changed

Android开发遇到的坑汇总/Android开发遇到的坑.md

Lines changed: 118 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
## Android开发遇到的坑汇总
1+
# Android开发遇到的坑汇总
22

3-
> Toolbar去除标题与返回键间的间距
3+
----
4+
5+
#### Toolbar去除标题与返回键间的间距
46

57
给toolbar加上以下属性:
68

@@ -28,4 +30,117 @@
2830
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
2931
app:theme="@style/ToolbarStyle"
3032
app:title="标题"
31-
app:titleTextColor="@color/colorWhite">
33+
app:titleTextColor="@color/colorWhite">
34+
35+
#### RecyclerView常见的一些坑
36+
> (1)ScrollView(或RecyclerView1)嵌套RecyclerView2,结果内部的RecyclerView2会自动的滑动至顶部.(一般情况下不推荐嵌套使用具有滑动功能的View)
37+
两种解决办法:
38+
39+
**方法一、**让内部Recyclerview去除焦点,父布局里获得焦点。具体如下:
40+
41+
给内部的Recyclerview设置以下代码:
42+
43+
recyclerview.setFocusableInTouchMode(false);
44+
recyclerview.requestFocus();
45+
46+
比如父布局的一个textview。
47+
48+
textview.setFocusableInTouchMode(true);
49+
textview.requestFocus();
50+
51+
**方法二、**在布局里面加相关属性:
52+
53+
内部的Recyclerview加这个属性:
54+
55+
android:overScrollMode="never"
56+
父布局覆盖子View获取焦点,加这个属性:
57+
58+
android:descendantFocusability="blocksDescendants"
59+
60+
> (2)RecyclerView 高度设置wrap_content 不显示的解决:
61+
62+
给RecyclerView的高度设置为`wrap_content`,结果整个模块什么也不显示,这是RecyclerView兼容包的bug,`23.2.0后`官方已经修复了。
63+
64+
【解决方式】在gradle里设置用23.2.0及以上的RecyclerView版本:
65+
66+
compile 'com.android.support:recyclerview-v7:23.2.0'
67+
68+
如果修改后重新build时报了其他奇怪的错,可以试试把以下相关兼容包也升级一下:
69+
70+
compile 'com.android.support:cardview-v7:23.2.0'
71+
compile 'com.android.support:appcompat-v7:23.2.0'
72+
compile 'com.android.support:design:23.2.0'
73+
74+
> (3)RecyclerView 中的item布局宽度设置match_parent属性失效的问题解决:
75+
76+
//这里为了解决RecyclerView不能撑满全屏的问题,这里layoutManager不管你布局里是否设置,都不能解决问题,所以需要在代码里`重新设置MATCH_PARENT`
77+
78+
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()) {
79+
@Override
80+
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
81+
return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
82+
ViewGroup.LayoutParams.WRAP_CONTENT);
83+
}
84+
};
85+
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
86+
recyclerview.setLayoutManager(layoutManager);
87+
关于为什么`RecyclerView 中的item布局宽度设置match_parent属性失效`的原因详解可以参考这篇博客,有详细介绍:[https://blog.csdn.net/overseasandroid/article/details/51840819](https://blog.csdn.net/overseasandroid/article/details/51840819)
88+
89+
#### NumberFormatException
90+
91+
起因是Bugly上报了一个错误:
92+
93+
#main(1)
94+
java.lang.NumberFormatException
95+
Invalid float "0,00"
96+
97+
说是我格式化“0,00”这样的一个字符串。出错的地方的代码大致如下:
98+
99+
String.format("%.2f", number);
100+
101+
经排查排除了格式字符串的问题后,最后发现是格式化的问题:`在不指定Locale时,是跟随系统语言`。在法语、德语、意大利语的语言中,格式化小数是逗号的。所以解决方法,指定一下语言:
102+
103+
String.format(Locale.CHINA, "%.2f", number);
104+
105+
#### SecurityException
106+
107+
在之前项目中做了6.0的动态权限后,Bugly报错如下,而且报错的全部都是6.0的手机:
108+
报错的意思翻译一下是:没有动态授权`CHANGE_NETWORK_STATE``WRITE_SETTINGS`权限。
109+
110+
查了一下,找到了问题。发现是6.0的一个bug,在部分6.0上CHANGE_NETWORK_STATE权限获取不到,那么只能去获取WRITE_SETTINGS这个权限了。这个问题已经在6.0.1修复了。关于这个bug详细讲解可以查看博客 [Android M WRITE_SETTINGS权限的一个BUG](https://www.jianshu.com/p/bab716584316)
111+
112+
【解决方式1】
113+
既然是6.0的问题,我们可以对6.0进行单独处理。抛出异常处或者在使用`CHANGE_NETWORK_STATE`权限前跳转到系统设置页去设置。
114+
115+
if(Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
116+
if (!Settings.System.canWrite(context)) {
117+
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS);
118+
intent.setData(Uri.parse("package:" + context.getPackageName()));
119+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
120+
context.startActivity(intent);
121+
}
122+
}
123+
124+
【解决方式2】以上方式每次都要手动去设置,很麻烦,可以看看这篇博文,写的很仔细 [Android 6 完美解决 WRITE_SETTINGS 权限设置问题](https://www.jianshu.com/p/0b880871b887)
125+
126+
### 在做6.0动态权限时,如果有申请相机权限时,应该保证`Manifest.permission.CAMERA``Manifest.permission.WRITE_EXTERNAL_STORAGE`权限同时申请,不要漏掉后者。
127+
128+
### 使用Glide时,注意对传入的Acticity与Fragment进行判断,避免传入已经销毁Acticity,造成`IllegalArgumentException`异常。可以参考这篇[Glide类似You cannot start a load for a destroyed activity异常简单分析](https://blog.csdn.net/loners_/article/details/73521968)
129+
130+
### [不要在Android的Application对象中缓存数据!](https://www.jianshu.com/p/83f0046bc310)
131+
132+
133+
134+
----
135+
136+
> 参考博文:
137+
138+
https://blog.csdn.net/qq_17766199/article/details/52661363
139+
https://blog.csdn.net/qq_17766199/article/details/79941199
140+
https://blog.csdn.net/geolo/article/details/7058515
141+
142+
**【说明】我这个总结主要是针对平时开发遇到的问题的一个汇总,由于实际开发项目不同,用到的技术和接触的一些东西也不一样,所以可能这里找不到你遇到的坑,不过没关系,我发现了一个github总结的很全面,有基础的使用,有NDK遇到的坑,有framework层的坑,有linux有关的坑等。。。如果对你有帮助的话,有兴趣的也可以过去看一下:[android-issues](https://github.com/ayyb1988/android-issues)**
143+
144+
----
145+
146+
# 有什么问题,欢迎大家提出,如果你也遇到了其他的坑,也欢迎提交给我,我会把它收集在这里,让大家都来学习一下,避免少走弯路。
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# 双击back返回键退出app功能的实现方式
2+
3+
有两种实现思路,看个人喜好吧:
4+
5+
### 方式1:
6+
7+
8+
public class MainActivity extends Activity {
9+
10+
private Toast toast;
11+
12+
@Override
13+
protected void onCreate(Bundle savedInstanceState) {
14+
super.onCreate(savedInstanceState);
15+
setContentView(R.layout.activity_main);
16+
toast = Toast.makeText(getApplicationContext(), "确定退出?", 0);
17+
}
18+
19+
public void onBackPressed() {
20+
quitToast();
21+
}
22+
23+
private void quitToast() {
24+
if(null == toast.getView().getParent()) {
25+
toast.show();
26+
}else{
27+
System.exit(0);
28+
}
29+
}
30+
}
31+
32+
33+
### 方式2:
34+
35+
public class MainActivity extends Activity {
36+
37+
private Toast toast;
38+
rotected void onCreate(Bundle savedInstanceState) {
39+
...
40+
toast = Toast.makeText(this, "再按一次退出应用", Toast.LENGTH_SHORT);
41+
toast.setGravity(Gravity.BOTTOM, 0, ConversionUtil.dip2px(this, 150));
42+
}
43+
44+
@Override
45+
public void onBackPressed() {
46+
if (doubleBackToExitPressedOnce) {
47+
if(toast!=null){
48+
toast.cancel();
49+
}
50+
super.onBackPressed();
51+
return;
52+
}
53+
54+
this.doubleBackToExitPressedOnce = true;
55+
toast.show();
56+
57+
new Handler().postDelayed(new Runnable() {
58+
59+
@Override
60+
public void run() {
61+
doubleBackToExitPressedOnce=false;
62+
}
63+
}, 2000);
64+
}
65+
}

0 commit comments

Comments
 (0)