• 学习安卓开发[1]


    一、程序结构

    Android原生应用采用了MVC的架构设计模式,因此可以将一个Android APP中的对象归为Model、View或Controller中的一种。

    具体到某个实际的APP结构中,它一般会由若干个activity、layout文件和自定义类组成,activity是Android SDK中Activity类的实例,负责管理用户与应用界面的交互,应用的功能是通过编写Activity子类来实现的;layout文件则用于定义需要显示的UI对象以及指定它们在屏幕上所处的位置,layout文件的后缀为XML。

    由此可知,layout文件等属于视图对象,此外Android还自带了很多可配置的视图类,在后面逐步了解。控制器则通常是Activity、Fragment或Service的子类。

     

    二、layout文件内容

    layout文件定义了界面显示的UI组件及其布局方式,对于下面这样一个简单界面

    layout文件内容为:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical">
        <TextView
            android:id="@+id/question_text_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="24dp" />
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/true_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/true_button" />
            <Button
                android:id="@+id/false_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/false_button" />
            <Button
                android:id="@+id/cheat_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/cheat_button"/>
            <Button
                android:id="@+id/next_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/next_button"
                android:drawableRight="@drawable/arrow_right"/>
        </LinearLayout>
    </LinearLayout>

    其组成有:

    一个垂直的LinerLayout组件,包含一个TextView组件和一个水平的LinerLayout组件;

    水平的LinerLayout组件中又包含4个Button组件。

    先看一下这里面包含的一些后续会经常用到的属性:

    1. android:layout_width和android:layout_height,可以设置为wrap_content(视图与其父视图大小相同)或match_content(视图会根据其内容自动调整大小)。可以看到作为根节点的LinerLayout也有layout_width和layout_height属性,这是因为Android系统为其提供了容纳整个应用的父视图。

    2.android:orientation,orientation是LinerLayout组件具有的属性,它指定LinerLayout的子组件是水平放置还是水平放置。

    3.android:text,TextView和Button具有text属性,指定组件要显示的文字内容。

    三、字符串资源

    可以看到android:text的值为类似"@string/next_button"这样的形式,这是对字符串资源的应用,字符串资源(string resource)在string.xml中定义。通过把字符串内容放置在字符串资源,然后再间接引用它们,这样可以方便地修改需要显示的内容,更重要的是便于应用的本地化。

    比如@string/next_button在字符串资源中的形式为:

    <string name="next_button">Next</string>

    那么为什么在layout文件中输入“@string/”后,Android会自动提示出“next_button”呢,这要从资源ID说起。非代码形式的内容都属于资源,比如图像文件、音频文件、XML文件等,资源文件都存放在app/res的子目录下,string.xml的路径为app/res/values,layout.xml的路径为app/res/layout,要获取这些xml中定义的资源需要先知道对应的资源ID,所有资源的ID都存放在R.java文件中,将Android Studio的项目视图切换为Project后,可根据路径app/build/generated/source/r/debug/对于项目包名称/R.java找到R文件,在这里我们可以在public static final class string下找到

    public static final int next_button=0x7f0b0025,这便是next_button的资源ID,资源ID都是int型。

    R文件在编译时自动生成,手动修改可能会导致未知错误。修改资源内容后,R文件不会实时刷新,只有在应用安装到模拟器或物理设备时才会重新生成,Android Studio还另外保存有一份用于代码编译的隐藏的R文件。

    四、Activity

    1.组件的引用

    一个页面的Activity与layout的名称有对应关系,比如activity_quiz.xml对应的activity名称为QuizActivity.java。在Activity中使用组件的第一步,也是通过资源ID获取该组件,比如引用一个Button时的代码为:

    private Button mTrueButton;

    ...

    mTrueButton=(Button) findViewById(R.id.true_button);

    拿到组件后,就可以做后续的操作了,比如为Button设置监听器(listener):

    mTrueButton.setOnClickListener(new View.OnClickListener(){

    @Override

    public void onClick(View v){

    }

    });

    或者改变TextView的显示内容:

    mQuestionTextView=(TextView) findViewById(R.id.question_text_view);

    mQuestionTextView.setText(“New Text”);

    2.Activity的生命周期

    在使用Android Studio向导创建一个Activity后,默认会有onCreate方法:

    @Override

    protected void onCreate(Bundle savedinstanceState){

    }

    onCreate属于Activity的生命周期方法,此外还有onStart(), onResume(), onPause(), onStop(), onDestroy()。页面在不同的状态间切换时,这些方法会被Android系统执行

     

    启动APP时,依次执行onCreate, onStart, onResume,直接进入运行态;

    Home键回到主页时,依次执行onPause, onStop,进入停止态;

    点击返回键退出APP时,则会依次执行onPause, onStop和onDestroy,页面被销毁;

    需要注意的是,旋转屏幕时也会依次执行onCreate, onStart, onResume,这是因为发生屏幕旋转时,Android会销毁当前activity,寻找合适的备选资源并重新创建。这一特性对于需要保存页面状态的activity会造成问题,因为重新创建activity会丢失当前页面的操作状态,这是我们不希望发生的。要解决这个问题,可以覆盖系统的onSaveInstanceState(Bundle)方法,在APP转入停止状态时,这个方法在onStop之前由系统调用,我们可以在这个方法中将activity视图状态相关的数据存入Bundle对象中:

        @Override

        public void onSaveInstanceState(Bundle savedInstanceState) {

            super.onSaveInstanceState(savedInstanceState);

            savedInstanceState.putInt(KEY_INDEX, mCurrentIndex);

    }

    然后在每次重新创建activity时尝试读取Bundle中的内容:

      @Override

        protected void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

            if (savedInstanceState != null) {

                mCurrentIndex = savedInstanceState.getInt(KEY_INDEX);

            }

    ....

    }

    五、页面通信

    一般来说一个APP不可能只有一个页面,通过主页面打开子页面时就涉及到了页面间的通信。

    Android使用基于Intent的通信方式,intent对象是component用来与操作系统通信的媒介工具。activity就是一种component对象。Intent是一种多用途通信工具,Intent类有多个构造方法,能满足不同的使用需要。

    1.从父页面启动子页面

    假设父页面为QuizActivity,子页面为CheatActivity,则从父页面启动子页面的方法为:

    ...

    Intent intent = new Intent(QuizActivity.this, CheatActivity.class);

    intent.putExtra(EXTRA_ANSWER_IS_TRUE, answerIsTrue);

    startActivity(intent);

    ...

    使用intent.putExtra方法可以在启动子页面的同时传入需要的值,然后子页面可读取传入值的方法为:

    mAnswerIsTrue = getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE, false);

    2.子页面返回结果给父页面

    在很多场景中都需要子页面返回结果给父页面。有两个方法可以使用:

    public final void setResult(int resultCode)

    public final void setResult(int resultCode, Intent data)

    resultCode的值为预定义常量,有:

    Activity.RESULT_OK,对应确认操作

    Activity.RESULT_CANCELED,对应取消操作

    Activity.RESULT_FIRST_USER,用于自定义结果代码

    使用public final void setResult(int resultCode, Intent data)即可将结果数据通过Intent返回给父页面。

    相应的,在父页面要取得子页面的返回结果,需要覆盖onActivityResult(int, int, Intent方法)

        @Override
    
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    
            if (resultCode != Activity.RESULT_OK) {
    
                return;
    
            }
    
            if (requestCode == REQUEST_CODE_CHEAT) {
    
                if (data == null) {
    
                    return;
    
                }
    
                //TODO
    
            }
    
        }
  • 相关阅读:
    简单的本地注册与登陆的功能
    Android 简单统计文本文件的字符数、单词数、行数、语句数Demo
    个人项目需求与分析——点菜系统App
    强大的健身软件——Keep
    大学生三大痛点
    我推荐的一款实用APP-圣才电子书
    PropertyDescriptor和BeanUtils使用去获得类的get 和 setter访问器
    神奇的 Object.defineProperty
    用cudamat做矩阵运算的GPU加速
    Java并发编程概要
  • 原文地址:https://www.cnblogs.com/zhixin9001/p/9879775.html
Copyright © 2020-2023  润新知