全面总结之 基础控件 篇(二)

ProgressBar - 进度条

我们尝尝使用 ProgressBar 来向用户展示某个操作的进度,或者提示用户等待,从而提高友好性。

ProgressBar 支持多种风格,通过 style 属性可以为 ProgressBar 指定风格。该属性支持以下几个属性:

  • @android:style/Widget.ProgressBar.Horizontal 水平进度条
  • @android:style/Widget.ProgressBar.Inverse 普通大小的环形进度条
  • @android:style/Widget.ProgressBar.Large 大环形进度条
  • @android:style/Widget.ProgressBar.Large.Inverse 大环形进度条
  • @android:style/Widget.ProgressBar.Small 小环形进度条
  • @android:style/Widget.ProgressBar.Small.Inverse 小环形进度条

其他常用属性:

  • android:max - 设置该进度条的最大值
  • android:progress - 设置该进度条已经完成的进度值
  • android:progressDrawable - 设置该进度条的轨道对应的 Drawable 对象
  • android:indeterminate - 该属性为 true,设置进度条不精确显示进度
  • android:indeteminateDrawable - 设置绘制不显示进度的进度条的 Drawable 对象
  • android:indeterminateDuration - 设置不精确显示进度的持续时间

常用的方法:

  • setProgress - 设置进度的完成百分比
  • incrementProgressBy - 设置进度条的进度增加或减少,参数为正数的时候增加,参数为负数的时候减少

dialog - 对话框

Dialog 类是对话框的基类,但您应该避免直接实例化 Dialog,而是使用下列子类之一:

  • AlertDialog:此对话框可显示标题、最多三个按钮、可选择项列表或自定义布局。

  • DatePickerDialog 或 TimePickerDialog:此对话框带有允许用户选择日期或时间的预定义 UI。

DatePickerDialog / TimePickerDialog 使用较少,这里就不详细介绍,具体使用可以看这里: Pickers

重要方法:
对话框的创建需要使用 AlertDialog.Builder 类,通过该类构建一个 AlertDialog.Builder 对象,然后调用该对象的一系列 setXXX 方法,常用的方法有:

  • setTitle:设置对话框的标题 Title。
  • setMessage:设置对话框主体信息。
  • setIcon:设置对话框的图标。
  • setItems:将弹窗内容设置为列表状(如果设置了 setMessage,则该设置无效)。
  • setMultiChoiceItems:将弹窗内容设置为多选框,该属性同样和 setMessage 互斥。
  • setSingleChoiceItems:将弹窗内容设置为单选,该属性同样和 setMessage 互斥。
  • setCancelable:如果该属性值为 false,则弹窗无法通过返回键或点击空白处退出。
  • setPositiveButton:设置“肯定”属性按钮,例如:OK、可以、确认。。。
  • setNegativeButton:设置“否定”属性按钮,例如:No、取消、退出等。
  • setNeutralButton:设置“中性”属性按钮,例如:稍后提醒、暂不等。
  • setView:自定义弹窗布局。
  • show:显示弹窗。
  • onCancel:取消对话框。

更多关于 Dialog 的内容,请看这里: https://developer.android.google.cn/guide/topics/ui/dialogs.html


Notification - 通知

Notification 是一种全局效果的通知,可以在系统的通知栏中显示。当 APP 向系统发出通知时,它先以图标的形式显示在通知栏中,用户可以通过下拉通知栏查看通知的详情。

Notification 必须包含以下内容:

  • 小图标
  • 标题
  • 内容

创建 Notification 主要涉及到 Notification.Builder、Notification 和 NotificationManager:

  • Notification.Builder 用来构建 Notification 对象
  • Notification 用来保存相关数据
  • NotificationManager 是一个系统服务,调用其 notify 方法可以向系统发送通知

基本操作:

  • 创建 Notification.Builder 对象,并设置标题内容图标
  • 创建 NotificationManager 对象
  • 调用 NotificationManager 的 notify 方法发送通知
        Notification.Builder builder = new Notification.Builder(this)
                .setContentTitle("这是标题")
                .setContentText("这是内容")
                .setSmallIcon(R.mipmap.ic_launcher);
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        manager.notify(1, builder.build());
    }

以上是简单的通知应用。

有时候我们需要点击通知,跳转到特定的 Activity 当中,要实现这样的功能,就需要用到之前 Intent 讲到的 pendingIntent,如何设置 PendingIntent 以获得全新任务取决于正在启动的 Activity 的性质。一般有两种情况:

  • 常规 Activity
    您要启动的 Activity 是应用的正常工作流的一部分。在这种情况下,请设置 PendingIntent 以启动全新任务并为 PendingIntent提供返回栈,这将重现应用的正常“返回”行为。

  • 特殊 Activity
    仅当从通知中启动时,用户才会看到此 Activity。 从某种意义上说,Activity 是通过提供很难显示在通知本身中的信息来扩展通知。对于这种情况,请将 PendingIntent 设置为在全新任务中启动。但是,由于启动的 Activity 不是应用 Activity 流程的一部分,因此无需创建返回栈。点击“返回”仍会将用户带到主屏幕。

