From 3b60a3b713858dd094c373104def5ae7c13de21f Mon Sep 17 00:00:00 2001 From: ZhanGSKen Date: Fri, 8 May 2026 19:35:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9EProtectModeTextView?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E6=8E=A7=E4=BB=B6=201.=20=E7=BB=A7?= =?UTF-8?q?=E6=89=BFLinearLayout=EF=BC=8C=E5=86=85=E7=BD=AETextView?= =?UTF-8?q?=E4=B8=8E0~12=E5=88=BB=E5=BA=A6SeekBar=202.=20=E5=88=BB?= =?UTF-8?q?=E5=BA=A60=E4=BF=9D=E6=8C=81=E5=8E=9F=E5=A7=8B=E6=96=87?= =?UTF-8?q?=E6=9C=AC=E4=B8=8D=E6=89=93=E4=B9=B1=EF=BC=8C1~12=E4=B8=BA?= =?UTF-8?q?=E6=AF=8F=E7=BB=84=E7=9B=B8=E9=82=BB=E5=AD=97=E7=AC=A6=E4=B8=AA?= =?UTF-8?q?=E6=95=B0=203.=20=E6=8C=89=E5=88=BB=E5=BA=A6=E5=9B=BA=E5=AE=9A?= =?UTF-8?q?=E9=95=BF=E5=BA=A6=E4=BB=8E=E5=A4=B4=E8=87=B3=E5=B0=BE=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E5=88=86=E7=BB=84=EF=BC=8C=E5=88=86=E7=BB=84=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E9=9A=8F=E6=9C=BA=E6=89=93=E4=B9=B1=E5=90=8E=E6=8B=BC?= =?UTF-8?q?=E6=8E=A5=E8=BE=93=E5=87=BA=204.=20=E6=94=AF=E6=8C=81=E5=90=AB?= =?UTF-8?q?=E7=A9=BA=E6=A0=BC/=E6=A0=87=E7=82=B9=E5=AE=8C=E6=95=B4?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E8=A7=A3=E6=9E=90=EF=BC=8C=E5=AF=B9=E5=A4=96?= =?UTF-8?q?=E6=8F=90=E4=BE=9BsetContentText=E8=AE=BE=E7=BD=AE=E6=96=87?= =?UTF-8?q?=E6=9C=AC=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mymessagemanager/build.properties | 4 +- .../unittest/UnitTestActivity.java | 14 +- .../views/ProtectModeTextView.java | 136 ++++++++++++++++++ .../src/main/res/layout/activity_unittest.xml | 70 +++++---- .../layout/layout_protect_mode_textview.xml | 22 +++ 5 files changed, 211 insertions(+), 35 deletions(-) create mode 100644 mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/ProtectModeTextView.java create mode 100644 mymessagemanager/src/main/res/layout/layout_protect_mode_textview.xml diff --git a/mymessagemanager/build.properties b/mymessagemanager/build.properties index 9e280bd..f0febc4 100644 --- a/mymessagemanager/build.properties +++ b/mymessagemanager/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Wed Feb 11 05:29:19 HKT 2026 +#Fri May 08 11:33:06 GMT 2026 stageCount=8 libraryProject= baseVersion=15.12 publishVersion=15.12.7 -buildCount=0 +buildCount=9 baseBetaVersion=15.12.8 diff --git a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/unittest/UnitTestActivity.java b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/unittest/UnitTestActivity.java index d34fd81..d405dfb 100644 --- a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/unittest/UnitTestActivity.java +++ b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/unittest/UnitTestActivity.java @@ -11,20 +11,29 @@ import android.view.View; import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogView; import cc.winboll.studio.mymessagemanager.R; +import cc.winboll.studio.mymessagemanager.views.ProtectModeTextView; public class UnitTestActivity extends Activity { public static final String TAG = "UnitTestActivity"; LogView mLogView; - + // 新增自定义控件 + ProtectModeTextView mProtectModeTv; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_unittest); - + mLogView = findViewById(R.id.logview); mLogView.start(); + + // 初始化ProtectModeTextView + mProtectModeTv = findViewById(R.id.protect_mode_tv); + // 设置测试文本,可自行修改 + String testText = "abcdefghijklmnopqrstuvwxyz消息管理 隐私保护 文本随机组合 滑动刻度测试1234567890"; + mProtectModeTv.setContentText(testText); } public void onMain(View view) { @@ -34,3 +43,4 @@ public class UnitTestActivity extends Activity { AddressUtils_Test.main(this); } } + diff --git a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/ProtectModeTextView.java b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/ProtectModeTextView.java new file mode 100644 index 0000000..003eb2a --- /dev/null +++ b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/ProtectModeTextView.java @@ -0,0 +1,136 @@ +package cc.winboll.studio.mymessagemanager.views; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.widget.LinearLayout; +import android.widget.SeekBar; +import android.widget.TextView; +import cc.winboll.studio.mymessagemanager.R; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +/** + * 保护模式自定义控件 + * 最终规则: + * 1. 刻度范围 0~12 + * 2. 刻度值 = 每一组截取【相邻字符个数】 + * 3. 从头到尾按固定长度切块分组 + * 4. 所有分组收集后随机打乱再拼接输出 + * 5. 刻度0 = 不打乱,显示原文 + * 6. 按原生字符计算(包含空格、标点) + */ +public class ProtectModeTextView extends LinearLayout { + + private TextView tvContent; + private SeekBar seekBarScale; + private String originText; + private List charAllList; + private final Random random = new Random(); + + public ProtectModeTextView(Context context) { + super(context); + initView(context); + } + + public ProtectModeTextView(Context context, AttributeSet attrs) { + super(context, attrs); + initView(context); + } + + public ProtectModeTextView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initView(context); + } + + private void initView(Context context) { + LayoutInflater.from(context).inflate(R.layout.layout_protect_mode_textview, this, true); + tvContent = findViewById(R.id.tv_content); + seekBarScale = findViewById(R.id.seek_bar_scale); + + // 刻度 0 ~ 12 + seekBarScale.setMax(12); + seekBarScale.setProgress(0); + + charAllList = new ArrayList<>(); + + seekBarScale.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + handleTextLogic(progress); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) {} + @Override + public void onStopTrackingTouch(SeekBar seekBar) {} + }); + } + + public void setContentText(String text) { + this.originText = text; + convertToCharList(text); + handleTextLogic(seekBarScale.getProgress()); + } + + private void convertToCharList(String text) { + charAllList.clear(); + if (text == null || text.isEmpty()) { + return; + } + char[] chars = text.toCharArray(); + for (char c : chars) { + charAllList.add(c); + } + } + + private void handleTextLogic(int groupSize) { + if (charAllList.isEmpty()) { + tvContent.setText(originText); + return; + } + + // 刻度0 原样不打乱 + if (groupSize <= 0) { + tvContent.setText(originText); + return; + } + + List groupList = new ArrayList<>(); + int totalLen = charAllList.size(); + + // 从头到尾 按 groupSize 个相邻字符切块 + int index = 0; + while (index < totalLen) { + StringBuilder sb = new StringBuilder(); + // 每一组取 groupSize 个相邻字符 + for (int i = 0; i < groupSize && index < totalLen; i++) { + sb.append(charAllList.get(index)); + index++; + } + groupList.add(sb.toString()); + } + + // 所有分组随机打乱 + Collections.shuffle(groupList, random); + + // 拼接输出 + StringBuilder result = new StringBuilder(); + for (String item : groupList) { + result.append(item); + } + + tvContent.setText(result.toString()); + } + + public String getOriginText() { + return originText; + } + + public void resetSeekBar() { + seekBarScale.setProgress(0); + } +} + diff --git a/mymessagemanager/src/main/res/layout/activity_unittest.xml b/mymessagemanager/src/main/res/layout/activity_unittest.xml index b37f8f1..6146c5f 100644 --- a/mymessagemanager/src/main/res/layout/activity_unittest.xml +++ b/mymessagemanager/src/main/res/layout/activity_unittest.xml @@ -1,44 +1,52 @@ + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> - + - + - + + -