还在担心Android功能不会用吗?Intro Showcase View助你快速实现功能引导

  1. 引言

在现代应用开发中,如何有效引导用户快速上手并掌握应用的核心功能,是提升用户体验的重要一环。功能引导不仅帮助用户理解复杂功能,还能提高用户留存率,减少因操作复杂度带来的用户流失。随着 Android 平台的不断发展,功能引导的实现方式也在不断演进。本文将深入探讨如何在 Android 开发中实现高效的功能引导,特别是在传统 View 系统与 Jetpack Compose 环境中的实现。

  1. 功能引导的设计原则

功能引导的设计需要遵循一定的规范和原则,以确保用户能够快速理解并掌握应用的关键功能。根据 Material Design 的设计规范,引导设计应注重以下几个方面:

  • 可见性:引导内容应足够突出,避免被用户忽略。通过颜色、动画等方式增强其视觉吸引力。
  • 简洁性:信息传达要简洁明了,避免过多的文字说明,用户能够一眼理解。
  • 互动性:引导应与用户的操作相关联,提供即时的反馈,增强用户的参与感。
    了解用户心理,特别是在首次使用应用时的心理状态,有助于设计更具吸引力和有效的引导流程。
  1. 功能引导的技术实现

使用传统 View 系统实现功能引导

在传统 Android 开发中,MaterialTapTargetPrompt 是一个广泛使用的库,旨在帮助开发者实现基于 Material Design 的功能引导。以下是如何使用该库的详细步骤:

  • 依赖导入:首先,在 build.gradle 文件中添加库的依赖:
    dependencies {
    implementation ‘uk.co.samuelwall:material-tap-target-prompt:3.3.2’
    }
  • 基本实现:通过以下代码,快速实现一个功能引导,该引导会在 FloatingActionButton 上显示一个提示:
    MaterialTapTargetPrompt.Builder(this)
    .setTarget(R.id.fab)
    .setPrimaryText(“发送你的第一封邮件”)
    .setSecondaryText(“点击信封图标开始撰写你的第一封邮件”)
    .setPromptStateChangeListener { prompt, state ->
    if (state == MaterialTapTargetPrompt.STATE_FOCAL_PRESSED) {
    // 用户已点击引导目标
    }
    }
    .show()
  • 状态变化处理:通过 setPromptStateChangeListener,你可以监控引导的状态变化,并根据用户操作执行相应的逻辑。
    Example

以下示例展示了在不同场景下如何使用该库进行功能引导:

  1. 简单的视图目标引导

最基本的功能引导只需要指定目标视图(通过 ID 或 View 对象)和引导文本。

通过 ID 设置目标视图:

MaterialTapTargetPrompt.Builder(this)
.setTarget(R.id.fab)
.setPrimaryText(“发送你的第一封邮件”)
.show()
通过 View 对象设置目标视图:

MaterialTapTargetPrompt.Builder(this)
.setTarget(findViewById(R.id.fab))
.setPrimaryText(“发送你的第一封邮件”)
.show()

  1. 引导 App Bar 中的菜单项

对于在 App Bar 中显示的菜单项,可以通过其 ID 进行目标设置。

菜单 XML 示例:
引导菜单项:

MaterialTapTargetPrompt.Builder(this)
.setTarget(R.id.action_search)
.setPrimaryText(“点击这里开始搜索”)
.setIcon(R.drawable.ic_search)
.show()

  1. RecyclerView 中的卡片引导

在 RecyclerView 中,你可以针对卡片或列表项的特定子视图设置引导目标。

获取卡片视图:

val card = mLinearLayoutManager.findViewByPosition(0) as LinearLayout
获取 ViewHolder 并设置引导:

if (card != null) {
val viewHolder = mRecyclerView.getChildViewHolder(card) as CardAdapter.ViewHolder
MaterialTapTargetPrompt.Builder(this)
.setTarget(viewHolder.mImageView)
.setClipToView(card.getChildAt(0))
.setPrimaryText(“这是一张卡片”)
.setSecondaryText(“点击查看更多内容”)
.show()
}

  1. 定位在屏幕中央的引导