常规 Activity
要设置可启动直接进入 Activity 的 PendingIntent,请执行以下步骤:

  • 在清单文件中定义应用的 Activity 层次结构。

    • 添加对 Android 4.0.3 及更低版本的支持。为此,请通过添加 <meta-data> 元素作为 <activity> 的子项来指定正在启动的 Activity 的父项。
      对于此元素,请设置 android:name="android.support.PARENT_ACTIVITY"。 设置 android:value="<parent_activity_name>",其中,<parent_activity_name> 是父 <activity> 元素的 android:name 值。请参阅下面的 XML 示例。

    • 同样添加对 Android 4.1 及更高版本的支持。为此,请将 android:parentActivityName 属性添加到正在启动的 Activity 的 <activity> 元素中。

<activity
    android:name=".MainActivity"
    android:label="@string/app_name" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity
    android:name=".ResultActivity"
    android:parentActivityName=".MainActivity">
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value=".MainActivity"/>
</activity>
  • 根据可启动 Activity 的 Intent 创建返回栈:
    • 创建 Intent 以启动 Activity。
    • 通过调用 TaskStackBuilder.create() 创建堆栈生成器。
    • 通过调用 addParentStack() 将返回栈添加到堆栈生成器。 对于在清单文件中所定义层次结构内的每个 Activity,返回栈均包含可启动 Activity 的 Intent 对象。此方法还会添加一些可在全新任务中启动堆栈的标志。
    • 通过调用 addNextIntent(),添加可从通知中启动 Activity 的 Intent。 将在第一步中创建的 Intent 作为 addNextIntent() 的参数传递。
    • 如需,请通过调用 TaskStackBuilder.editIntentAt() 向堆栈中的 Intent 对象添加参数。有时,需要确保目标 Activity 在用户使用“返回”导航回它时会显示有意义的数据。
    • 通过调用 getPendingIntent() 获得此返回栈的 PendingIntent。 然后,您可以使用此 PendingIntent 作为 setContentIntent() 的参数。

以下代码段演示了该流程:

...
Intent resultIntent = new Intent(this, ResultActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent to the top of the stack
stackBuilder.addNextIntent(resultIntent);
// Gets a PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
        stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());

特殊 Activity
下文介绍如何设置特殊 Activity PendingIntent。

特殊 Activity 无需返回栈,因此您不必在清单文件中定义其 Activity 层次结构,也不必调用 addParentStack() 来构建返回栈。取而代之的是,您可使用清单文件设置 Activity 任务选项,并通过调用 getActivity() 创建 PendingIntent:

  • 在清单文件中,将以下属性添加到 Activity 的 <activity> 元素
    • android:name="activityclass"
      Activity 的完全限定类名。
    • android:taskAffinity=""
      与您在代码中设置的 FLAG_ACTIVITY_NEW_TASK 标志相结合,这可确保此 Activity 不会进入应用的默认任务。任何具有应用默认关联的现有任务均不受影响。
    • android:excludeFromRecents="true"
      将新任务从“最新动态”中排除,这样用户就不会在无意中导航回它。

以下代码段显示了该元素:

<activity
    android:name=".ResultActivity"
...
    android:launchMode="singleTask"
    android:taskAffinity=""
    android:excludeFromRecents="true">
</activity>
...
  • 构建并发出通知:
    • 创建可启动 Activity的 Intent。
    • 通过使用 FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_CLEAR_TASK 标志调用 setFlags(),将 Activity 设置为在新的空任务中启动。
    • 为 Intent 设置所需的任何其他选项。
    • 通过调用 getActivity() 从 Intent 中创建 PendingIntent。 然后,您可以使用此 PendingIntent 作为 setContentIntent() 的参数。

以下代码段演示了该流程:

// Instantiate a Builder object.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// Creates an Intent for the Activity
Intent notifyIntent =
        new Intent(this, ResultActivity.class);
// Sets the Activity to start in a new, empty task
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_CLEAR_TASK);
// Creates the PendingIntent
PendingIntent notifyPendingIntent =
        PendingIntent.getActivity(
        this,
        0,
        notifyIntent,
        PendingIntent.FLAG_UPDATE_CURRENT
);

// Puts the PendingIntent into the notification builder
builder.setContentIntent(notifyPendingIntent);
// Notifications are issued by sending them to the
// NotificationManager system service.
NotificationManager mNotificationManager =
    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Builds an anonymous Notification object from the builder, and
