前言
配置完本地的开发环境后,就该从Android系统的四种组件中的活动开始学习了。
正文
活动是一种可以容纳其它组建的容器,也是与用户交互的最基本也是重要的一部分,除非目标项目的对象不是用户,才可以不使用活动。我们通过Android Studio工具来创建一个最基本的活动。
- 创建一个新的Android项目,而不添加任何活动。
- 创建一个新的java类,使其继承AppCompatActivity.
- 重写父类方法的
onCreate()
,该方法将会在活动创建时调用,我们可以在这个方法下对该活动进行初始化的行为
public class FirstActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
- 为该活动创建一个布局
- 在活动中加载这个布局,使用
setContentView()
方法,传入R.layout.first_layout
即可加载该布局
public class FirstActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置使用first_layout.xml文件定义的界面布局
setContentView(R.layout.first_layout);
}
}
- 最后在AndroidManifest.xml,即该项目的清单文件中为该活动注册
在<application>
标签下新加<Activity>
标签,即加入<activity android:name=".FirstActivity"/>
然后在该标签下加入:
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<!--指定该activity是程序的入口-->
<category android:name="android.intent.category.LAUNCHER"/>
<!--当加载该应用的时候运行该Activity-->
</intent-filter>
- 之后就能够运行该应用,选择合适的选择合适的AVD即可运行该应用
- 然后我们来了解一下Toast以及Menu
首先是Toast:
顺延该书中所讲,我们可以在活动中使用Toast
来推送通知达到提醒用户的目的。
首先在活动中绑定button,并为该组件插入Toast代码;
详情如下述所示:
// 事先在布局文件中加入名为button的组件
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(FirstActivity.this, R.string.button_onclick, Toast.LENGTH_SHORT).show();
// 同样可以使用下面的
// Toast.makeText(FirstActivity.this, "You clicked the Button", Toast.LENGTH_SHORT).show();
}
});
当用户点击名为button的按钮,就会调用onClick()方法,所以我们重写onClick()方法,使用Toast,其中makeText()方法需要传入三个参数,有两种重载的方法:
Toast makeText(Context context, int resId, int duration)
Toast makeText(Context context, CharSequence text, int duration)
第一个参数均是所在活动的上下文。
第二个参数一是传入在res/values/strings资源文件的文本标签名称:
<string name="button_onclick">You clicked the Button</string>
,之后传入R.string.标签名称
即可。
这也是为了方便统一对应用中的文本进行管理,提高应用翻译时的效率,二是传入CharSequence变量,我们可以直接传入String变量。
第三个参数我们使用Toast.LENGTH_SHORT
和Toast.LENGTH_LONG
来确定显示时长。
结果如下图所示:
接下来我们来看看Menu:
当我们使用的Activity继承自AppCompatActivity,在运行应用的时候,会看到顶部会出现一个标题栏,这个组件是在res/values/styles.xml中可以看到,我们可以在标题栏中加入菜单选项:
首先,创建menu.xml,为menu准备菜单布局,如下所示:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/add_item"
android:title="add"/>
<item
android:id="remove_item"
android:title="remove"/>
</menu>
之后为FirstActivity的标题栏传入该菜单布局,在onCreateOptionMenu()
中键入下述代码:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.first_menu, menu);
return true;
}
现在如果我们重新运行该应用,应该可以看到右上角多出来的选单,之后我们可以为每一个菜单项目添加监听,在它们被按下时可以执行其他的命令,这里我们可以使用Toast,在FirstActivity下重写onOptionItemSelected()
方法,如下述所示:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.add_item:
Toast.makeText(this, "You clicked Add", Toast.LENGTH_SHORT).show();
break;
case R.id.remove_item:
Toast.makeText(this, "You clicked Remove", Toast.LENGTH_SHORT).show();
break;
default:
}
return true;
}
这样我们就可以在点击菜单项目的时候相应地做出响应。
我们如果需要修改应用的标题栏以及配色,可以打开res/values/styles.xml:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
在这里我们能够看该应用默认的一些颜色,以及其他的属性,如果我们不需要自带的ActionBar,或者是想要自己美化原有的ActionBar,可以将parent属性中的内容替换为Theme.AppCompat.Light.NoActionBar
,这样默认自带的ActionBar就不会出现了,在API21之后我们使用ToolBar接替ActionBar的地位,
- 最后就是如何结束一个Activity:使用
finish()
方法即可。
该课总结及部分知识点
(课后瞎翻系列,对于一个刚学的人来说,每一篇出现的新鲜词语总是让人忍不住想去翻翻)
关键字:活动,AppCompatActivity,onCreate(),setContentView(),R,AndroidManifest
- 活动:
活动是我们编写应用,与用户交互的重要组件,当我们想在项目中加入一个活动时,需要在清单文件(Manifest.xml)中进行注册
- AppCompatActivity, onCreate():
AppCompatActivity官方定义如下:
Base class for activities that use the support library action bar features.
我们可以得知,该类可以适配低版本并使用后来出现的新特性,例如:ActionBar,MaterialDesign等
You can add an ActionBar to your activity when running on API level 7 or higher by extending this class for your activity and setting the activity theme to Theme.AppCompat
or a similar theme.
onCreate()定义及相关内容:
该方法是继承自AppCompatActivity类,在该类中的实现代码:
protected void onCreate(@Nullable Bundle savedInstanceState) {
final AppCompatDelegate delegate = getDelegate();
delegate.installViewFactory();
delegate.onCreate(savedInstanceState);
if (delegate.applyDayNight() && mThemeId != 0) {
// If DayNight has been applied, we need to re-apply the theme for
// the changes to take effect. On API 23+, we should bypass
// setTheme(), which will no-op if the theme ID is identical to the
// current theme ID.
if (Build.VERSION.SDK_INT >= 23) {
onApplyThemeResource(getTheme(), mThemeId, false);
} else {
setTheme(mThemeId);
}
}
super.onCreate(savedInstanceState);
}
public AppCompatDelegate getDelegate() {
if (mDelegate == null) {
mDelegate = AppCompatDelegate.create(this, this);
}
return mDelegate;
}
代理类AppCompatDelegate中:
public static AppCompatDelegate create(Activity activity, AppCompatCallback callback) {
return create(activity, activity.getWindow(), callback);
}
private static AppCompatDelegate create(Context context, Window window,
AppCompatCallback callback) {
if (Build.VERSION.SDK_INT >= 24) {
return new AppCompatDelegateImplN(context, window, callback);
} else if (Build.VERSION.SDK_INT >= 23) {
return new AppCompatDelegateImplV23(context, window, callback);
} else if (Build.VERSION.SDK_INT >= 14) {
return new AppCompatDelegateImplV14(context, window, callback);
} else if (Build.VERSION.SDK_INT >= 11) {
return new AppCompatDelegateImplV11(context, window, callback);
} else {
return new AppCompatDelegateImplV9(context, window, callback);
}
}
获取该AppCompatActivity对象中的mDelegate,如果不存在,则创建一个,可以看出mDelegate是根据项目实际SDK版本来创建的,之后为该类应用主题,如果sdk版本大于23,则不调用setTheme(),之后调用父类FragmentActivity的方法onCreate(),在后面的地方在看FragmentActivity相关的内容。
上述代码使用到AppCompatDelegate.java中的方法
再往里看我就有些看不懂了,留着给以后的自己看吧,现在先把这些东西整理到一起。
- setContentView():
在setContentView()
方法中,同样使用了AppCompatActivity下的mDelegate,用以加载layout资源文件,如下述代码所示:
public void setContentView(@LayoutRes int layoutResID) {
getDelegate().setContentView(layoutResID);
}
- R.java:
该类是由aapt(Android Asset Packaging Tool, 该工具可以查看,创建, 更新ZIP格式的文档附件(zip, jar, apk))工具自动生成的资源索引,通过该类我们可以轻易的在代码中访问到我们之前创建的layout资源或者其他的/res下的文件,每当我们创建一个新的资源文件或者在资源文件中做出修改,都会被该工具检测并作出相应的调整,最终反映到R中,但是整个过程操作过程不需要我们关心,很是方便。
参考文章:
Material适配详解
setContentView()究竟做了什么
源码级分析AppCompatActivity适配过程
带你深度了解AppCompatActivity和Toolbar(Android21)
《疯狂Android讲义》第一版 P27 1.5.2
上一节内容:第一行代码学习笔记 ——准备工作(一)
下一节内容:第一行代码学习笔记——活动之间的交互,Intent(三)