简易安卓句分器实现

最近,我发现许多抖音用户喜欢将小说内容一句一句地发到游戏评论框中。这种行为虽然能让更多人看到这些内容,但手动复制和粘贴却是一个繁琐的过程。为了简化这一操作,我决定开发一个应用,可以一键输入大量文本,并将其根据句号、逗号和分号划分成句子。用户可以通过一个悬浮窗轻松访问上一句、当前句子和下一句,进一步简化操作。

在这个应用的开发过程中,我使用了 Android 的三个重要组件:FragmentViewModelView Binding。下面,我将详细介绍这三者的关系以及如何实现具体功能的代码。

1. Fragment

Fragment 是 Android UI 的一部分,可以被看作一个独立的界面模块。在应用中,多个 Fragment 可以在同一个 Activity 中共存,各自管理自己的 UI 和生命周期事件。在我们的应用中,HomeFragment 负责与用户交互,例如输入文本和处理按钮点击事件。

以下是 HomeFragment 的完整代码:

java 复制代码
package cn.techfanyi.ui.home;

import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;

import cn.techfanyi.databinding.FragmentHomeBinding;

public class HomeFragment extends Fragment {

    private FragmentHomeBinding binding;
    private HomeViewModel homeViewModel;

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        // 创建ViewModel
        homeViewModel = new ViewModelProvider(this).get(HomeViewModel.class);

        // 绑定视图
        binding = FragmentHomeBinding.inflate(inflater, container, false);
        View root = binding.getRoot();

        // 获取输入框和按钮
        EditText editText = binding.editText; // 假设在XML中有一个EditText用于输入
        Button recognizeButton = binding.recognizeButton; // 假设在XML中有一个按钮用于识别
        TextView resultTextView = binding.resultTextView; // 显示结果的TextView

        // 设置按钮点击事件
        recognizeButton.setOnClickListener(v -> {
            String inputText = editText.getText().toString();
            if (TextUtils.isEmpty(inputText)) {
                Toast.makeText(getContext(), "请输入文本", Toast.LENGTH_SHORT).show();
                return;
            }

            // 将输入的文本划分为句子
            String[] sentences = inputText.split("[。;,]");
            homeViewModel.setSentences(sentences); // 将句子存储到ViewModel中

            // 更新结果文本
            resultTextView.setText(TextUtils.join("\n", sentences));
        });

        return root;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }
}

2. ViewModel

ViewModel 是 Android 架构组件,用于存储和管理与 UI 相关的数据。其主要作用是持久化数据,使其能够在 FragmentActivity 的生命周期变化(如屏幕旋转)时依然可用。在我们的应用中,HomeViewModel 用于管理文本数据和句子划分的逻辑。

以下是 HomeViewModel 的代码:

java 复制代码
package cn.techfanyi.ui.home;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

public class HomeViewModel extends ViewModel {
    private final MutableLiveData<String[]> sentences;

    public HomeViewModel() {
        sentences = new MutableLiveData<>();
    }

    // 设置句子
    public void setSentences(String[] sentencesArray) {
        sentences.setValue(sentencesArray);
    }

    // 获取句子
    public LiveData<String[]> getSentences() {
        return sentences;
    }
}

3. View Binding

View Binding 是一种更安全和高效的方式来访问 XML 布局中的视图。它会为每个 XML 布局文件生成一个绑定类,可以直接通过绑定类访问布局中的视图,而无需手动调用 findViewById()

在本应用中,假设我们的布局文件为 fragment_home.xml,以下是示例 XML 布局代码:

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.home.HomeFragment">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入长句子" />

    <Button
        android:id="@+id/recognizeButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="识别句子"
        app:layout_constraintTop_toBottomOf="@id/editText"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

    <TextView
        android:id="@+id/resultTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/recognizeButton"
        android:padding="16dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

悬浮窗功能实现

悬浮窗的功能主要实现上一句、当前句子、下一句的展示与复制。为了实现这个功能,我们可以使用 WindowManager 来创建一个悬浮窗,并在其中显示相应的句子。

java 复制代码
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;

public class FloatingWindowManager {
    private Context context;
    private WindowManager windowManager;
    private View floatingView;
    private TextView previousSentenceTextView;
    private TextView currentSentenceTextView;
    private TextView nextSentenceTextView;

    public FloatingWindowManager(Context context) {
        this.context = context;
        windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        createFloatingView();
    }

    private void createFloatingView() {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        floatingView = inflater.inflate(R.layout.floating_window_layout, null);

        previousSentenceTextView = floatingView.findViewById(R.id.previousSentence);
        currentSentenceTextView = floatingView.findViewById(R.id.currentSentence);
        nextSentenceTextView = floatingView.findViewById(R.id.nextSentence);

        // 设置句子点击事件
        currentSentenceTextView.setOnClickListener(v -> {
            // 复制当前句子到剪贴板
            ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
            ClipData clip = ClipData.newPlainText("sentence", currentSentenceTextView.getText());
            clipboard.setPrimaryClip(clip);
        });

        // 添加悬浮窗
        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);
        params.gravity = Gravity.TOP | Gravity.LEFT; // 悬浮窗的位置
        params.x = 0;
        params.y = 100;

        windowManager.addView(floatingView, params);
    }

    public void updateSentences(String[] sentences, int currentIndex) {
        if (currentIndex > 0) {
            previousSentenceTextView.setText(sentences[currentIndex - 1]);
        }
        currentSentenceTextView.setText(sentences[currentIndex]);
        if (currentIndex < sentences.length - 1) {
            nextSentenceTextView.setText(sentences[currentIndex + 1]);
        }
    }
}

关系及绑定

在应用中,FragmentViewModelView Binding 之间的关系如下:

  • Fragment :负责管理 UI 和用户交互逻辑,通过 ViewModel 获取和存储数据,使用 View Binding 直接访问布局中的视图。
  • ViewModel:负责存储和管理与 UI 相关的数据,确保数据在生命周期变化时的持久性。
  • View Binding:简化了视图的访问,提高了代码的安全性和可读性。

总结

通过使用 FragmentViewModelView Binding,我们可以创建一个简化小说内容分享的应用。应用不仅提升了用户体验

,同时也展示了 Android 开发中这三者之间的紧密关系。希望这篇博客能够为你的 Android 开发之路提供一些启示!

相关推荐
yoyo_zzm7 分钟前
Laravel6.x新特性全解析
java·spring boot·后端
AIFarmer13 分钟前
【无标题】
开发语言·c++·算法
Nick_zcy19 分钟前
小说在线阅读网站和小说管理系统 · 功能全解析
java·后端·python·springboot·ruoyi
源码宝21 分钟前
基于 SpringBoot + Vue 的医院随访系统:技术架构与功能实现
java·vue.js·spring boot·架构·源码·随访系统·随访管理
昇腾CANN27 分钟前
TileLang-Ascend 算子性能优化方法与实操
开发语言·javascript·性能优化·昇腾·cann
AGV算法笔记34 分钟前
CVPR 2025 最新感知算法解读:GaussianLSS 如何用 Gaussian Splatting 重构 BEV 表示?
算法·重构·自动驾驶·3d视觉·感知算法·多视角视觉
沐知全栈开发38 分钟前
ionic 手势事件详解
开发语言
lsx2024061 小时前
Bootstrap 按钮
开发语言
qinqinzhang1 小时前
Java 中的 IoC、AOP、MVC
java
神仙别闹1 小时前
基于 Python 实现 BERT 的情感分析模型
开发语言·python·bert