当目标视图距离屏幕边缘超过 88dp 时,引导提示会自动调整位置,以不覆盖目标视图。

MaterialTapTargetPrompt.Builder(this)
.setTarget(targetView)
.setPrimaryText(“中心位置的引导”)
.show()

  1. 自定义文本样式

你可以使用 SpannableStringBuilder 自定义引导文本的样式,如改变文本颜色、背景等。

自定义主文本样式:

val primaryText = SpannableStringBuilder(“发送你的第一封邮件”)
val backgroundColour = BackgroundColorSpan(ContextCompat.getColor(this, R.color.colorAccent))
primaryText.setSpan(backgroundColour, 0, 4, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
自定义次文本样式:

val secondaryText = SpannableStringBuilder(“点击信封图标开始撰写你的第一封邮件”)
val foregroundColour = ForegroundColorSpan(ContextCompat.getColor(this, R.color.colorAccent))
secondaryText.setSpan(foregroundColour, 8, 15, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
应用自定义文本样式:

MaterialTapTargetPrompt.Builder(this)
.setTarget(targetView)
.setPrimaryText(primaryText)
.setSecondaryText(secondaryText)
.show()
通过上述示例,你可以灵活地在 Android 应用中实现不同场景下的功能引导,从简单的视图引导到复杂的 RecyclerView 卡片引导,再到自定义文本样式,这些都能极大地提升用户体验。

在 Jetpack Compose 中实现功能引导

随着 Android 开发逐渐向 Jetpack Compose 过渡,功能引导的实现也需要适应新的 UI 框架。intro-showcase-view 是一个专门为 Compose 设计的引导库,支持流畅的 Compose 风格的引导实现。

  • 选择 Jetpack Compose 的原因:Jetpack Compose 提供了更灵活、更强大的 UI 构建方式,使引导的设计和实现更加直观和高效。
  • 基于 intro-showcase-view 的实现:通过 intro-showcase-view,你可以快速创建一个引导,并与 Compose 组件无缝集成。
    在 Jetpack Compose 中,IntroShowcaseView 是一个非常方便的库,它可以帮助你快速创建功能引导。以下是如何在 Compose 中使用该库的示例。

引入依赖

首先,在 build.gradle 文件中添加以下依赖:

implementation ‘com.canopas.intro-showcase-view:introshowcaseview:’
示例代码

以下是一个使用 IntroShowcaseView 的完整示例,演示了如何在 Jetpack Compose 中创建一个功能引导:

@Composable
fun ShowcaseSample() {
var showAppIntro by remember {
mutableStateOf(true)
}

IntroShowcase(
    showIntroShowCase = showAppIntro,
    dismissOnClickOutside = false,
    onShowCaseCompleted = {
        // App Intro 完成后执行的操作
        showAppIntro = false
    },
) {
    FloatingActionButton(
        onClick = {},
        modifier = Modifier.introShowCaseTarget(
            index = 0,
            style = ShowcaseStyle.Default.copy(
                backgroundColor = Color(0xFF1C0A00), // 背景颜色
                backgroundAlpha = 0.98f, // 背景透明度
                targetCircleColor = Color.White // 目标圆圈的颜色
            ),
            content = {
                Column {
                    Text(
                        text = "检查邮件",
                        color = Color.White,
                        fontSize = 24.sp,
                        fontWeight = FontWeight.Bold
                    )
                    Text(
                        text = "点击这里检查/发送邮件",
                        color = Color.White,
                        fontSize = 16.sp
                    )
                    Spacer(modifier = Modifier.height(10.dp))
                    Icon(
                        painterResource(id = R.drawable.right_arrow),
                        contentDescription = null,
                        modifier = Modifier
                            .size(80.dp)
                            .align(Alignment.End),
                        tint = Color.White
                    )
                }
            }
        ),
        backgroundColor = ThemeColor,
        contentColor = Color.White,
        elevation = FloatingActionButtonDefaults.elevation(6.dp)
    ) {
        Icon(
            Icons.Filled.Email,
            contentDescription = "Email"
        )
    }
}

}
功能说明

  • IntroShowcase 是库中提供的主要组件,用于包裹需要引导的内容。
  • introShowCaseTarget 是扩展函数,用于设置引导的目标视图、样式和内容。
  • ShowcaseStyle 可以用于自定义引导的样式,例如背景颜色、透明度和目标圈颜色。
    通过 IntroShowcaseView,在 Jetpack Compose 中实现功能引导变得非常简单。这种方式不仅简化了开发流程,还为用户提供了直观的操作提示,提升了用户体验。示例代码:https://github.com/canopas/compose-intro-showcase/tree/master/app
  1. 自定义与高级应用

在许多情况下,默认的引导形式可能无法满足需求。此时,可以通过自定义来实现更复杂的引导场景。

  • 自定义形状与动画:MaterialTapTargetPrompt 提供了扩展接口,可以自定义引导的形状(如矩形、椭圆)和动画效果,使引导更符合应用的整体风格。
  • 根据应用场景定制引导:例如,在引导多个步骤的复杂流程时,确保每一步都与用户操作密切相关,并通过视觉提示引导用户完成整个流程。
  • 高级应用:在实现多步骤引导或处理复杂的用户场景时,可以结合条件判断、用户数据等实现更具针对性的引导体验。
    在使用 MaterialTapTargetPrompt 库时,除了默认的功能外,你还可以通过自定义 Builder、Shapes、Text 等组件,进一步增强功能引导的灵活性和可扩展性。以下内容将介绍如何进行这些自定义操作。
  1. 自定义 Builder

MaterialTapTargetPrompt 中的默认 Builder 实现继承自 PromptOptions,而 PromptOptions 提供了创建点击目标的通用功能。你可以扩展 PromptOptions 来实现自定义功能。

例如,以下自定义 Builder 在引导显示时,会将指定的键值存储为 true 到 SharedPreferences,并且只有在该键值为 false 时才会显示引导提示。

class CustomTapTargetPromptBuilder(context: Context) :
MaterialTapTargetPrompt.Builder(context) {

private val sharedPreferences = context.getSharedPreferences("MyPrefs", Context.MODE_PRIVATE)

fun setPreferenceKey(key: String): CustomTapTargetPromptBuilder {
    val shouldShow = sharedPreferences.getBoolean(key, false)
    if (!shouldShow) {
        this.setOnHidePromptListener {
            sharedPreferences.edit().putBoolean(key, true).apply()
        }
    } else {
        this.setPrimaryText("Prompt already shown")
    }
    return this
}

}
使用自定义 Builder:

CustomTapTargetPromptBuilder(this)
.setTarget(R.id.fab)
.setPrimaryText(“点击这里开始”)
.setPreferenceKey(“show_prompt_fab”)
.show()

  1. 自定义形状(Shapes)

默认情况下,MaterialTapTargetPrompt 使用圆形作为引导形状。不过,你可以通过扩展 PromptBackground 和 PromptFocal 类,渲染任何其他形状。例如,使用矩形作为引导背景。

new MaterialTapTargetPrompt.Builder(this)
.setTarget(view)
.setPrimaryText(“Different shapes”)
.setSecondaryText(“Extend PromptFocal or PromptBackground to change the shapes”)
.setPromptBackground(new RectanglePromptBackground())
.setPromptFocal(new RectanglePromptFocal())
.show();

  1. 自定义背景效果

可以通过设置 PromptBackground 来使背景变暗,从而突出引导目标。

builder.setPromptBackground(DimmedPromptBackground())
.setPrimaryText(“这是一个暗背景效果的引导”)
.show()
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.NonNull;
import android.util.DisplayMetrics;

import uk.co.samuelwall.materialtaptargetprompt.extras.PromptOptions;
import uk.co.samuelwall.materialtaptargetprompt.extras.backgrounds.CirclePromptBackground;

/**

  • Prompt background implementation that darkens behind the circle background.
    */
    public class DimmedPromptBackground extends CirclePromptBackground
    {
    @NonNull private RectF dimBounds = new RectF();
    @NonNull private Paint dimPaint; public DimmedPromptBackground()
    {
    dimPaint = new Paint();
    dimPaint.setColor(Color.BLACK);
    } @Override
    public void prepare(@NonNull final PromptOptions options, final boolean clipToBounds, @NonNull Rect clipBounds)
    {
    super.prepare(options, clipToBounds, clipBounds);
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    // Set the bounds to display as dimmed to the screen bounds
    dimBounds.set(0, 0, metrics.widthPixels, metrics.heightPixels);
    } @Override
    public void update(@NonNull final PromptOptions options, float revealModifier, float alphaModifier)
    {
    super.update(options, revealModifier, alphaModifier);
    // Allow for the dimmed background to fade in and out
    this.dimPaint.setAlpha((int) (200 * alphaModifier));
    } @Override
    public void draw(@NonNull Canvas canvas)
    {
    // Draw the dimmed background
    canvas.drawRect(this.dimBounds, this.dimPaint);
    // Draw the background
    super.draw(canvas);
    }
    }
  1. 自定义文本(Text)

MaterialTapTargetPrompt 中的文本由 PromptText 类渲染。大多数情况下,可以通过使用 SpannableStringBuilder 来实现文本内容和样式的更改。如果需要进一步自定义文本的布局和渲染方式,可以扩展 PromptText 类。

val primaryText = SpannableStringBuilder(“发送你的第一封邮件”)
primaryText.setSpan(
BackgroundColorSpan(ContextCompat.getColor(this, R.color.colorAccent)),
0, 4, Spanned.SPAN_INCLUSIVE_INCLUSIVE
)

val secondaryText = SpannableStringBuilder(“点击信封图标开始撰写邮件”)
secondaryText.setSpan(
ForegroundColorSpan(ContextCompat.getColor(this, R.color.colorAccent)),
8, 15, Spanned.SPAN_INCLUSIVE_INCLUSIVE
)

MaterialTapTargetPrompt.Builder(this)
.setTarget(R.id.fab)
.setPrimaryText(primaryText)
.setSecondaryText(secondaryText)
.show()
如果你需要更复杂的文本布局,可以扩展 PromptText 类,并通过 builder.setPromptText() 方法将自定义的文本处理类应用到引导中。

class CustomPromptText : PromptText() {
override fun draw(canvas: Canvas, paint: Paint, clipBounds: Rect, focalBounds: Rect) {
// 自定义文本绘制逻辑
}
}

MaterialTapTargetPrompt.Builder(this)
.setPromptText(CustomPromptText())
.setPrimaryText(“自定义文本布局”)
.show()
通过自定义 Builder、Shapes 和 Text,你可以为 Android 应用的功能引导添加更丰富、更个性化的功能。这种灵活性使得 MaterialTapTargetPrompt 成为一个强大而易用的工具,能够满足各种应用场景的需求。

  1. 性能优化与兼容性考虑

功能引导的性能优化和兼容性问题也是开发者需要关注的重点:

  • 性能影响分析:在引导显示过程中,动画、资源加载等可能会对性能产生影响,特别是在低端设备上。通过优化资源、减少不必要的动画,可以提升引导的流畅性。
  • 兼容性适配:由于 Android 设备和版本的多样性,在实现功能引导时需要考虑不同版本之间的兼容性问题,确保在所有目标设备上都能正常运行。
  1. 结束语

功能引导是提升用户体验的重要手段,随着 Android 开发环境的不断变化,引导的实现方式也在不断演进。本文介绍了在传统 View 系统与 Jetpack Compose 中实现功能引导的方法,并探讨了自定义引导、性能优化与兼容性问题。希望通过这些实践,开发者能够在未来的项目中更好地实现功能引导,提升应用的用户体验。

在实现功能引导的过程中,开发者应始终关注用户的实际需求,通过不断优化和改进,使引导成为用户与应用之间更加顺畅的桥梁。

这篇博客旨在为 Android 开发者提供全面的功能引导实现指南,从设计原则到技术实现,从自定义应用到性能优化,帮助开发者更好地掌握并应用功能引导技术。

参考

https://github.com/sjwall/MaterialTapTargetPrompt
https://sjwall.github.io/MaterialTapTargetPrompt
https://github.com/canopas/Intro-showcase-view
https://canopas.github.io/compose-intro-showcase/

声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/420119.html

(0)
联系我们
联系我们
分享本页
返回顶部