App程序开发总结

1、Android 布局

1.1、线性布局(LinearLayout)

特点

  1. 控件在水平或垂直方向上依次排列。
  2. 可以通过设置权重(layout_weight)来控制控件在布局中所占的比例,实现灵活的界面设计。
  3. 易于理解和使用,是Android开发中最基础的布局方式之一。

适用场景

  • 当需要在一行或一列中整齐地排列控件时,如菜单项、按钮组等。
  • 当需要按比例分割空间给不同的控件时,如制作一个分割成多个区域的界面。

实际应用与示例代码

例如,创建一个垂直方向的线性布局,其中包含两个按钮,第一个按钮占据2/3的空间,第二个按钮占据1/3的空间。

<LinearLayout  
    xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical">  
  
    <Button  
        android:layout_width="match_parent"  
        android:layout_height="0dp"  
        android:layout_weight="2"  
        android:text="Button 1" />  
  
    <Button  
        android:layout_width="match_parent"  
        android:layout_height="0dp"  
        android:layout_weight="1"  
        android:text="Button 2" />  
  
</LinearLayout>

1.2、约束布局(ConstraintLayout)

特点

  1. 提供了更灵活的布局方式,允许控件之间建立水平和垂直方向的约束关系。
  2. 可以通过约束链(Chains)来统一管理一组相关联的控件,实现复杂的布局设计。
  3. 减少了布局嵌套,提高了布局性能。

适用场景

  • 当界面设计复杂,需要灵活调整控件位置和关系时。
  • 当需要优化布局性能,减少布局嵌套层级时。

实际应用与示例代码

例如,创建一个约束布局,其中包含两个文本视图(TextView),它们水平排列且等宽,同时底部对齐。

<androidx.constraintlayout.widget.ConstraintLayout  
    xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:app="http://schemas.android.com/apk/res-auto"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent">  
  
    <TextView  
        android:id="@+id/textView1"  
        android:layout_width="0dp"  
        android:layout_height="wrap_content"  
        android:text="Text 1"  
        app:layout_constraintBottom_toBottomOf="parent"  
        app:layout_constraintEnd_toStartOf="@id/textView2"  
        app:layout_constraintHorizontal_chainStyle="spread"  
        app:layout_constraintStart_toStartOf="parent"  
        app:layout_constraintWidth_percent="0.5" />  
  
    <TextView  
        android:id="@+id/textView2"  
        android:layout_width="0dp"  
        android:layout_height="wrap_content"  
        android:text="Text 2"  
        app:layout_constraintBottom_toBottomOf="@id/textView1"  
        app:layout_constraintEnd_toEndOf="parent"  
        app:layout_constraintStart_toEndOf="@id/textView1"  
        app:layout_constraintWidth_percent="0.5" />  
  
</androidx.constraintlayout.widget.ConstraintLayout>

在这个例子中,我们使用了layout_constraintWidth_percent来设置两个文本视图的宽度各占父布局的50%,同时使用约束链(通过app:layout_constraintHorizontal_chainStyle="spread"定义)来确保它们水平等距分布。底部对齐是通过将两个文本视图的layout_constraintBottom_toBottomOf属性设置为相同值来实现的。

1.3、表格布局(TableLayout)

特点:

  • 允许将控件以表格的形式进行排列,具有行和列的概念。
  • 可以通过设置行列的属性来调整控件的布局,如合并单元格、设置列宽等。
  • 适用于需要整齐划一展示信息的界面设计。

适用场景:

  • 当需要以表格形式展示数据时,如成绩单、时间表等。
  • 当需要制作类似表单的输入界面时。

实际应用与示例代码:

例如,创建一个两行两列的表格布局,每个单元格中包含一个文本视图。

<TableLayout  
    xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent">  
  
    <TableRow>  
        <TextView  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content"  
            android:text="Cell 1" />  
          
        <TextView  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content"  
            android:text="Cell 2" />  
    </TableRow>  
  
    <TableRow>  
        <TextView  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content"  
            android:text="Cell 3" />  
          
        <TextView  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content"  
            android:text="Cell 4" />  
    </TableRow>  
  
</TableLayout>

1.4、帧布局(FrameLayout)

