问题记录
- 这篇博客我会不定时更新,记录内容为我在Android开发过程中遇到的实际问题以及解决方法,当然,也会存在未解决的问题,如果各位看官有知道的 方便的话也可以在评论区留言指出,谢谢啦~
- 开发工具为
Android Studio
- 开发工具为
问题一(CirclerImageView 设置 selector 不成功)
- 开源库
CirclerImageView
设置selector
不成功,点击并不会触发selector
内设的逻辑。(设置了clickable
的)- 虽然它是继承自
ImageView
的,但是这一点并不与ImageView
一致。 - 原因未知
- 虽然它是继承自
问题二(Default Activity Not Found,app出现红叉,build.gradle、values下的文件出现乱码)
- 有些代码写着写着就跑步起来了,当然,代码本身并没有问题,编译也是没有问题,就是跑不起来,app出现红叉,提示
Default Activity Not Found
,但是一检查<intent-filter>
标签加的好好的,这就很奇怪了,明明设置了默认活动的,为什么找不到呢?先不急,仔细看看自己的代码,又发现了Project
下的build.gradle
里面的代码居然全变为了乱码,values
下面的文件中的代码也是如此,再深入研究,你又会发现,连新建的项目都出现了这个错误- 可以明确的告诉你,并不是你的代码写得有问题,而是 Android Studio 自己的问题,下面有两种解决办法,第一种肯定是可行的,第二种我刚开始弄完之后是可行的,可是后面又时不时的出现错误···所以推荐第一种,简单准确!
- 解决方法一:将
C:\Users\用户名\.AndroidStudio3.4\system\caches
这个文件夹直接删除,然后重启Android Studio
就行啦 - 解决方法二:其实就是这四个文件乱码导致的原因(
values
下有默认三个文件,加上build.gradle
这个文件),所以我们就改变它们的编码格式即可。- 使用任意编译器,打开这四个文件,设置编码为
UTF-8
然后保存,就是这么简单,这下重启项目即可。 - 在这之前,我还使用了其他的方法,比如改
Android Studio
的编码格式等等,都不行 0_0吗,真惨
- 使用任意编译器,打开这四个文件,设置编码为
问题三(findViewByPosition() 方法返回值为 null)
- 在给
RecyclerView
找Item
的View
实例时,通过LinearLayoutManager
的findViewByPosition()
方法拿到的View
实例会出现null
的情况,前提是在监听RecyclerView
滑动的时候,如下:
public class FragmentRoute extends Fragment {
···
//判断是否是第一次滑动
private static boolean mIsFirstSmooth;
//一个临时变量,用于记录上一次的位置
private static int temp;
···
private static final String TAG = "FragmentRoute";
···
private void init(View view) {
···
//因为我一开始是要指定 Item 为中间的一个,所以一开始初始化这个 temp 为 中间位置
temp = recyclerView.getWidth() / 2;
···
}
/**
* 计算 RecyclerView 的滑动距离
* @return 滑动距离
*/
public int getSmoothDistance() {
int now = recyclerView.computeHorizontalScrollOffset();
//先对第一次滑动作单独处理
if (mIsFirstSmooth) {
int ret = Math.abs(now - temp);
temp = now;
mIsFirstSmooth = false;
return ret;
} else {
//第一次滑动结束后,后面的都在这块代码中
int ret = Math.abs(now - temp);
temp = now;
return ret;
}
}
}
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@SuppressLint("ResourceType")
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
···
//下面的三个实例会时不时的出现 null 的情况
apply = manager.findViewByPosition(0);
my = manager.findViewByPosition(1);
all = manager.findViewByPosition(2)
···
}
}
}
- 原因未解决:推测应该是滑动监听这里有问题,所以我直接在
Adapter
中去拿View
了
问题四(计算 recyclerView 滑动距离的方法)
- 设置计算
recyclerView
滑动距离的方法- 我开始使用的是
computeHorizontalScrollOffset()
这个方法,后面才感觉并不是从中间的一个Item
开始计时的,这里把我搞蒙了0_0(还是太才了,源码没怎么看懂,都是返回0?)
- 我开始使用的是
- 解决:经过我打印出来的结果,这个方法计算的是其他
Item
到第一个Item
的距离,于是,我就写出了这样一个计算RecyclerView
滑动距离的方法了(代码比较简单,不作过多说明了,因为我看其他博客都是去计算Item
高度,但是那样每个Item
高度不一样就不行了,所以我写了一个这样的方法)- 注意:我这里的
RecyclerView
是水平的哦!垂直也是类似的,自己思考咯~
- 注意:我这里的
public class FragmentRoute extends Fragment {
···
//判断是否是第一次滑动
private static boolean mIsFirstSmooth;
//一个临时变量,用于记录上一次的位置
private static int temp;
···
private static final String TAG = "FragmentRoute";
···
private void init(View view) {
···
//因为我一开始是要指定 Item 为中间的一个,所以一开始初始化这个 temp 为 中间位置
temp = recyclerView.getWidth() / 2;
···
}
/**
* 计算 RecyclerView 的滑动距离
* @return 滑动距离
*/
public int getSmoothDistance() {
int now = recyclerView.computeHorizontalScrollOffset();
//先对第一次滑动作单独处理
if (mIsFirstSmooth) {
int ret = Math.abs(now - temp);
temp = now;
mIsFirstSmooth = false;
return ret;
} else {
//第一次滑动结束后,后面的都在这块代码中
int ret = Math.abs(now - temp);
temp = now;
return ret;
}
}
}
问题四(SurfaceView 加载黑屏的情况)
- 一般使用
SurfaceView
重写的三个构造方法(与自定义 View 类似的),默认为super
(调用的父类的),这样就会出现黑屏,绘制不出东西来 - 解决:手动使用
this
去调用重写的构造方法- 原因未知,父类构造方法也是这样实现的
太麻烦了,先这样写, 后续修改
已解决问题
1. 小细节,场景:根据不同的packageId来创建对应的文件,并进行写入
添加的分隔符“/”位置在路径后面,导致文件路径不符合预期
2. 网络请求失败,写入文件byte size = 0
下载失败,排查file为未创建、url地址错误、file.name错误
原因:项目中下载库已经创建了file,不需要我们在手动创建
3. module中我的修改push不到远端,且文件呈黄色,并且,add后通过status查看,没有我的修改
as中,黄色文件表示未加入git,被忽略了
解决:在as的设置中,找到versino control,发现该module被unegiste了
将该module加入到version control中,并从unregiste中移除
4. 在fragment中使用kotlin-android-extensions代替findViewById,出现空指针
原因:与 Activity 不同的是,Fragment 需要在 onViewCreated 中使用控件才行,否则会报空指针异常
反编译后,查看,内部会调用onCreateView()拿到View,如果是null,则返回null,而在onCreateView()中使用的话,拿到的这个View必然是null的
5. 使用ViewPager + tabLayout时,在setupWithViewPager()之前手动调用setText()去设置title,是不会显示的
原因:内部会重新调用view pager的getPageTitle()方法去设置title
6. 在kotlin中,继承 RecyclerView的viewholder时,如果构造方法中设置一个 val itemView: View 属性,那么在使用的时候就会出错:Overload resolution ambiguity. All these functions match
原因:kotlin代码中的val itemView: View,对应到java代码,就是:public final View itemView,而ViewHolder中本来就有一个一摸一样的itemView,就会导致:父类与子类直接的属性冲突
7. 序列化时,所有对象都需要进行序列化(包括对象内部的属性)
8. notifyDataSetChanged(),更新数据,必须保证是同一个数据源(如:同一个list,就意味着不能将另一个list的引用赋值给这个list)
9. tablayout的tab默认没有添加颜色,就是主题色,而主题是白色就会显示为没有text的样子
内部是通过TextView进行展示的,而Textview的布局没有设置textColor,所有就是主题色
10. viewPager的滑动事件被activity拦截了,但是有个疑点:在version item list这边的滑动是没有被拦截的,只有ppe配置那边的滑动被拦截了
猜测:从SlideActivity的onSlideFinish方法入手
11. scrollView内部如果嵌套了一个relativelayout,则RelativeLayout的match_parent不起作用,不能把ScrollView 撑起来
解决:设置ScrollView属性:android:fillViewport="true"填充内容
12. scrollView滑动问题,先看看布局有没有超出屏幕,超出屏幕才能看出到底滑没化
重申:并不是网上说的包装relativelayout不能滑动
13. 如果item高度超过了屏幕高度,请使用wrap_content
14. 实现吸顶效果,通过removeView()、addView()实现的效果,存在略微卡顿,闪烁现象
原因:主布局是:title + list这种形式
吸顶的实现是:通过remove tab,然后将tab add到title的父布局中,是一个LinearLayout
就在于这个LinearLayout父布局,是wrap_content,然后当滑动到顶部时,加入一个tab到title中时,父布局LinearLayout变高了,将recyclerView顶下去了,但是又因为我手指还未移走,所以视图又回到了原来的item位置,就出现了闪烁的现象
解决:在LinearLayout下面放了一个FramLayout,add View的时候就add到这个里面去
15. 第一个put操作会报空指针,原因是put方法返回一个先前值,但是这里是第一次调用,所以返回的是一个null,而我们外面的接收类型是int,会执行自动拆箱操作,所以会为空
git操作也是类似的
HashMap<Integer, Integer> elementCountMap = new HashMap<Integer, Integer>();
int oldCount = elementCountMap.put(nums[index++], 1);
int index = 0;
while (index <= nums.length - 1) {
int oldCount = elementCountMap.put(nums[index++], 1);
if (oldCount != 0)
elementCountMap.put(nums[index++], ++oldCount);
}
其他
1. 使用Inten传递Bundle时,两个方法的区别
putExtra(String name, @Nullable Bundle value) :将Bundle存入Intent内部的Bundle的map中
putExtras(@NonNull Bundle extras) :将Bundle中的数据存到Intent内部的Bundle中
2. 一般在recyclerView中,去拿item的某一个子View,是先去拿的ViewHolder,然后再去拿View
findViewHolderForAdapterPosition(),或者其他的findViewHolder方法
3. as 后面一搬写一个?,防止强转失败,程序崩溃
4. 不想写安全调用?,可以在变量赋值时,后面加一个运算符 ?: 空值
5. 关于一个view的实例,如果该实例是不会变的(即使它的parent View变了,但本身是没变的),则我们通过findViewById(),拿到的View,就可以存起来,下次直接用就行了,不用每次都去findViewById
6. removeView:会先确定view的索引,然后再便利父View,找到该View,进行移除(置空它的parent引用、以及自己的引用)
addView:会先对父View进行布局、绘制、然后再添加View,进行布局、绘制
使用View.GONE、View.VISIBILITY来代替,这两个方法虽然也会重新进行布局、绘制,但不存在View移除/添加问题,只会更新一下View树
使用ViewStub代替setVisibility(View.GONE的View是占内存的,只是不显示而已)
7. modole.text?.isNotBlank() == true,这行判断语句,不能改为 != false
原因:对于可空值的判断,是有三种情况的:null、false、true,一定要注意,想要什么条件的时候才继续往下执行(别忘了三个值中的null)