用正确的理念和工具,10分钟学会Android开发

531 阅读4分钟

目标

大多数企业实际工作中 90% 的 App 开发需求,都是和 RESTful 的 API 接口交互数据并展示的需求,本教程实现这样的基本需求,基于快速框架 Genos 链接

完全掌握Genos需要一天到两周不等,然后你就可以去找一份工作了。

相信我,你会比市场上半数以上的 Android 程序员做出的 App 要稳定美观,且代码量少的多。

为什么要用 Genos, 请看教程之后的内容


教程开始

完整代码见 https://github.com/nyssance/genos-samples 的 V2EXSample

第零步 (1 分钟到一天到放弃不等): 下载 Java8 和 Android Studio 3.0.1, 学一点 Java

第一步 (1 分钟,视病情轻重,强迫症患者可能会到 5-30 分钟不等,主要用于纠结 package 名和项目名): 创建一个新项目

Start a new project. 官方指南

Screen Configure
Target Android Devices Phone and Tablet : API 17
Add an Activity to Mobile Empty Activity

配置_Gradle Scripts: build.gradle (Module: app)_.

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    // 替换为 Genos
    // implementation 'com.android.support:appcompat-v7:26.1.0'
    // implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    implementation 'com.nyssance.genos:genos:1.0.0-rc2'
    ...

然后sync, 有关 Android 中 使用 gradle 的知识,以及同步如果被墙如何解决,可自行百度

第二步 (2 分钟): 创建模型类

  • 访问 V2EX 最热主题地址 https://www.v2ex.com/api/topics/hot.json
  • 复制取第一条数据,贴到 http://www.jsonschema2pojo.org/, Source type 选 JSON, Annotation style 选 Gson, 选中 Use primitive types, 本教程不要选 Include getters and setters (实际工作中看个人偏好)
  • 生成 Topic, Node, Member 三个模型类,下载放入你的项目源码中(真实工作中,所有模型类应由服务端生成提供给客户端程序员,如果贵司不是这个方式,且认为这是客户端自己的工作,嗯,考虑换家公司吧,工程和管理水平太弱)
  • for iOS: Gson 就是 Android 界的 ObjectMapper

第三步 (5 分钟): 写必要的类

以下代码示例均不含 import, 如果你是 Mac 电脑,把光标移动到每个标红的地方,然后Alt + 回车,会自动完成需要的操作

AppService.java (实际工作中这个类也不应该手写,而应该由服务器端根据格式生成,因为 API 都是服务器端提供的)

public interface APIService {
    @GET("topics/{pk}.json")
    Call<List<Topic>> topicList(@Path("pk") String pk);

    @GET("nodes/show.json")
    Call<Node> nodeList(@Query("name") String name);

    @GET("members/show.json")
    Call<Member> memberList(@Query("id") int id);
}

AppManager.java

public class AppManager extends BaseAppManager {
    private static final AppManager INSTANCE = new AppManager();
    public static APIService API;

    private AppManager() {
        super();
    }

    public static AppManager getInstance() {
        return INSTANCE;
    }

    @Override
    public void settings() {
        BASE_URL = "https://www.v2ex.com/api/";
        // Create retrofit
        API = onCreateRetrofit().create(APIService.class);
    }

    @Override
    public void route(Fragment fragment, String uri) {

    }
}

TopicList.java

public class TopicList extends TableList<Topic, SubtitleHolder> {

    @Override
    protected void onPrepare() {
        mCall = API.topicList("hot"); // 最热
        mTileId = R.layout.list_item_subtitle; // 可以定义你自己的 layout, 定义每一行的样式,对应的 Holder 也需要换成你自己的
    }

    @Override
    protected void onDisplayItem(Topic item, SubtitleHolder holder, int viewType) {
        holder.title.setText(item.title);
        holder.subtitle.setText("id: " + item.id);
        holder.setImage(holder.icon, "https:" + item.node.avatarNormal);
    }

    @Override
    protected void onOpenItem(Topic item) {
        Snackbar.make(mListView, "Replace with your own action", Snackbar.LENGTH_SHORT).show();
        // 在这里进行点击后的 startActivity 等操作
    }

    @Override
    protected void loadMore(int size, int position) {
        // 我没发现 V2EX API 怎么翻页,所以暂时覆写该方法,屏蔽了该功能,能?page=1 这种格式的可以自动翻页, 形式如 mCall = API.topicList("hot", mPage)
    }
}
  • TableList 就是一行只有一个元素的 Fragment, CollectionList/GridList 用于一行多个, iOS 看这个名字应该很好理解 扩展阅读: RecyclerView
  • 命名规则 模型名+List/模型名+Detail, 绝大多数情况, 只需要扩展 List/Detail 这两种接口,因为 API 返回的数据 不是 List 就是 Detail (以后会提供标准的 Create 和 Update 页面)。另外根据业务需求,也可能根据 DDD 划分一些自己的页面,这些可能服务器端更容易理解
  • V2EX 返回数据是直接的一个列表,如果你的接口返回是包在 data 中的,可以继承genos.ui.fragment.ListFragment写一个自己的 TableList, 然后写一个自己的 ListModel, 覆写 TransformListFromData 方法即可

第四步(2 分钟): 修改必要的类

MainActivity.java

public class MainActivity extends TabBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mFragments.append(R.id.navigation_hot, new TopicList());
        mFragments.append(R.id.navigation_latest, PlaceholderFragment.newInstance(2));
        mFragments.append(R.id.navigation_me, PlaceholderFragment.newInstance(3));
        onNavigationItemSelected(R.id.navigation_hot);
    }
}
  • TabBarActivity 是底部导航,需要侧栏导航,继承genos.ui.activity.DrawerActivity即可
  • TabBarActivity 的默认菜单名是 res/menu 里的 navigation_tab_bar,DrawerActivity 是 navigation_drawer, 创建同名文件,可替换为自己的菜单,你也可以用其他名字,手动在onCreateOptionsMenu中 inflate
  • XXXListActivity 会自动搜寻名为 list_xxx 的菜单和字符串设为菜单和标题,你也可以手动装配
  • Fragment 因为名称会被混淆,所有设置均需要手动

第五步 (1 分钟) 运行

你现在是 Android 专家了