特点:

  • 控件会堆叠在一起,后添加的控件会覆盖在先前添加的控件之上。
  • 布局简单,主要用于容纳单一控件或作为其他布局的容器。
  • 通常用于实现特定的视觉效果,如层叠视图。

适用场景:

  • 当需要在一个区域内堆叠多个视图时,如实现卡片式UI效果。
  • 当作为其他复杂布局的容器时,提供一个简单的层叠环境。

实际应用与示例代码:

例如,创建一个帧布局,其中包含两个文本视图,第二个文本视图会覆盖在第一个文本视图之上。

<FrameLayout  
    xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent">  
  
    <TextView  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:text="Background Text"  
        android:textSize="24sp" />  
  
    <TextView  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:text="Foreground Text"  
        android:textSize="24sp"  
        android:textColor="#FF0000"  
        android:layout_gravity="center" />  
  
</FrameLayout>

1.5、相对布局(RelativeLayout)

特点:

  • 控件的位置可以根据其他控件或父容器的边缘来确定。
  • 提供了灵活的定位方式,可以方便地实现复杂的布局效果。
  • 但过度使用可能导致布局性能下降,因为每次布局测量和布局过程都需要进行多次计算。

适用场景:

  • 当需要根据其他控件的位置来定位控件时,如一个按钮位于另一个文本的右侧。
  • 当布局相对简单,且性能不是主要考虑因素时。

实际应用与示例代码:

例如,创建一个相对布局,其中包含一个文本视图和一个位于其右侧的按钮。

<RelativeLayout  
    xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent">  
  
    <TextView  
        android:id="@+id/textView"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:text="Click the button"  
        android:layout_alignParentStart="true"  
        android:layout_centerVertical="true" />  
  
    <Button  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:text="Click Me"  
        android:layout_toEndOf="@id/textView"  
        android:layout_centerVertical="true" />  
  
</RelativeLayout>

2、Android 常用控件介绍

2.1、组件介绍

TextView

特点:用于显示文本内容,可以设置文本颜色、大小、样式等属性。

适用场景:展示静态文本信息,如标题、说明文字等。

EditText

特点:允许用户输入和编辑文本,可以配置为单行或多行输入,支持文本格式化和输入类型限制。

适用场景:需要用户输入信息的场景,如搜索框、表单填写等。

Button

特点:可点击的按钮,用于触发某个动作或事件。

适用场景:用户交互的重要元素,如提交表单、跳转页面等。

RadioButton

特点:单选按钮,允许用户在一组选项中选择一个。

适用场景:需要用户从多个选项中选择一个的场景,如性别选择、支付方式选择等。

CheckBox

特点:复选框,允许用户选择多个选项。

适用场景:需要用户选择多个选项的场景,如兴趣爱好选择、服务条款同意等。

ImageView

特点:用于显示图片,支持多种图片格式,可以设置图片的缩放类型、透明度等属性。

适用场景:展示图片信息的场景,如用户头像、产品图片等。

2.2、实际案例:用户注册表单

以下是一个简单的用户注册表单的XML布局示例,包含了上述控件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">
    <ImageView
        android:id="@+id/imageViewLogo"
        android:layout_width="38dp"
        android:layout_height="37dp"
        android:src="@drawable/logo" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="用户注册"
        android:textSize="30dp"
        android:textStyle="bold" />

    <EditText
        android:id="@+id/editTextUsername"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Username" />

    <EditText
        android:id="@+id/editTextEmail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Email"
        android:inputType="textEmailAddress" />

    <EditText
        android:id="@+id/editTextPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Password"
        android:inputType="textPassword" />

    <RadioGroup
        android:id="@+id/radioGroupGender"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <RadioButton
            android:id="@+id/radioButtonMale"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Male" />

        <RadioButton
            android:id="@+id/radioButtonFemale"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Female" />
    </RadioGroup>

    <CheckBox
        android:id="@+id/checkBoxAgree"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我同意条款和条件" />

    <Button
        android:id="@+id/buttonRegister"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="注册" />

    
</LinearLayout>

效果展示:

3、Activity与Intent

3.1、Activity

3.1.1、Activity介绍