// passes it to the NotificationManager
mNotificationManager.notify(id, builder.build());

删除通知
除非发生以下情况之一,否则通知仍然可见:

  • 用户单独或通过使用“全部清除”清除了该通知(如果通知可以清除)。
  • 用户点击通知,且您在创建通知时调用了 setAutoCancel()。
  • 您针对特定的通知 ID 调用了 cancel()。此方法还会删除当前通知。
  • 您调用了 cancelAll() 方法,该方法将删除之前发出的所有通知。

更多关于 Notification 的内容,请看这里:通知


Toast

Toast是在窗口表面弹出的一个消息。它只填充消息展现需要的空间,并且用户当前的Activity依然可见和可交互。通知自动的渐入渐出,不接受交互事件。

广播通知能够由Activity或Service创建和显示。如果你创建了一个源自Service的广播通知,它会显示当前有焦点的Activity的前面。

如要需要用户对通知做出响应,请考虑使用状态栏通知。

基础

首先,用makeText()方法实例化一个Toast对象。这个方法需要三个参数:

  • 应用程序的Context对象

  • 要显示的文本消息

  • 通知持续表示的时间

这个方法会返回一个合适的被实例化的Toast对象。你能够用show()方法显示广播通知,显示方法如下:

Context context = getApplicationContext();
CharSequence text = "Hello toast!";
int duration = Toast.LENGTH_SHORT;

Toast toast = Toast.makeText(context, text, duration);
toast.show();

这个示例程序给你演示大多数广播通知所需要做的每一件事情。你很少需要再做其他的事情。但是,你可能想要把广播通知放到不同的位置,甚至要使用自己的布局来替代那个简单的文本消息框。以下,将向你介绍如何实现这些想法。

给广播通知定位

标准的广播通知水平居中显示在屏幕底部附近,你能够通过setGravity(int,int,int)方法来改变这个位置。这个方法有三个参数:

  • Gravity常量(详细参照Gravity类)

  • X轴偏移量

  • Y轴偏移量。

例如,如果你想让通知显示在屏幕的左上角,你可以用下面这样的方法调用:

toast.setGravity(Gravity.TOP|Gravity.LEFT, 0, 0);

如果你想要向右移动位置,可以增加第二个参数的值。要向下移动,可以增加最后一个参数的值。

创建一个定制的广播视窗

如果一个简单的文本消息不同满足现实的需要,你可以给广播通知创建一个定制的布局。要创建一个定制的布局,可以在XML文件或应用程序代码中定义一个View布局,然后把根View对象传递给setView(View)方法。
例如,你可以用下面的XML文件创建一个如下图2所示的广播通知视窗。

<LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android"
              android:id="@+id/toast_layout_root"
              android:orientation="horizontal"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:padding="10dp"
              android:background="#DAAA"
              >
    <ImageView android:id="@+id/image"
               android:layout_width="wrap_content"
               android:layout_height="fill_parent"
               android:layout_marginRight="10dp"
               />
    <TextView android:id="@+id/text"
              android:layout_width="wrap_content"
              android:layout_height="fill_parent"
              android:textColor="#FFF"
              />

</LinearLayout>

注意,LinearLayout元素的ID属性值是“toast_layout_root”。你必须使用这个ID的把XML的定义填充到布局中,方法如下:

LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.toast_layout,(ViewGroup) findViewById(R.id.toast_layout_root));

ImageView image = (ImageView) layout.findViewById(R.id.image);
image.setImageResource(R.drawable.android);
TextView text = (TextView) layout.findViewById(R.id.text);
text.setText("Hello! This is a custom toast!");

Toast toast = new Toast(getApplicationContext());
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();

首先,用 getLayoutInflater() 方法(或 getSystemService() 方法)获取 LayoutInflater 对象,然后使用 inflate(int, ViewGroup) 方法把 XML 定义填充到布局中,这个方法的第一个参数是布局资源的 ID,第二个参数要填充布局的 View 对象,本例是根 View 对象。你能够使用这个被填充的布局来查找布局中 View 对象,以便获取和定义 ImageView 和 TextView 元素的内容。最后,用 Toast(Context) 方法创建一个广播通知,并设置了一些广播通知的属性,如 Gravity 常量和持续显示时间。然后调用 setView(View) 方法,把它传递给要填充的布局对象。然后调用 show() 方法显示这个定制的广播通知。

注意:除非你要用setView(View)方法定义布局,否则不要使用公共的Toast类构造器。如果不使用定制的布局,必须使用makeText(Context, int, int)方法来创建广播通知。

Copyright© 2020-2022 li-xyz 冀ICP备2022001112号-1