好的,我们来创建一个简单的 Android 应用,它可以作为面试知识点的展示或小测验工具。这个应用将包含一个 Activity,展示几个常见的 Android 面试问题及其答案。用户可以点击问题来切换显示或隐藏答案。

功能说明

  1. 主界面 (activity_main.xml): 包含一个 ScrollView 用于滚动,内部是一个垂直的 LinearLayout,用于放置多个“问题-答案”卡片。
  2. 问题卡片 (QuestionCard.java): 一个自定义的 View (继承自 LinearLayout),包含一个显示问题的 TextView 和一个默认隐藏的显示答案的 TextView。点击卡片可以切换答案的可见性。
  3. MainActivity.java: 负责初始化界面,创建并添加多个 QuestionCard 到主布局中。
  4. 数据 (InterviewQuestions.java): 一个简单的数据类,用于存储问题和答案列表。

代码实现

<!-- 文件: app/src/main/res/layout/activity_main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#f5f5f5"tools:context=".MainActivity"><LinearLayoutandroid:id="@+id/container_layout"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"android:padding="8dp"><!-- QuestionCards will be added here programmatically --></LinearLayout>
</ScrollView>
// 文件: app/src/main/java/com/example/androidinterview/QuestionCard.java
package com.example.androidinterview;import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;import androidx.annotation.Nullable;public class QuestionCard extends LinearLayout {private TextView answerTextView;private boolean isAnswerVisible = false;public QuestionCard(Context context, String question, String answer) {super(context);init(context, question, answer);}public QuestionCard(Context context, @Nullable AttributeSet attrs) {super(context, attrs);// This constructor is required for inflation from XML, but we'll use the other one.init(context, "Default Question", "Default Answer");}private void init(Context context, String question, String answer) {setOrientation(LinearLayout.VERTICAL);// 设置卡片样式setPadding(16, 16, 16, 16);setBackgroundResource(R.drawable.card_background); // 需要预先创建 card_background.xml drawablesetLayoutTransition(new android.animation.LayoutTransition()); // 添加默认布局动画// 问题 TextViewTextView questionTextView = new TextView(context);questionTextView.setText(question);questionTextView.setTextSize(18);questionTextView.setTextColor(Color.BLACK);questionTextView.setPadding(0, 0, 0, 8);// 设置粗体questionTextView.setElegantTextHeight(true);questionTextView.setTypeface(questionTextView.getTypeface(), android.graphics.Typeface.BOLD);// 答案 TextView (初始隐藏)answerTextView = new TextView(context);answerTextView.setText(answer);answerTextView.setTextSize(16);answerTextView.setTextColor(Color.GRAY);answerTextView.setPadding(0, 8, 0, 0);answerTextView.setVisibility(GONE); // 初始隐藏// 添加视图到卡片addView(questionTextView);addView(answerTextView);// 设置点击事件监听器来切换答案可见性setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {toggleAnswerVisibility();}});}private void toggleAnswerVisibility() {isAnswerVisible = !isAnswerVisible;answerTextView.setVisibility(isAnswerVisible ? VISIBLE : GONE);}
}
// 文件: app/src/main/java/com/example/androidinterview/InterviewQuestions.java
package com.example.androidinterview;import java.util.ArrayList;
import java.util.List;public class InterviewQuestions {public static class QuestionAnswer {private final String question;private final String answer;public QuestionAnswer(String question, String answer) {this.question = question;this.answer = answer;}public String getQuestion() {return question;}public String getAnswer() {return answer;}}public static List<QuestionAnswer> getQuestions() {List<QuestionAnswer> list = new ArrayList<>();list.add(new QuestionAnswer("Q1: 请解释 Android 四大组件及其作用?","A: Android 四大组件是 Activity、Service、BroadcastReceiver 和 ContentProvider。\n" +"- Activity: 代表一个拥有用户界面的单屏,是与用户交互的入口。\n" +"- Service: 在后台执行长时间运行的操作,不提供用户界面。\n" +"- BroadcastReceiver: 用于响应系统范围内的广播消息(如电池电量低、网络状态改变)。\n" +"- ContentProvider: 管理共享数据集,允许其他应用程序查询或修改数据。"));list.add(new QuestionAnswer("Q2: Activity 的生命周期有哪些重要方法?","A: 主要生命周期方法包括:\n" +"onCreate(): Activity 被创建时调用,进行初始化。\n" +"onStart(): Activity 变为可见但未获得焦点。\n" +"onResume(): Activity 开始与用户交互,获得焦点。\n" +"onPause(): Activity 失去焦点但仍可见,应在此保存关键数据。\n" +"onStop(): Activity 完全不可见。\n" +"onDestroy(): Activity 被销毁前调用。\n" +"onRestart(): Activity 从停止状态重新启动时调用。"));list.add(new QuestionAnswer("Q3: 请说明 Fragment 的生命周期及其与 Activity 生命周期的关系?","A: Fragment 生命周期与 Activity 生命周期紧密相关。Fragment 的主要方法包括:\n" +"onAttach(): Fragment 与 Activity 关联。\n" +"onCreate(): Fragment 被创建。\n" +"onCreateView(): 创建 Fragment 的视图。\n" +"onActivityCreated(): Activity 的 onCreate() 执行完毕。\n" +"onStart(), onResume(), onPause(), onStop(), onDestroyView(), onDestroy(), onDetach() 等方法与 Activity 对应。\n" +"关系:Fragment 的生命周期方法会在宿主 Activity 相应的生命周期方法中被调用。例如,Activity 的 onStart() 调用后,其内部所有可见 Fragment 的 onStart() 也会被调用。"));list.add(new QuestionAnswer("Q4: Intent 是什么?有什么用途?","A: Intent 是一个消息对象,用于请求另一个应用程序组件(如 Activity、Service)的操作。\n" +"用途:\n" +"- 启动 Activity (startActivity())\n" +"- 启动 Service (startService() / bindService())\n" +"- 发送广播 (sendBroadcast())\n" +"Intent 分为显式 Intent(指定目标组件)和隐式 Intent(通过 Action、Category 等让系统查找合适的组件)。"));list.add(new QuestionAnswer("Q5: 请解释 View 的绘制流程 (measure, layout, draw)?","A: View 的绘制分为三个步骤:\n" +"1. Measure (测量): 系统调用 measure() 方法,从根视图开始,自上而下遍历整个 View 树,确定每个 View 的大小。每个 View 根据其父容器的 MeasureSpec 和自身的 LayoutParams 计算出自己的尺寸。\n" +"2. Layout (布局): 系统调用 layout() 方法,确定每个 View 在其父容器中的位置和大小(left, top, right, bottom)。\n" +"3. Draw (绘制): 系统调用 draw() 方法,将 View 绘制到屏幕上。这个过程通常包括绘制背景、内容、子视图和前景/滚动条等。"));return list;}
}
<!-- 文件: app/src/main/res/drawable/card_background.xml -->
<?xml version="1.0" encoding="utf-8"?>
<!-- 简单的卡片背景,带圆角和阴影效果 -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><solid android:color="@android:color/white" /><corners android:radius="8dp" />
</shape>
<!-- 文件: app/src/main/res/values/colors.xml -->
<?xml version="1.0" encoding="utf-8"?>
<resources><color name="colorPrimary">#6200EE</color><color name="colorPrimaryDark">#3700B3</color><color name="colorAccent">#03DAC5</color>
</resources>
<!-- 文件: app/src/main/res/values/strings.xml -->
<resources><string name="app_name">Android 面试精选</string>
</resources>
<!-- 文件: app/src/main/res/values/styles.xml 或 themes.xml (取决于项目模板) -->
<resources xmlns:tools="http://schemas.android.com/tools"><!-- Base application theme. --><style name="Theme.AndroidInterview" parent="Theme.MaterialComponents.DayNight.DarkActionBar"><!-- Customize your theme here. --><item name="colorPrimary">@color/colorPrimary</item><item name="colorPrimaryDark">@color/colorPrimaryDark</item><item name="colorAccent">@color/colorAccent</item></style>
</resources>
<!-- 文件: app/src/main/AndroidManifest.xml -->
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.AndroidInterview"tools:targetApi="31"><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

说明

  1. MainActivity: 入口点,负责从 InterviewQuestions 类获取数据,并为每个问题答案对创建一个 QuestionCard 实例,然后将其添加到 activity_main.xml 中定义的 LinearLayout 容器里。
  2. QuestionCard: 这是一个自定义的 ViewGroup。它接收问题和答案字符串,在其构造函数中动态创建 TextView 来显示它们。答案 TextView 初始是 GONE 的。通过给整个卡片设置 OnClickListener,实现了点击卡片切换答案可见性的功能。setLayoutTransition 添加了一个简单的动画效果,使显示/隐藏更平滑。
  3. InterviewQuestions: 一个简单的数据持有类,包含一个内部类 QuestionAnswer 来封装单个问题和答案。getQuestions() 方法返回一个预定义的 QuestionAnswer 列表。
  4. card_background.xml: 一个 Shape Drawable,为 QuestionCard 提供一个白色的背景、圆角,使其看起来像一张卡片。
  5. 布局和样式: activity_main.xml 使用 ScrollView 包裹 LinearLayout,确保内容可以滚动。styles.xml 定义了基本的应用主题。

这个应用结构清晰,易于扩展。你可以通过修改 InterviewQuestions.getQuestions() 方法轻松添加更多面试题。