Activity是Android应用中的一个单独的用户界面。每一个Activity都被给予一个窗口,在其中可以放置UI组件。当一个新的Activity启动时,前一个Activity将会暂停,并压入历史堆栈中。用户可以通过回退操作返回到前一个Activity。Activity是Android应用中非常重要的组件,它代表了用户与应用互动的一个屏幕或一个界面。

3.1.2、Activity生命周期

Activity的生命周期是由Android系统进行管理的,它描述了Activity从创建到销毁所经历的一系列状态。这些状态包括:

  1. 活动状态(Active/Running):Activity处于任务栈的栈顶,用户可以与其进行交互。
  2. 暂停状态(Paused):Activity失去了焦点但仍然对用户可见,如栈顶的Activity是透明的或并未铺满整个屏幕。此时,Activity可能因内存不足而被系统杀死。
  3. 停止状态(Stopped):当Activity被其他Activity完全遮挡时,它对用户不可见,但仍然保留其状态和成员信息。此时,如果系统需要内存,这个Activity也可能会被杀死。
  4. 销毁状态(Destroyed):Activity被系统从任务栈中移除,如果需要再次显示,必须重新创建和启动。

在Activity的生命周期中,系统会调用一系列的方法,如onCreate()onStart()onResume()onPause()onStop(), 和 onDestroy(),以便开发者在不同阶段进行相应的操作。

3.1.3、Activity启动模式

Android中的Activity有四种启动模式,它们决定了当启动一个新的Activity时,这个Activity与任务栈中已存在的Activity如何交互。这四种模式是:

  1. standard(标准模式):每次启动一个新的Activity都会创建该Activity的新实例,无论该Activity是否已经存在于任务栈中。

  2. singleTop(栈顶单例模式):如果新的Activity已经位于任务栈的栈顶,则不会创建新的Activity实例,而是通过调用该实例的onNewIntent()方法来传递新的Intent。如果新的Activity不在栈顶,则会创建新的实例并压入栈顶。

  3. singleTask(栈内单例模式):在这种模式下,系统会检查任务栈中是否已经存在该Activity的实例。如果存在,则将该实例之上的所有Activity出栈,使其成为栈顶,并调用其onNewIntent()方法。如果不存在,则创建新的实例。这意味着,在同一任务栈中,这个Activity只有一个实例存在。

  4. singleInstance(全局单例模式):这是一种特殊的启动模式。在这种模式下启动的Activity会运行在一个独立的任务栈中,并且这个Activity在整个应用中只有一个实例。无论从哪里启动这个Activity,都会回到这个已经存在的实例,并且这个实例所在的任务栈中不会有其他Activity存在。如果从这个Activity启动其他Activity,那么新的Activity会运行在新的任务栈中。

3.2、Intent与IntentFilter

3.2.1、Intent

Intent是一个消息传递对象,可用于请求一个动作。Intent可以用来启动Activity、Service或发送广播。Intent描述了一种操作,可以是启动一个新的Activity,或者是请求一个已经存在的Activity执行某个操作。

  • Intent的表现形式(代码)
Intent intent = new Intent(CurrentActivity.this, TargetActivity.class);  
startActivity(intent);
  • Intent的种类
  1. 显式Intent:明确指定了要启动的组件(如Activity的类名)。
  2. 隐式Intent:不指定具体要启动的组件,而是通过Intent Filter中的action、category、data来匹配能够处理该Intent的组件。
  • Intent属性
  1. setAction()设置动作类型。
  2. setData()设置要操作的数据URI。
  3. setType()设置数据类型(MIME类型)。
  4. setCategory()设置Intent的类别。
  5. putExtra()添加附加数据。
  • IntentFilter

IntentFilter用于描述一个组件(如Activity、Service、BroadcastReceiver)能够响应的Intent类型。它根据Intent的action、data、category来过滤Intent。

3.3、不同页面数据传递(示例代码)

传递数据:

Intent intent = new Intent(CurrentActivity.this, TargetActivity.class);  
intent.putExtra("key", "value"); // 传递字符串数据  
startActivity(intent);

接收数据(在TargetActivity中):

String value = getIntent().getStringExtra("key"); // 通过key获取传递的数据

3.4、Fragment


Fragment表示Activity中的一个片段或行为。它可以让用户在一个Activity中切换不同的视图或屏幕。Fragment有自己的生命周期,且它的生命周期受宿主Activity的生命周期影响。

