“我的代码怎么可能会有bug,为什么crash了?”
“明明我就是按这个操作来的,为啥我这个就不行?肯定是这个人的代码有问题。”
“我好像以前碰过这个问题,怎么解决的啊?”
“这都是些什么问题”
“这真是令人窒息的操作”
“。。。。”
明天你是否会想起,那些你踩过的坑?
在开发中难免遇到令人摸不着头脑,或者明明很熟悉却就是不知道怎么做的问题,下面将记录平时中本人遇到的一些操作解决方法,都是平时笔记中的东西,现在拿出来整理一下,也算是一个回顾,大家有遇到类似的问题也可以参考一下。
·使用ButterKnife时总是报空指针异常
解决方法:
1.首先在Project的build.gradle文件中增加
2.在Module的build.gradle文件中增加两个地方:
·android studio 编译错误
解决方法:
看起来貌似是什么label属性冲突了。那就在清单文件中修改:
·RecyclerView与CheckBox的嵌套问题
在RecyclerView中使用CheckBox的时候由于复用问题,会导致滑动后在同样的位置选中
解决方法:
第一种暴力方式:
holder.setIsRecyclable(false);
直接不开启复用,缺点:效率更低,可能卡顿
第二种:
1.创建一个用来装position的集合
private List<Integer> mCheckPositions;
2.在bindView的时候先为checkbox设置tag
((CityHolder) holder).checkBox.setTag(position);
3.根据checkbox的position和集合中的值进行比较,如果包含的话就设置setChecked为true,反之为false
if (mCheckPositions != null) {
((CityHolder) holder).checkBox.setChecked(mCheckPositions.contains(holder.getAdapterPosition()) ? true : false);
} else {
((CityHolder) holder).checkBox.setChecked(false);
}
4.监听checkbox的oncheck动作,再选中状态将其position存入list集合中
((CityHolder) holder).checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
if (!mCheckPositions.contains(((CityHolder) holder).checkBox.getTag())) {
int position = holder.getAdapterPosition();
mCheckPositions.add(position);
} else {
if (mCheckPositions.contains(((CityHolder) holder).checkBox.getTag())) {
int position = holder.getAdapterPosition();
// mCheckPositions.remove(position);
}
}
}
}
});
·Getting android.content.res.Resources$NotFoundException: exception even when the resource is present in android
异常引起的原因是TextView设置setText的时候里面放的是非String类型的值
·Cannot merge new index 65536 into a non-jumbo instruction!
异常引起是因为项目中的方法数太多
解决方法:
使用dex分包:
compile 'com.android.support:multidex:1.0.1'
在项目的build中添加如下
android {
dexOptions {
jumboMode = true
}
}
·百度地图设置缩放级别
mBaiduMap = mMapView.getMap();
mMapView为百度控件com.baidu.mapapi.map.MapView的ID初始化后的名称
然后
MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.zoomBy(2);
mBaiduMap.animateMapStatus(mapStatusUpdate);
zoomBy里面的数字就代表着缩放级别
【8,+∞):大于等于8的缩放级别都是10米
【7, 8):大于等于7小于8的缩放级别都是20米
【6, 7):大于等于6小于7的缩放级别都是50米
【5, 6):大于等于5小于6的缩放级别都是100米
【4, 5):大于等于4小于5的缩放级别都是200米
【3, 4):大于等于3小于4的缩放级别都是500米
【2, 3):大于等于2小于3的缩放级别都是1千米
【1, 2):大于等于1小于2的缩放级别都是2千米
【0, 1):大于等于0小于1的缩放级别都是5千米
【-1, 0):大于等于-1小于0的缩放级别都是10千米
【-2,-1):大于等于-2小于-1的缩放级别都是20千米
【-3,-2):大于等于-3小于-2的缩放级别都是25千米
【-4,-3):大于等于-4小于-3的缩放级别都是50千米
【-5,-4):大于等于-5小于-4的缩放级别都是100千米
【-6,-5):大于等于-6小于-5的缩放级别都是200千米
【-7,-6):大于等于-7小于-6的缩放级别都是500千米
【-8,-7):大于等于-8小于-7的缩放级别都是1000千米
(-∞,-8):小于-8的缩放级别都是2000千米
建议:写缩放级别的最好写在registerLocationListener的外面,避免隔一段时间缩放又回到原来的状态。
·Android中修改弹出dialog背景无色透明,弹出时有遮罩
1
然后引用
·RecyclerView跳转到指定位置
方法一,直接使用当前的manager
/**
* RecyclerView 移动到当前位置,
*
* @param manager 设置RecyclerView对应的manager
* @param n 要跳转的位置
*/
public static void MoveToPosition(LinearLayoutManager manager, int n) {
manager.scrollToPositionWithOffset(n, 0);
manager.setStackFromEnd(true);
}
方法二、根据当前RecyclerView的条目数量,这个相对复杂一些,但是可以有效地避免指针越界呦..
/**
* RecyclerView 移动到当前位置,
*
* @param manager 设置RecyclerView对应的manager
* @param mRecyclerView 当前的RecyclerView
* @param n 要跳转的位置
*/
public static void MoveToPosition(LinearLayoutManager manager, RecyclerView mRecyclerView, int n) {
int firstItem = manager.findFirstVisibleItemPosition();
int lastItem = manager.findLastVisibleItemPosition();
if (n <= firstItem) {
mRecyclerView.scrollToPosition(n);
} else if (n <= lastItem) {
int top = mRecyclerView.getChildAt(n - firstItem).getTop();
mRecyclerView.scrollBy(0, top);
} else {
mRecyclerView.scrollToPosition(n);
}
}
·TextView解析a标签,用Html.fromHtml()方法后URL链接有自带颜色和下划线
Tv.setText(Html.fromHtml(url));//解析html
mTv.setMovementMethod(LinkMovementMethod.getInstance());//设置可点击
这样默认是用浏览器打开a标签里面的链接,但是如果要获取到a标签的点击事件和链接的话,得换一个方法
在textview的布局文件里面加入这个属性
android:autoLink="all"
public static void setLinkClickable(final SpannableStringBuilder clickableHtmlBuilder,
final URLSpan urlSpan, final String color) {
int start = clickableHtmlBuilder.getSpanStart(urlSpan);
int end = clickableHtmlBuilder.getSpanEnd(urlSpan);
int flags = clickableHtmlBuilder.getSpanFlags(urlSpan);
ClickableSpan clickableSpan = new ClickableSpan() {
public void onClick(View view) {
//Do something with URL here.
String url = urlSpan.getURL();
}
public void updateDrawState(TextPaint ds) {
//设置颜色
ds.setColor(Color.parseColor(color));
//设置是否要下划线
ds.setUnderlineText(false);
}
};
clickableHtmlBuilder.setSpan(clickableSpan, start, end, flags);
}
public static CharSequence getClickableHtml(String html,String color) {
Spanned spannedHtml = Html.fromHtml(html);
SpannableStringBuilder clickableHtmlBuilder = new SpannableStringBuilder(spannedHtml);
URLSpan[] urls = clickableHtmlBuilder.getSpans(0, spannedHtml.length(), URLSpan.class);
for (final URLSpan span : urls) {
setLinkClickable(clickableHtmlBuilder, span,color);
}
return clickableHtmlBuilder;
}
使用:
holder.tv_7_content.setText(TextViewTool.getClickableHtml(liveBroadcastData.content,"#4f70ff"));
holder.tv_7_content.setMovementMethod(LinkMovementMethod.getInstance());
·ListView的setSection()方法失效
用listview的smoothScrollToPosition() 方法
·ListView滑动距离获取
public int getScrollY() {//获取滚动距离
View c = listView.getChildAt(0);
if (c == null) {
return 0;
}
int firstVisiblePosition = listView.getFirstVisiblePosition();
int top = c.getTop();
int headerHeight = 0;
if (firstVisiblePosition >= 1) {
headerHeight = listView.getHeight();
}
return -top + firstVisiblePosition * c.getHeight() + headerHeight;
}
·SP保存Map数据时key value中有自己的JavaBean类
保存时Gson对象为
Gson gson = new GsonBuilder().enableComplexMapKeySerialization().create();
保存:
String s = gson.toJson(map1);
解析:
Map<Point, String> retMap = gson.fromJson(s, new TypeToken<Map<Point, String>>(){ }.getType());
·android下载文件存储到本地的时候,下载成功本地文件却没有
原因是在下载的时候对汉字进行了解析为ASCII字符。所以对String进行如下操作:
new URI(fileUrl).toASCIIString()
·为项目创建不同的res便于项目管理
http://antonioleiva.com/android-multiple-resource-folders/
·ButterKnife点击事件没有反应
在添加依赖的时需要添加两个:
compile 'com.jakewharton:butterknife:8.4.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
·TextView在代码中设置drawLeft
·