• 使用最新AndroidStudio编写Android编程权威指南(第3版)中的代码会遇到的一些问题


    Android编程权威指南(第3版)这本书是基于Android7.0的,到如今已经过于古老,最新的Android版本已经到10,而这本书的第四版目前还没有正式发售,在最近阅读这本书时,我发现这本书的部分代码已经不适合最新的Android开发,所以写下了这篇文章,将我碰到的坑写下来,帮助现在同样在学习使用这本书的人。

    本文所说的环境基于AndroidStudio 3.5,Android SDK 28。

    在本书第七章7.3.3(中文第三版109页)中写道

    要使用AppCompat支持库,项目必须将其列入依赖关系。打开应用模块下的build.gradle文件。每个项目都有两个build.gradle文件。一个用于整个项目,另一个用于应用模块。我们要编辑的是app/build.gradle文件。

     但在最新版的AndroidStudio中,这步是可以跳过的,在Google最新的文档中,建议使用AndroidX代替com.android.support 包

    按照官方文档说明 AndroidX 是对 android.support.xxx 包的整理后产物。由于之前的 support 包过于混乱,所以,Google 推出了AndroidX。

    由于在后续版本中,会逐步放弃对 support 的升级和维护,所以如果是新的项目建议直接使用AndroidX,如果是旧项目,也建议直接迁移到AndroidX

    具体见以下的Google Android文档。

    https://developer.android.google.cn/jetpack/androidx

    回到正题,最新的Android Studio中会默认引入AndroidX的appcompat包,所以完全不必要进行这一步的操作。

    在本书第八章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 武装CrimeAdapterCrimeListFragment.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:本人也在学习这本书,目前的进度就到这里,以后发现新的问题再补充。

  • 相关阅读:
    SqlServer2008启动不了的问题
    .exe 不包含适合入口点的静态“Main”方法
    两种常用的序列化
    异或运算^
    SqlServer数据库实现C#中的split功能
    遍历电脑下面所有文件--递归
    ExecuteNonQuery引发了System.ArgumentException类型异常
    JQuery属性过滤(转)
    SQL SERVER 执行远端数据库的SQL命令
    马云:做一个静静的观察者 能学到更多
  • 原文地址:https://www.cnblogs.com/puzhiwei/p/11653739.html
Copyright © 2020-2023  润新知