使用要点

  1. Fragment必须嵌入到Activity中使用。
  2. Fragment的生命周期与Activity紧密相关。
  3. 可以通过FragmentManager来管理Fragment(如添加、替换、删除)。
  4. Fragment之间可以通过接口进行通信。

3.4.1、在Activity中添加Fragment的案例

通过布局文件添加Fragment

在Activity的布局文件中,可以直接使用<fragment>标签来添加Fragment:

<fragment android:name="com.example.MyFragment"  
          android:id="@+id/my_fragment"  
          android:layout_width="match_parent"  
          android:layout_height="match_parent" />
在Activity中动态添加Fragment

在Activity的代码中,可以使用FragmentManager来动态添加Fragment:

FragmentManager fragmentManager = getSupportFragmentManager();  
FragmentTransaction transaction = fragmentManager.beginTransaction();  
MyFragment fragment = new MyFragment();  
transaction.add(R.id.fragment_container, fragment); // R.id.fragment_container是容纳Fragment的ViewGroup的ID  
transaction.commit();

在这个例子中,MyFragment是自定义的Fragment类,R.id.fragment_container是Activity布局中用于容纳Fragment的ViewGroup(如FrameLayout)的ID。通过FragmentTransactionadd方法将Fragment添加到容器中,并通过commit方法提交事务。

4、Android高级控件

4.1、高级控件高级在何处

  1. 数据适配器的使用:高级控件通常需要与数据适配器(Adapter)配合使用。适配器的作用是将复杂的数据填充到指定的视图界面上。例如,ListView、Spinner、GridView等控件都需要使用适配器来管理和展示数据。这种数据与视图之间的分离设计,使得控件更加灵活和可重用。
  2. 视图管理与数据绑定的分离:高级控件通常不直接处理数据的展示,而是通过适配器来实现数据与视图的绑定。这种设计模式降低了控件与数据之间的耦合度,提高了代码的可维护性和可扩展性。
  3. 支持复杂的数据展示:与低级控件相比,高级控件能够展示更复杂的数据结构。例如,通过SimpleAdapter,可以绑定格式复杂的数据,包括文本、图片等多种数据类型。
  4. 提供丰富的交互功能:高级控件往往支持更丰富的用户交互,如列表项的点击事件监听、滑动切换视图等。这些交互功能提升了用户体验,使得应用更加生动和易用。
  5. 优化的性能表现:一些高级控件,如RecyclerView,通过引入ViewHolder机制等优化手段,提高了列表滚动的性能表现,减少了不必要的视图创建和销毁操作。

4.2、常用的高级控件

4.2.1、AutoCompleteTextView

AutoCompleteTextView 可以在用户输入时提供自动完成的建议列表

1、添加 AutoCompleteTextView 到布局

    <AutoCompleteTextView
        android:id="@+id/autoText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:completionHint="请选择选项"
        android:completionThreshold="1"
        android:hint="请输入文本" />

2、将 AutoCompleteTextView 与 ArrayAdapter 绑定

AutoCompleteTextView autoText = findViewById(R.id.autoText);
        String[] courses = {
                "Android入门",
                "Android项目实战",
                "Android网络开发",
        };
        ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, courses);
        autoText.setAdapter(adapter);

效果展示:

4.2.2、Spinner

Spinner 提供下拉选择功能,显示数据集合

1、添加 Spinner 到布局

<Spinner  
    android:id="@+id/spinner"  
    android:layout_width="match_parent"  
    android:layout_height="wrap_content" />

2、创建一个 ArrayAdapter

ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,  
R.array.android_development_terms, android.R.layout.simple_spinner_item);  
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

在上述代码中,R.array.android_development_terms 是一个字符串数组资源,可以在 res/values/arrays.xml 中定义它,例如:

<resources>
    <string-array name="android_development_terms">
        <item>Activity</item>
        <item>Fragment</item>
        <item>Intent</item>
        <item>Adapter</item>
        <item>BroadcastReceiver</item>
        <item>Service</item>
        <item>ContentProvider</item>
        <item>AsyncTask</item>
    </string-array>
</resources>

3、将 Spinner 与 ArrayAdapter 绑定

