Android编程权威指南(第3版)这本书是基于Android7.0的,到现在已通过于古老,最新的Android版本已经到10,而这本书的第四版目前尚未正式发售,在最近阅读这本书时,我发现这本书的部分代码已经不适合最新的Android开发,因此写下了这篇文章,将我碰到的坑写下来,帮助如今一样在学习使用这本书的人。java
本文所说的环境基于AndroidStudio 3.5,Android SDK 28。android
在本书第七章7.3.3(中文第三版109页)中写道编程
要使用AppCompat支持库,项目必须将其列入依赖关系。打开应用模块下的build.gradle文件。每一个项目都有两个build.gradle文件。一个用于整个项目,另外一个用于应用模块。咱们要编辑的是app/build.gradle文件。
app
但在最新版的AndroidStudio中,这步是能够跳过的,在Google最新的文档中,建议使用AndroidX代替com.android.support 包
ide
按照官方文档说明 AndroidX 是对 android.support.xxx 包的整理后产物。因为以前的 support 包过于混乱,因此,Google 推出了AndroidX。布局
因为在后续版本中,会逐步放弃对 support 的升级和维护,因此若是是新的项目建议直接使用AndroidX,若是是旧项目,也建议直接迁移到AndroidX学习
具体见如下的Google Android文档。gradle
https://developer.android.google.cn/jetpack/androidxui
回到正题,最新的Android Studio中会默认引入AndroidX的appcompat包,因此彻底没必要要进行这一步的操做。google
在本书第八章8.3.2使用使用 RecyclerView 中
书中写道
RecyclerView类来自于Google支持库。要使用它,首先要添加RecyclerView依赖库。
这句话是对的,但以后说
找到并选择recyclerview-v7支持库,单击OK按钮完成依赖库添加,
这句话就不使用于Android9.0以上的开发了,就像上文说的,咱们应该引入的是AndroidX的支持库,而不是recyclerview-v7
app/build.gradle文件,在 dependencies 中添加如下语句,引入 androidx.recyclerview:recyclerview:1.0.0
implementation 'androidx.recyclerview:recyclerview:1.0.0'
完成后以下
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.recyclerview:recyclerview:1.0.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' }
代码清单8-15 在布局文件中添加RecyclerView视图( fragment_crime_list.xml) 的根节点也就不该该是
android.support.v7.widget.RecyclerView
而应该是
androidx.recyclerview.widget.RecyclerView
完整版以下
<?xml version="1.0" encoding="utf-8"?> <androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/crime_recycler_view"> </androidx.recyclerview.widget.RecyclerView>
仍是第八章8.3.4实现 ViewHolder 和 Adapter(中文第三版143页) 中
代码清单8-17定义ViewHolder内部类( CrimeListFragment.java)
原文的代码是下面这段
public class CrimelistFragment extends Fragment { ... private class CrimeHolder extends RecyclerView.ViewHolder { public CrimeHolder(LayoutInflater inflater, ViewGroup parent) { super(inflater.inflate(R.layout.list_item_crime, parent, false)); } } }
若是和我同样使用的是Android Studio的3.5版本的话,你就会发现,Android Studio的的代码自动不全生成的是以下的代码
public class CrimeHolder extends RecyclerView.ViewHolder { public CrimeHolder(@NonNull View itemView) { super(itemView); } }
明明在书上CrimeHolder构造方法应该是有两个参数的,而Android Studio生存的构造方法只有一个参数。
这是为何呢,由于Google将实例化 list_item_crime 布局的过程挪到了以后实现 Adapter 的 onCreateViewHolder 方法
在代码清单8-19 武装CrimeAdapter( CrimeListFragment.java) 中,书中的代码以下
private class CrimeAdapter extends RecyclerView.Adapter<CrimeHolder> { ... @Override public CrimeHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater layoutInflater = LayoutInflater.from(getActivity()); return new CrimeHolder(layoutInflater, parent); } @Override public void onBindViewHolder(CrimeHolder holder, int position) { } @Override public int getItemCount() { return mCrimes.size(); } }
若是按书中的代码,你会发现滴6行 new CrimeHolder 明显没法经过编译,毕竟看参数就能看出来
那么这段应该怎么写呢?
前文说到 实例化 list_item_crime 布局的过程挪到了以后实现 Adapter 的 onCreateViewHolder 方法,也就是说,咱们须要作的就是将书中本来在 CrimeHolder 实例化 list_item_crime 的过程挪到 onCreateViewHolder 方法之中。
具体代码以下:
@NonNull @Override public CrimeHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(getActivity()).inflate(R.layout.list_item_crime, parent, false); return new CrimeHolder(view); }
未完待续。。。
ps:本人也在学习这本书,目前的进度就到这里,之后发现新的问题再补充。