界面是布局和微件的层次结构形式构建而成。布局是 ViewGroup 对象,即控制其子视图在屏幕上的放置方式的容器。微件是 View 对象,即按钮和文本框等界面组件。
应用组件是 Android 应用的基本构建块。每个组件都是一个入口点,系统或用户可通过该入口点进入您的应用。有些组件会依赖于其他组件。 共有四种不同的应用组件类型: • Activity • 服务 • 广播接收器 • 内容提供程序
在 Android 系统启动应用组件之前,系统必须通过读取应用的清单文件 (AndroidManifest.xml) 确认组件存在。您的应用必须在此文件中声明其所有组件,该文件必须位于应用项目目录的根目录中。
应用资源是指代码使用的附加文件和静态内容,例如位图、布局定义、界面字符串、动画说明等。应将各类资源放入项目 res/ 目录的特定子目录中。
布局可定义应用中的界面结构(例如 Activity 的界面结构)。布局中的所有元素均使用 View 和 ViewGroup 对象的层次结构进行构建。View 通常绘制用户可查看并进行交互的内容。然而,ViewGroup 是不可见容器,用于定义 View 和其他 ViewGroup 对象的布局结构,如图 所示。 View 对象通常称为“微件”,可以是众多子类之一,例如 Button 或 TextView。ViewGroup 对象通常称为“布局”,可以是提供其他布局结构的众多类型之一,例如 LinearLayout 或 ConstraintLayout。
Activity类是 Android 应用的关键组件,而 Activity 的启动和组合方式则是该平台应用模型的基本组成部分。应用中的一个 Activity 会被指定为主 Activity,这是用户启动应用时出现的第一个屏幕。然后,每个 Activity 可以启动另一个 Activity,以执行不同的操作。用中的各个 Activity 协同工作形成统一的用户体验,但每个 Activity 与其他 Activity 之间只存在松散的关联,应用内不同 Activity 之间的依赖关系通常很小。 一个 Activity 在其生命周期中会经历多种状态。
任务是用户在执行某项工作时与之互动的一系列 Activity 的集合。
Fragment 表示 FragmentActivity 中的行为或界面的一部分。您可以在一个 Activity 中组合多个片段,从而构建多窗格界面,并在多个 Activity 中重复使用某个片段。您可以将片段视为 Activity 的模块化组成部分,它具有自己的生命周期,能接收自己的输入事件,并且您可以在 Activity 运行时添加或移除片段(这有点像可以在不同 Activity 中重复使用的“子 Activity”)。
片段所在 Activity 的生命周期会直接影响片段的生命周期,其表现为,Activity 的每次生命周期回调都会引发每个片段的类似回调。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment android:name="com.example.android.fragments.HeadlinesFragment"
android:id="@+id/headlines_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.example.android.fragments.ArticleFragment"
android:id="@+id/article_fragment"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
getParentFragmentManager().setFragmentResultListener("key", this, new FragmentResultListener() {
@Override
public void onFragmentResult(@NonNull String key, @NonNull Bundle bundle) {
// We use a String here, but any type that can be put in a Bundle is supported
String result = bundle.getString("bundleKey");
// Do something with the result...
}
});
另一个framgment设置结果
Bundle result = new Bundle();
result.putString("bundleKey", "result");
getParentFragmentManager().setFragmentResult("requestKey", result);
getChildFragmentManager().setFragmentResultListener("key", this, new FragmentResultListener() {
@Override
public void onFragmentResult(@NonNull String key, @NonNull Bundle bundle) {
String result = bundle.getString("bundleKey");
// Do something with the result..
}
});
View listView = getActivity().findViewById(R.id.list);
Activity 也可使用 findFragmentById() 或 findFragmentByTag(),通过从 FragmentManager 获取对 Fragment 的引用来调用片段中的方法。
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null){
// 初始化viewHolder
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.item_list, null);
convertView.setTag(viewHolder);
}else{
// 复用旧对象
viewHolder = (ViewHolder)convertView.getTag();
}
// 设置textview内容
viewHolder.textView.setText(contents.get(position));
return convertView;
}
void getData2(){
final TextView textView = (TextView) findViewById(R.id.text);
// ...
// 初始化 RequestQueue.
RequestQueue queue2 = Volley.newRequestQueue(this);
// 发起一个StringRequest 请求指定网址
StringRequest stringRequest = new StringRequest(Request.Method.GET, "https://www.gcu.edu.cn/main.htm",
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// 在textview控件上显示最多500个字符的内容
textView.setText("Response is: "+ response.substring(0,500));
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// 有错误是,显示: 请求数据报错!
textView.setText("请求数据报错!");
}
});
// 放置到调度队列.
queue2.add(stringRequest);
}
public class MyModel extends ViewModel {
private MutableLiveData<String> msg;
private MutableLiveData<Integer> count;
private MutableLiveData<List<ImageInfo>> data;
public MutableLiveData<Integer> getCount() {
if (count == null) {
count = new MutableLiveData<>();
}
return count;
}
public MutableLiveData<String> getMsg() {
if (msg == null) {
msg = new MutableLiveData<>();
}
return msg;
}
public MutableLiveData<List<ImageInfo>> getData() {
if(data == null){
data = new MutableLiveData<>();
}
return data;
}
}
public class MainActivity extends AppCompatActivity {
public static final String INFOKEY = "com.gcu.simple.infokey";
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
}
public void openMessage(View view){
Intent intent = new Intent(this, InfoActivity.class);
String msg = textView.getText().toString();
intent.putExtra(INFOKEY, msg);
startActivity(intent);
}
public void listBtn(View view){
Intent intent = new Intent(this, ListActivity.class);
startActivity(intent);
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="1dp"
android:layout_marginEnd="1dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0">
<Button
android:id="@+id/btn_msg"
android:text="查看消息"
android:onClick="openMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
/>
<TextView
android:id="@+id/textView"
android:text="什么都没有"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
/>
<Button
android:id="@+id/btn_data"
android:text="数据更新及列表"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="listBtn"
/>
<Button
android:id="@+id/btn_style"
style="@style/button_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="使用样式" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
</style>
<style name="button_text" parent="TextAppearance.AppCompat.Widget.ActionBar.Title">
<item name="android:textSize">20sp</item>
<item name="android:textColor">#FF0000</item>
<item name="android:textStyle">italic</item>
</style>
<style name="button_text.mytextstyle" >
<item name="android:textSize">30sp</item>
<item name="android:textStyle">bold</item>
</style>
</resources>