Spinner spinner = (Spinner) findViewById(R.id.spinner);  
spinner.setAdapter(adapter);

4、设置 Spinner 的监听器

spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {  
    @Override  
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {  
        String selected = parent.getItemAtPosition(position).toString();  
        Log.i("MyTag", "Selected: " + selected); 
    }  
  
    @Override  
    public void onNothingSelected(AdapterView<?> parent) {  
        // Do something here if needed  
    }  
});

效果展示:

4.2.3、ScrollView、HoriontalScrollView

ScrollView 是一个可以垂直滚动的视图组

<ScrollView  
    android:layout_width="match_parent"  
    android:layout_height="match_parent">  
  
    <LinearLayout  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:orientation="vertical">  
  
        <!-- 放置你的其他视图组件,如TextView, ImageView等 -->  
  
    </LinearLayout>  
  
</ScrollView>

HorizontalScrollView 的使用与 ScrollView 类似,但它是水平滚动的。

<HorizontalScrollView  
    android:layout_width="match_parent"  
    android:layout_height="wrap_content">  
  
    <LinearLayout  
        android:layout_width="wrap_content"  
        android:layout_height="match_parent"  
        android:orientation="horizontal">  
  
        <!-- 放置你的其他视图组件,这些组件将会水平排列 -->  
  
    </LinearLayout>  
  
</HorizontalScrollView>

4.2.4、ListView

ListView 展示列表数据,支持滚动与交互

1、添加 ListView 到布局

    <ListView  
        android:id="@+id/list_view"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content" />  

2、设置适配器和处理点击事件

 // 数据源,一个简单的字符串数组  
String[] data = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"};  
  
// 获取ListView控件的引用  
ListView listView = findViewById(R.id.list_view);  
  
// 创建一个ArrayAdapter,将数据源与ListView进行绑定  
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, data);  
  
// 设置ListView的适配器  
listView.setAdapter(adapter);  
  
// 设置ListView的项点击监听器  
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
@Override  
public void onItemClick(AdapterView<?> parent, android.view.View view, int position, long id) {  
// 当某个项被点击时,显示一个Toast消息  
    Toast.makeText(MainActivity.this, "You clicked: " + parent.getItemAtPosition(position), Toast.LENGTH_SHORT).show();  
}  
});  

效果展示:

4.2.5、GridView

GridView 用于以网格形式展示一系列项目

1、布局文件中添加 GridView

<GridView  
    android:id="@+id/gridView"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:numColumns="3"  
    android:verticalSpacing="10dp"  
    android:horizontalSpacing="10dp"  
    android:columnWidth="90dp"  
    android:stretchMode="columnWidth"  
    android:gravity="center"/>

2、创建一个适配器来填充 GridView

public class ImageAdapter extends BaseAdapter {
    private Context context;
    private final Integer[] imageIds = {
            R.drawable.logo,
            R.drawable.dm1,
            R.drawable.dm2,
            R.drawable.dm3,
            R.drawable.dm4,
            R.drawable.cat,
            // ... 更多图片资源ID
    };

    public ImageAdapter(Context c) {
        context = c;
    }

    @Override
    public int getCount() {
        return imageIds.length;
    }

    @Override
    public Object getItem(int position) {
        return imageIds[position];
    }

    @Override
    public long getItemId(int position) {
        return position;
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) {
            imageView = new ImageView(context);
            imageView.setLayoutParams(new GridView.LayoutParams(180, 180));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(3, 3, 3, 3);
        } else {
            imageView = (ImageView) convertView;
        }

        imageView.setImageResource(imageIds[position]);
        return imageView;
    }
}

3、在Activity 中设置 GridView 的适配器,并为其添加点击事件监听器

GridView gridView = findViewById(R.id.gridView);
gridView.setAdapter(new ImageAdapter(this));

gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    Toast.makeText(MainActivity.this, "You clicked item " + position,Toast.LENGTH_SHORT).show();
}
});

效果展示:

4.2.6、ProgressBar、SeekBar

4.2.6.1、ProgressBar

ProgressBar 可以用来显示一个任务的进度。以下是如何在布局文件中添加一个 ProgressBar 和如何在代码中更新它的进度的示例:

1、XML 布局文件

