我也是刚入门安卓开发,所以浅浅的了解android项目的目录结构
1. app/
这是项目的主要模块所在的目录,包含应用的源码和资源。它是大部分开发者会频繁使用的部分。app/
目录下通常有以下子目录:
manifests/
AndroidManifest.xml
:项目的核心配置文件。在这里定义应用的包名、应用的组件(Activity、Service、BroadcastReceiver 等)、权限(如网络权限)、应用主题等。它可以看作应用的"入口点"。
java/
-
com.example.myapp/
:这里是项目的主 Java 或 Kotlin 源代码目录。典型的 Android 项目结构如下:MainActivity.java
或MainActivity.kt
:应用的主界面 Activity。- 其他业务逻辑类,如 ViewModel、Adapter 等,按照模块化和功能分包管理。
java/
目录用于保存:- Activity、Fragment、Service、BroadcastReceiver 等 Android 组件。
- 数据模型、工具类、适配器 等非 Android 组件的业务逻辑代码。
res/
该目录存放应用的所有静态资源,如布局文件、图片、字符串、颜色等,按照不同的类型进行划分。
layout/
:存放 XML 格式的布局文件,如activity_main.xml
,用于定义应用界面。drawable/
:存放图片资源和 XML 绘图文件(如 shape、selector 等)。mipmap/
:存放不同分辨率的启动图标(即 app 图标)。values/
:存放 XML 文件,包括字符串资源(strings.xml
)、颜色定义(colors.xml
)、样式(styles.xml
)、尺寸定义(dimens.xml
)等。menu/
:存放应用菜单的 XML 文件。
assets/
这个目录下可以放置应用需要的原始文件,比如字体、音频文件、HTML 文件等,应用可以通过 AssetManager
访问这些资源。
gradle/
-
build.gradle
:项目构建配置文件,分为项目级和模块级两个文件。项目级的build.gradle
位于根目录下,而模块级的位于app/
目录下,通常用于配置项目依赖、编译 SDK 版本、打包方式等。- 项目级
build.gradle
:配置全局的依赖、插件和 Gradle 版本。 - 模块级
build.gradle
:配置应用的依赖库、编译选项、ProGuard、签名等。
- 项目级
2. 项目根目录
gradle/
该目录存放的是项目构建工具 Gradle 的一些配置文件,比如 gradle-wrapper.properties
,用于配置 Gradle 的版本和相关参数。
.idea/
这是 Android Studio 生成的项目配置文件目录,存储了一些 IDE 的配置信息,比如代码风格、代码导航等。这个目录一般不会直接修改。
build/
这是构建目录,用于存放项目编译后的输出文件,如 .apk
文件、编译中间文件等。这个目录不需要手动管理,通常被自动生成。
.gradle/
这个目录存放了 Gradle 缓存文件和配置项,类似于 build/
目录,也是自动生成的,无需手动修改。
local.properties
该文件用于本地配置 Android SDK 的路径。通常不会共享到版本控制系统中,因为它是机器相关的配置。
settings.gradle
用于配置项目包含的模块,主要定义项目包含哪些子模块,比如 app
模块。
gradlew
& gradlew.bat
这两个文件是 Gradle 的脚本启动器,用于在不同操作系统下执行 Gradle 命令。gradlew
用于 macOS/Linux,gradlew.bat
用于 Windows。
根据value中配置arrays.xml可以拿到数据
第一种也是最简单的一种,直接在value.xml配置文件中添加数据即可实现。
在你的layout.xml中加入ListView,再在ListView中加android:entries="@array/subjects"
即可实现
simple_expandable_list_item_1 内置的adapter也可以把数据放入其中
第二种相对第一种多了一步adapter的步骤。adapter是一个内置接口,能用来做数据绑定。
java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ListView listView = findViewById(R.id.list);
String[] data = { "计算机","高等数学","高等物理","数据结构" };
ArrayAdapter<String> adapter = new ArrayAdapter<String>
(this, android.R.layout.simple_expandable_list_item_1,data);
listView.setAdapter(adapter);
}
}
先找到ListView的id,创建一个ArrayAdapter对象,把数据传入,去调用已经内置好的接口setAdapter,这样也能轻松得到如上图片。
自定义的adapter可以多样化的制定想要的效果
第三种就相对前两种难了一些,它更能多元化满足你的需求,以下我写了一个成绩单的小demo。
大概的效果是这样的
两个布局文件
layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<TextView
android:id="@+id/txt_name"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:gravity="start"
android:textColor="#0F0000"
android:textSize="25sp"/>
<TextView
android:id="@+id/txt_grade"
android:layout_width="90dp"
android:layout_height="35dp"
android:gravity="start"
android:textColor="#FF0000"
android:textSize="25sp" />
</LinearLayout>
这一个是控制每一行两个name和grade的样式的
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:orientation="vertical"
android:background="#F5F5F5"
tools:context=".MainActivity">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="成绩单"
android:textSize="24sp"
android:textColor="#333"
android:layout_gravity="center_horizontal"
android:paddingBottom="16dp" />
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@android:color/darker_gray"
android:dividerHeight="2dp"
android:background="#FFFFFF"
android:padding="8dp"
android:layout_marginTop="10dp"
android:elevation="4dp" />
</LinearLayout>
这个是控制总样式的。
对于实现自定义的apapter如下代码:
MainActivty.java
package com.example.adapterdemo;
import android.os.Bundle;
import android.widget.ListView;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.list);
CustomerAdapter adapter = new CustomerAdapter(this,getDate());
listView.setAdapter(adapter);
}
private List<Student> getDate(){
List<Student> stuList = new ArrayList<Student>();//构造测试数据
stuList.add(new Student("姓名","分数"));
stuList.add(new Student("李华", "100"));
stuList.add(new Student("王强", "98"));
stuList.add(new Student("张伟", "95"));
stuList.add(new Student("刘洋", "97"));
stuList.add(new Student("陈磊", "96"));
stuList.add(new Student("杨帆", "92"));
stuList.add(new Student("赵敏", "99"));
stuList.add(new Student("黄杰", "94"));
stuList.add(new Student("周涛", "91"));
stuList.add(new Student("吴峰", "93"));
return stuList;
}
}
入口类
Student.java
package com.example.adapterdemo;
public class Student {
private String name; // 姓名
private String grade; // 年级
// 构造函数
public Student(String name, String grade) {
this.name = name; // 给 name 字段赋值
this.grade = grade; // 给 grade 字段赋值
}
// 获取姓名
public String getName() {
return name;
}
// 获取年级
public String getGrade() {
return grade;
}
}
学生类
CustomerAdapter.java
package com.example.adapterdemo;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class CustomerAdapter extends BaseAdapter {
private List<Student> mDate = new ArrayList<Student>();
private LayoutInflater flater;
public CustomerAdapter(Context context, List<Student> list){
mDate.addAll(list);
flater = LayoutInflater.from(context);
}
@Override
public int getCount() {
if (null != mDate){
return mDate.size();
}
return 0;
}
@Override
public Object getItem(int i) {
if (null != mDate && i < mDate.size()){
return mDate.get(i);
}
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (null == view){
view = flater.inflate(R.layout.layout,null);//为每一个子项加载布局
}
//获取子item布局文件中的控件
TextView txtName = (TextView) view.findViewById(R.id.txt_name);
TextView txtGrade = (TextView) view.findViewById(R.id.txt_grade);
Student stuInfo = (Student) getItem(i);
if (null != stuInfo){
txtName.setText(stuInfo.getName());
txtGrade.setText(stuInfo.getGrade());
}
return view;
}
}
继承BaseAdapter,自定义的Adapter,可以更好的满足需求。
总结
arrays.xml
:简单、静态的场景,快速绑定数据,适合固定内容。simple_expandable_list_item_1
:快速实现列表功能,适合简单列表展示,开发成本低。- 自定义
Adapter
:复杂布局和逻辑需求,高度定制化,适合需要灵活展示内容的场景。
根据实际需求选择不同的方式,可以有效提升开发效率和应用的用户体验。