<ProgressBar  
    android:id="@+id/progressBar"  
    style="?android:attr/progressBarStyleHorizontal"  
    android:layout_width="match_parent"  
    android:layout_height="wrap_content"  
    android:max="100"  
    android:progress="0" />

2、Java 代码 (MainActivity.java):

ProgressBar progressBar;  
  
@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.activity_main);  
  
    progressBar = findViewById(R.id.progressBar);  
  
    // 模拟进度更新  
    new Thread(new Runnable() {  
        @Override  
        public void run() {  
            for (int i = 0; i <= 100; i++) {  
                final int progress = i;  
                runOnUiThread(new Runnable() {  
                    @Override  
                    public void run() {  
                        progressBar.setProgress(progress);  
                    }  
                });  
                try {  
                    Thread.sleep(100); // 模拟耗时任务  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
    }).start();  
}

效果展示:

4.2.6.2、SeekBar

SeekBar 允许用户通过滑动条来选择一个值。以下是如何在布局文件中添加一个 SeekBar 和如何在代码中处理其值变化的示例:

1、XML 布局文件

<TextView
        android:id="@+id/progressText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

<SeekBar  
    android:id="@+id/seekBar"  
    android:layout_width="match_parent"  
    android:layout_height="wrap_content"  
    android:max="100" />

2、Java 代码 (MainActivity.java):

SeekBar seekBar;  
TextView progressText;  
  
@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.activity_main);  
  
    seekBar = findViewById(R.id.seekBar);  
    progressText = findViewById(R.id.progressText); // 用TextView 来显示进度值  
  
    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {  
        @Override  
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {  
            progressText.setText("Progress: " + progress); // 更新 TextView 以显示当前进度值  
        }  
  
        @Override  
        public void onStartTrackingTouch(SeekBar seekBar) { } // 可以根据需要实现这些方法  
  
        @Override  
        public void onStopTrackingTouch(SeekBar seekBar) { } // 可以根据需要实现这些方法  
    });  
}

效果展示:

4.2.7、选项卡(TabHost、TabWidget、FrameLayout)

在Android中,TabHostTabWidget, 和 FrameLayout 常被一起使用来创建一个带有选项卡的用户界面。以下是一个简单的示例代码,展示了如何使用这些组件:

1、XML 布局文件

<TabHost
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:android="http://schemas.android.com/apk/res/android">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1">

                <!-- 在这里添加你的选项卡内容 -->
                <!-- 例如,两个TextView作为两个选项卡的内容 -->
                <TextView
                    android:id="@+id/textview1"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="这是选项卡1的内容" />

                <TextView
                    android:id="@+id/textview2"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="这是选项卡2的内容"
                    android:visibility="gone"/> <!-- 初始时设置为不可见 -->
            </FrameLayout>
        </LinearLayout>
    </TabHost>

2、Java 代码 (MainActivity.java)

TabHost tabHost = findViewById(android.R.id.tabhost);
TabWidget tabWidget = findViewById(android.R.id.tabs);
FrameLayout tabContent = findViewById(android.R.id.tabcontent);

// 设置选项卡内容
tabHost.setup();

// 创建选项卡1
TabHost.TabSpec tabSpec1 = tabHost.newTabSpec("Tab 1");
tabSpec1.setContent(R.id.textview1);
tabSpec1.setIndicator("选项卡1");
tabHost.addTab(tabSpec1);

// 创建选项卡2
TabHost.TabSpec tabSpec2 = tabHost.newTabSpec("Tab 2");
tabSpec2.setIndicator("选项卡2");
tabHost.addTab(tabSpec2);

// 设置选项卡更改监听器(可选)
tabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
    public void onTabChanged(String tabId) {
        if ("Tab 1".equals(tabId)) {
            findViewById(R.id.textview1).setVisibility(View.VISIBLE);
            findViewById(R.id.textview2).setVisibility(View.GONE);
        } else if ("Tab 2".equals(tabId)) {
            findViewById(R.id.textview1).setVisibility(View.GONE);
            findViewById(R.id.textview2).setVisibility(View.VISIBLE);
        }
    }
});

效果展示:

4.2.8、ViewPager2

ViewPager2 是 Android Jetpack 组件库中的一个控件,用于在屏幕上水平或垂直滑动视图。

1、添加依赖

首先,在 build.gradle 文件中添加 ViewPager2 的依赖

dependencies {  
    implementation 'androidx.viewpager2:viewpager2:1.0.0'  
}

2、创建布局文件

在布局文件中添加 ViewPager2 控件

<!-- res/layout/activity_main.xml -->  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical">  
  
    <androidx.viewpager2.widget.ViewPager2  
        android:id="@+id/viewPager"  
        android:layout_width="match_parent"  
        android:layout_height="match_parent" />  
</LinearLayout>

3、创建适配器

创建一个继承自 RecyclerView.Adapter 的适配器类,用于提供 ViewPager2 显示的数据

import android.view.LayoutInflater;  
import android.view.View;  
import android.view.ViewGroup;  
import android.widget.ImageView;  
import android.widget.TextView;  
import androidx.annotation.NonNull;  
import androidx.recyclerview.widget.RecyclerView;  
  
public class ViewPagerAdapter extends RecyclerView.Adapter<ViewPagerAdapter.ViewHolder> {  
    private int[] imageResources;  
  
    public ViewPagerAdapter(int[] imageResources) {  
        this.imageResources = imageResources;  
    }  
  
    @NonNull  
    @Override  
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {  
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.pager_item, parent, false);  
        return new ViewHolder(view);  
    }  
  
    @Override  
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {  
        holder.imageView.setImageResource(imageResources[position]);  
    }  
  
    @Override  
    public int getItemCount() {  
        return imageResources.length;  
    }  
  
    public class ViewHolder extends RecyclerView.ViewHolder {  
        ImageView imageView;  
  
        public ViewHolder(@NonNull View itemView) {  
            super(itemView);  
            imageView = itemView.findViewById(R.id.imageView);  
        }  
    }  
}

其中,pager_item 是每个页面项的布局,如下所示

<!-- res/layout/pager_item.xml -->  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical"  
    android:gravity="center">  
  
    <ImageView  
        android:id="@+id/imageView"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:scaleType="centerCrop" />  
</LinearLayout>

4、在 Activity 中设置 ViewPager2

在 Activity 中初始化 ViewPager2 并设置适配器

import androidx.appcompat.app.AppCompatActivity;  
import androidx.viewpager2.widget.ViewPager2;  
import android.os.Bundle;  
  
public class MainActivity extends AppCompatActivity {  
    private ViewPager2 viewPager;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
  
        viewPager = findViewById(R.id.viewPager);  
        int[] imageResources = new int[]{R.drawable.image1, R.drawable.image2, R.drawable.image3}; // 替换为你的图片资源ID  
        ViewPagerAdapter adapter = new ViewPagerAdapter(imageResources);  
        viewPager.setAdapter(adapter);  
    }  
}

5、Android菜单与对话框设计 

5.1、菜单

5.1.1、OptionsMenu(选项菜单)

在Android中,OptionsMenu通常位于屏幕的右上角,以三个垂直点的图标显示。用户点击该图标时,会显示一个下拉菜单。

代码示例

1、在res/menu目录下创建一个XML文件来定义菜单项

<menu xmlns:android="http://schemas.android.com/apk/res/android">  
    <item  
        android:id="@+id/action_settings"  
        android:title="@string/action_settings"  
        android:orderInCategory="100"  
        app:showAsAction="never" />  
</menu>

2、在Activity中重写onCreateOptionsMenu()onOptionsItemSelected()方法

@Override  
public boolean onCreateOptionsMenu(Menu menu) {  
    getMenuInflater().inflate(R.menu.menu_main, menu);  
    return true;  
}  
  
@Override  
public boolean onOptionsItemSelected(MenuItem item) {  
    int id = item.getItemId();  
    if (id == R.id.action_settings) {  
        // 处理设置菜单项的点击事件  
        return true;  
    }  
    return super.onOptionsItemSelected(item);  
}

5.1.2、ContextMenu(上下文菜单)

ContextMenu(上下文菜单)通常用于在用户长按某个视图时显示一个菜单,提供与该视图相关的操作选项。

代码示例

1、XML:

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="长按我显示上下文菜单"
        android:textSize="20dp"
        />

2、Java 代码 (MainActivity.java):

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 注册上下文菜单
        registerForContextMenu(findViewById(R.id.textView));
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        // 添加菜单项
        menu.add(0, 1, 0, "选项1");
        menu.add(0, 2, 0, "选项2");
        menu.add(0, 3, 0, "选项3");
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case 1:
                // 处理选项1的点击事件
                Toast.makeText(this, "你点击了选项1", Toast.LENGTH_SHORT).show();
                return true;
            case 2:
                // 处理选项2的点击事件
                Toast.makeText(this, "你点击了选项2", Toast.LENGTH_SHORT).show();
                return true;
            case 3:
                // 处理选项3的点击事件
                Toast.makeText(this, "你点击了选项3", Toast.LENGTH_SHORT).show();
                return true;
            default:
                return super.onContextItemSelected(item);
        }
    }
}

效果展示:

5.2、对话框

5.2.1、AlertDialog(普通对话框)

AlertDialog 是一个用于显示对话框的便捷类,它可以显示一个标题、一些文本、最多三个按钮以及一个可选的列表视图。

代码示例:

1、XML:

    <Button
        android:id="@+id/show_dialog_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="button"/>

2、Java 代码 (MainActivity.java):

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 绑定布局文件中的按钮,点击后会弹出AlertDialog
        Button showDialogButton = findViewById(R.id.show_dialog_button);
        showDialogButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showAlertDialog();
            }
        });
    }

    private void showAlertDialog() {
        // 创建AlertDialog.Builder对象
        AlertDialog.Builder builder = new AlertDialog.Builder(this);

        // 设置对话框的标题和消息
        builder.setTitle("标题");
        builder.setMessage("这是一个AlertDialog示例。");

        // 添加“确定”按钮及其点击事件
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // 确定按钮的点击事件
                // 在这里编写确定后的操作
            }
        });

        // 添加“取消”按钮及其点击事件
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // 取消按钮的点击事件
                // 在这里编写取消后的操作,或者什么都不做直接关闭对话框
            }
        });

        // 创建并显示AlertDialog
        AlertDialog dialog = builder.create();
        dialog.show();
    }
}

效果展示:

5.2.2、AlertDialog.Builder(灵活对话框)

AlertDialog.Builder 是 Android 中用于构建 AlertDialog 的一个便捷的类。它提供了一种链式调用的方式来配置和显示对话框。

示例代码:

1、XML:

    <Button
        android:id="@+id/show_dialog_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="button"/>

2、Java 代码 (MainActivity.java):

public class MainActivity extends AppCompatActivity {  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
  
        // 假设你的布局文件中有一个按钮,点击后会弹出AlertDialog  
        Button showDialogButton = findViewById(R.id.show_dialog_button);  
        showDialogButton.setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                showFlexibleAlertDialog();  
            }  
        });  
    }  
  
    private void showFlexibleAlertDialog() {  
        // 创建AlertDialog.Builder对象  
        AlertDialog.Builder builder = new AlertDialog.Builder(this);  
  
        // 设置对话框的标题  
        builder.setTitle("请选择一个选项");  
  
        // 设置单选列表及其点击事件  
        String[] items = {"选项1", "选项2", "选项3"};  
        builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {  
            @Override  
            public void onClick(DialogInterface dialog, int which) {  
                // which 是被点击的项目的索引  
                Toast.makeText(MainActivity.this, "你选择了: " + items[which], Toast.LENGTH_SHORT).show();  
                dialog.dismiss(); // 关闭对话框  
            }  
        });  
  
        // 设置取消按钮及其点击事件(可选)  
        builder.setNegativeButton("取消", null); // 如果不需要执行任何操作,可以传入null  
  
        // 创建并显示AlertDialog  
        AlertDialog dialog = builder.create();  
        dialog.show();  
    }  
}

效果展示:

结束语:

通过本次总结,回顾了《APP应用开发》课程中关于Android布局与控件、Activity与Intent以及高级控件与交互设计等方面的知识。这些知识为我构建功能丰富、界面美观的Android应用提供了坚实的基础。在未来的学习和实践中,我将继续深入探索Android开发的奥秘,不断提升自己的技能水平。

参考文献:

开发者指南  |  Android Developers

  • 37
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值