Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
A
Android_Catering_service
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
姜天宇
Android_Catering_service
Commits
309f64be
Commit
309f64be
authored
Apr 30, 2025
by
姜天宇
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:增加纠错功能;学习页增加重置背景功能
parent
622bd51f
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
45 changed files
with
1291 additions
and
119 deletions
+1291
-119
proguard-rules.pro
app/proguard-rules.pro
+5
-0
USBCameraHelper.java
camera/src/main/java/com/jiangdg/uvc/USBCameraHelper.java
+5
-2
build.gradle
common/build.gradle
+2
-0
DrawerMenuAdapter.java
...in/java/com/wmdigit/common/adapter/DrawerMenuAdapter.java
+4
-3
BaseDiffRecyclerViewAdapter.java
...igit/common/base/adapter/BaseDiffRecyclerViewAdapter.java
+1
-1
BaseRecyclerViewAdapter.java
.../wmdigit/common/base/adapter/BaseRecyclerViewAdapter.java
+13
-8
BaseMessage.java
.../main/java/com/wmdigit/common/base/model/BaseMessage.java
+21
-0
BaseMvvmFragment.java
...n/java/com/wmdigit/common/base/mvvm/BaseMvvmFragment.java
+12
-0
MessageType.java
...n/src/main/java/com/wmdigit/common/enums/MessageType.java
+21
-0
ProductsVO.java
...on/src/main/java/com/wmdigit/common/model/ProductsVO.java
+38
-0
EnglishAndNumberKeyboard.java
...mdigit/common/view/keyboard/EnglishAndNumberKeyboard.java
+14
-1
ic_switch.png
common/src/main/res/drawable/ic_switch.png
+0
-0
layout_english_number_keyboard.xml
...on/src/main/res/layout/layout_english_number_keyboard.xml
+14
-2
strings.xml
common/src/main/res/values/strings.xml
+12
-1
CMakeLists.txt
core/src/main/cpp/CMakeLists.txt
+6
-0
features_hnsw.cpp
core/src/main/cpp/features_hnsw.cpp
+27
-0
TargetDetectionRepository.java
.../com/wmdigit/core/catering/TargetDetectionRepository.java
+65
-22
Hnsw.java
core/src/main/java/com/wmdigit/core/hnsw/Hnsw.java
+16
-0
HnswRepository.java
core/src/main/java/com/wmdigit/core/hnsw/HnswRepository.java
+11
-2
VideoPipeRepository.java
.../java/com/wmdigit/core/videopipe/VideoPipeRepository.java
+2
-0
FeaturesDao.java
.../main/java/com/wmdigit/data/database/dao/FeaturesDao.java
+16
-0
ProductsDao.java
.../main/java/com/wmdigit/data/database/dao/ProductsDao.java
+16
-0
ProductAndImgPathsPO.java
...om/wmdigit/data/database/entity/ProductAndImgPathsPO.java
+100
-0
FeaturesMapper.java
...java/com/wmdigit/data/database/mapper/FeaturesMapper.java
+1
-1
ProductsMapper.java
...java/com/wmdigit/data/database/mapper/ProductsMapper.java
+31
-0
FeaturesRepository.java
.../wmdigit/data/database/repository/FeaturesRepository.java
+27
-0
ProductsRepository.java
.../wmdigit/data/database/repository/ProductsRepository.java
+10
-0
history.txt
history.txt
+3
-0
SettingActivity.java
...ng/src/main/java/com/wmdigit/setting/SettingActivity.java
+3
-4
FuncButtonAdapter.java
...n/java/com/wmdigit/setting/adapter/FuncButtonAdapter.java
+3
-3
LocalImageAdapter.java
...n/java/com/wmdigit/setting/adapter/LocalImageAdapter.java
+63
-0
ProductsAdapter.java
...ain/java/com/wmdigit/setting/adapter/ProductsAdapter.java
+130
-13
LocalImageDiffUtil.java
.../com/wmdigit/setting/adapter/diff/LocalImageDiffUtil.java
+28
-0
ProductsDiffUtil.java
...va/com/wmdigit/setting/adapter/diff/ProductsDiffUtil.java
+21
-1
DataLearningFragment.java
...va/com/wmdigit/setting/fragment/DataLearningFragment.java
+117
-13
DelAllFeaturesByProductCodeMessage.java
...git/setting/model/DelAllFeaturesByProductCodeMessage.java
+25
-0
DelOneFeatureByPathMessage.java
...com/wmdigit/setting/model/DelOneFeatureByPathMessage.java
+15
-0
LocalImage.java
...g/src/main/java/com/wmdigit/setting/model/LocalImage.java
+23
-0
DataLearningViewModel.java
.../com/wmdigit/setting/viewmodel/DataLearningViewModel.java
+210
-30
SettingViewModel.java
.../java/com/wmdigit/setting/viewmodel/SettingViewModel.java
+36
-3
activity_setting.xml
module-setting/src/main/res/layout/activity_setting.xml
+35
-3
fragment_data_learning.xml
...le-setting/src/main/res/layout/fragment_data_learning.xml
+12
-6
layout_learning_correction_item.xml
...g/src/main/res/layout/layout_learning_correction_item.xml
+52
-0
layout_local_image_item.xml
...e-setting/src/main/res/layout/layout_local_image_item.xml
+22
-0
strings.xml
module-setting/src/main/res/values/strings.xml
+3
-0
No files found.
app/proguard-rules.pro
View file @
309f64be
-
keepattributes
*
Annotation
*
-
keepclassmembers
class
**
{
@
org
.
greenrobot
.
eventbus
.
Subscribe
<
methods
>
;
}
-
keep
enum
org
.
greenrobot
.
eventbus
.
ThreadMode
{
*
;
}
\ No newline at end of file
camera/src/main/java/com/jiangdg/uvc/USBCameraHelper.java
View file @
309f64be
...
@@ -68,13 +68,16 @@ public class USBCameraHelper {
...
@@ -68,13 +68,16 @@ public class USBCameraHelper {
synchronized
(
mSyncFrame
)
{
synchronized
(
mSyncFrame
)
{
count
++;
count
++;
int
len
=
buffer
.
capacity
();
int
len
=
buffer
.
capacity
();
if
(
frame
!=
null
){
frame
=
null
;
}
frame
=
new
byte
[
len
];
frame
=
new
byte
[
len
];
buffer
.
get
(
frame
);
buffer
.
get
(
frame
);
if
(
count
%
frameInterval
==
0
){
if
(
count
%
frameInterval
==
0
){
count
=
0
;
count
=
0
;
if
(
onImageAnalyzeListener
!=
null
){
if
(
onImageAnalyzeListener
!=
null
){
onImageAnalyzeListener
.
onAnalyzed
(
encodeYuvToJpeg
(
frame
,
640
,
480
,
ImageFormat
.
NV21
));
//
onImageAnalyzeListener.onAnalyzed(encodeYuvToJpeg(frame, 640, 480, ImageFormat.NV21));
//
onImageAnalyzeListener.onAnalyzed(nv21ToBitmap.nv21ToBitmap(frame, 640, 480));
onImageAnalyzeListener
.
onAnalyzed
(
nv21ToBitmap
.
nv21ToBitmap
(
frame
,
640
,
480
));
// onImageAnalyzeListener.onAnalyzed(BitmapFactory.decodeByteArray(frame, 0, frame.length));
// onImageAnalyzeListener.onAnalyzed(BitmapFactory.decodeByteArray(frame, 0, frame.length));
}
}
}
}
...
...
common/build.gradle
View file @
309f64be
...
@@ -89,5 +89,7 @@ dependencies {
...
@@ -89,5 +89,7 @@ dependencies {
api
'androidx.drawerlayout:drawerlayout:1.2.0'
api
'androidx.drawerlayout:drawerlayout:1.2.0'
api
'com.github.jenly1314.AppUpdater:app-updater:1.2.0'
api
'com.github.jenly1314.AppUpdater:app-updater:1.2.0'
// eventbus
api
'org.greenrobot:eventbus:3.1.1'
}
}
\ No newline at end of file
common/src/main/java/com/wmdigit/common/adapter/DrawerMenuAdapter.java
View file @
309f64be
...
@@ -20,7 +20,7 @@ import java.util.List;
...
@@ -20,7 +20,7 @@ import java.util.List;
* 抽屉菜单适配器
* 抽屉菜单适配器
* @author dizi
* @author dizi
*/
*/
public
class
DrawerMenuAdapter
extends
BaseDiffRecyclerViewAdapter
<
DrawerMenu
Adapter
.
DrawerMenuViewHolder
,
DrawerMenu
ItemVO
,
DrawerMenuDiffUtils
>
{
public
class
DrawerMenuAdapter
extends
BaseDiffRecyclerViewAdapter
<
DrawerMenuItemVO
,
DrawerMenuDiffUtils
>
{
public
DrawerMenuAdapter
(
Context
mContext
,
List
<
DrawerMenuItemVO
>
mList
)
{
public
DrawerMenuAdapter
(
Context
mContext
,
List
<
DrawerMenuItemVO
>
mList
)
{
super
(
mContext
,
mList
);
super
(
mContext
,
mList
);
...
@@ -32,12 +32,13 @@ public class DrawerMenuAdapter extends BaseDiffRecyclerViewAdapter<DrawerMenuAda
...
@@ -32,12 +32,13 @@ public class DrawerMenuAdapter extends BaseDiffRecyclerViewAdapter<DrawerMenuAda
}
}
@Override
@Override
protected
int
get
ItemLayoutResId
(
)
{
protected
int
get
LayoutResIdByViewType
(
int
viewType
)
{
return
R
.
layout
.
item_navi_menu
;
return
R
.
layout
.
item_navi_menu
;
}
}
@Override
@Override
protected
DrawerMenuViewHolder
createViewHolder
(
View
itemView
,
BaseViewHolder
.
OnItemClickListener
onItemClickListener
)
{
protected
DrawerMenuViewHolder
createViewHolder
(
View
itemView
,
BaseViewHolder
.
OnItemClickListener
onItemClickListener
,
int
viewType
)
{
return
new
DrawerMenuViewHolder
(
itemView
,
onItemClickListener
);
return
new
DrawerMenuViewHolder
(
itemView
,
onItemClickListener
);
}
}
...
...
common/src/main/java/com/wmdigit/common/base/adapter/BaseDiffRecyclerViewAdapter.java
View file @
309f64be
...
@@ -16,7 +16,7 @@ import java.util.List;
...
@@ -16,7 +16,7 @@ import java.util.List;
* 带有数据比较器的RecyclerView适配器
* 带有数据比较器的RecyclerView适配器
* @author dizi
* @author dizi
*/
*/
public
abstract
class
BaseDiffRecyclerViewAdapter
<
VH
extends
BaseViewHolder
<
T
>,
T
extends
BaseDiffUtilModel
,
DF
extends
BaseDiffUtil
<
T
>>
extends
BaseRecyclerViewAdapter
<
VH
,
T
>{
public
abstract
class
BaseDiffRecyclerViewAdapter
<
T
extends
BaseDiffUtilModel
,
DF
extends
BaseDiffUtil
<
T
>>
extends
BaseRecyclerViewAdapter
<
T
>{
/**
/**
* 旧的数据源
* 旧的数据源
*/
*/
...
...
common/src/main/java/com/wmdigit/common/base/adapter/BaseRecyclerViewAdapter.java
View file @
309f64be
...
@@ -16,7 +16,7 @@ import java.util.List;
...
@@ -16,7 +16,7 @@ import java.util.List;
* 基础列表适配器
* 基础列表适配器
* @author dizi
* @author dizi
*/
*/
public
abstract
class
BaseRecyclerViewAdapter
<
VH
extends
BaseViewHolder
<
T
>,
T
>
extends
RecyclerView
.
Adapter
<
VH
>
{
public
abstract
class
BaseRecyclerViewAdapter
<
T
>
extends
RecyclerView
.
Adapter
<
BaseViewHolder
<
T
>
>
{
protected
Context
mContext
;
protected
Context
mContext
;
/**
/**
...
@@ -39,13 +39,13 @@ public abstract class BaseRecyclerViewAdapter<VH extends BaseViewHolder<T>, T> e
...
@@ -39,13 +39,13 @@ public abstract class BaseRecyclerViewAdapter<VH extends BaseViewHolder<T>, T> e
@NonNull
@NonNull
@Override
@Override
public
VH
onCreateViewHolder
(
@NonNull
ViewGroup
parent
,
int
viewType
)
{
public
BaseViewHolder
<
T
>
onCreateViewHolder
(
@NonNull
ViewGroup
parent
,
int
viewType
)
{
View
itemView
=
LayoutInflater
.
from
(
mContext
).
inflate
(
get
ItemLayoutResId
(
),
parent
,
false
);
View
itemView
=
LayoutInflater
.
from
(
mContext
).
inflate
(
get
LayoutResIdByViewType
(
viewType
),
parent
,
false
);
return
createViewHolder
(
itemView
,
mOnItemClickListener
);
return
createViewHolder
(
itemView
,
mOnItemClickListener
,
viewType
);
}
}
@Override
@Override
public
void
onBindViewHolder
(
@NonNull
VH
holder
,
int
position
)
{
public
void
onBindViewHolder
(
@NonNull
BaseViewHolder
<
T
>
holder
,
int
position
)
{
T
item
=
mList
.
get
(
position
);
T
item
=
mList
.
get
(
position
);
holder
.
bind
(
item
);
holder
.
bind
(
item
);
}
}
...
@@ -60,11 +60,16 @@ public abstract class BaseRecyclerViewAdapter<VH extends BaseViewHolder<T>, T> e
...
@@ -60,11 +60,16 @@ public abstract class BaseRecyclerViewAdapter<VH extends BaseViewHolder<T>, T> e
}
}
}
}
public
void
setData
(
List
<
T
>
mList
)
{
this
.
mList
=
mList
;
}
/**
/**
* 获取item的布局ID
* 根据viewType获取对应布局
* @param viewType
* @return
* @return
*/
*/
protected
abstract
int
get
ItemLayoutResId
(
);
protected
abstract
int
get
LayoutResIdByViewType
(
int
viewType
);
/**
/**
* 由子类new出ViewHolder
* 由子类new出ViewHolder
...
@@ -72,5 +77,5 @@ public abstract class BaseRecyclerViewAdapter<VH extends BaseViewHolder<T>, T> e
...
@@ -72,5 +77,5 @@ public abstract class BaseRecyclerViewAdapter<VH extends BaseViewHolder<T>, T> e
* @param onItemClickListener
* @param onItemClickListener
* @return
* @return
*/
*/
protected
abstract
VH
createViewHolder
(
View
itemView
,
BaseViewHolder
.
OnItemClickListener
onItemClickListener
);
protected
abstract
BaseViewHolder
<
T
>
createViewHolder
(
View
itemView
,
BaseViewHolder
.
OnItemClickListener
onItemClickListener
,
int
viewType
);
}
}
common/src/main/java/com/wmdigit/common/base/model/BaseMessage.java
0 → 100644
View file @
309f64be
package
com
.
wmdigit
.
common
.
base
.
model
;
import
com.wmdigit.common.enums.MessageType
;
/**
* EventBus得消息基类
* @author dizi
*/
public
class
BaseMessage
<
T
>{
private
MessageType
type
;
private
T
payload
;
public
BaseMessage
(
MessageType
type
,
T
payload
)
{
this
.
type
=
type
;
this
.
payload
=
payload
;
}
public
T
getPayload
()
{
return
payload
;
}
}
common/src/main/java/com/wmdigit/common/base/mvvm/BaseMvvmFragment.java
View file @
309f64be
...
@@ -88,6 +88,18 @@ public abstract class BaseMvvmFragment<VM extends BaseViewModel, DB extends View
...
@@ -88,6 +88,18 @@ public abstract class BaseMvvmFragment<VM extends BaseViewModel, DB extends View
});
});
}
}
/**
* 从当前活动中获取共享的ViewModel实例
* 该方法使用泛型来允许获取不同类型的ViewModel,但要求这些类型继承自BaseViewModel
* 通过在活动级别共享ViewModel,确保在活动内的各个片段间共享数据
*
* @param viewModelClass ViewModel类的类型,用于指定所需ViewModel的具体类型
* @return 返回指定类型的ViewModel实例,该实例在当前活动中共享
*/
protected
<
AVM
extends
BaseViewModel
>
AVM
getSharedViewModelFromActivity
(
Class
<
AVM
>
viewModelClass
){
return
new
ViewModelProvider
(
requireActivity
()).
get
(
viewModelClass
);
}
/**
/**
* 初始化View
* 初始化View
*/
*/
...
...
common/src/main/java/com/wmdigit/common/enums/MessageType.java
0 → 100644
View file @
309f64be
package
com
.
wmdigit
.
common
.
enums
;
/**
* EventBus得消息类型枚举
* @author dizi
*/
public
enum
MessageType
{
/**
* 展示大图
*/
SHOW_LARGE_IMAGE
,
/**
* 通过图片路径删除一个向量
*/
DEL_ONE_FEATURE_BY_PATH
,
/**
* 通过商品编码删除所有向量
*/
DEL_ALL_FEATURES_BY_PRODUCT_CODE
}
common/src/main/java/com/wmdigit/common/model/ProductsVO.java
View file @
309f64be
...
@@ -4,11 +4,20 @@ import androidx.annotation.NonNull;
...
@@ -4,11 +4,20 @@ import androidx.annotation.NonNull;
import
com.wmdigit.common.base.diffutil.BaseDiffUtilModel
;
import
com.wmdigit.common.base.diffutil.BaseDiffUtilModel
;
import
java.util.List
;
/**
/**
* 商品信息
* 商品信息
* @author dizi
* @author dizi
*/
*/
public
class
ProductsVO
extends
BaseDiffUtilModel
{
public
class
ProductsVO
extends
BaseDiffUtilModel
{
/**
* layout类型
* 0-商品列表layout
* 1-学习记录layout
*/
private
int
layoutType
;
/**
/**
* 品名
* 品名
*/
*/
...
@@ -29,9 +38,14 @@ public class ProductsVO extends BaseDiffUtilModel {
...
@@ -29,9 +38,14 @@ public class ProductsVO extends BaseDiffUtilModel {
* 是否被选中
* 是否被选中
*/
*/
private
Boolean
isChecked
;
private
Boolean
isChecked
;
/**
* 图片路径
*/
private
List
<
String
>
imgPathList
;
public
ProductsVO
()
{
public
ProductsVO
()
{
isChecked
=
false
;
isChecked
=
false
;
layoutType
=
0
;
}
}
public
ProductsVO
(
String
productName
,
String
productCode
,
String
productMnemonicCode
,
String
unitPrice
)
{
public
ProductsVO
(
String
productName
,
String
productCode
,
String
productMnemonicCode
,
String
unitPrice
)
{
...
@@ -42,6 +56,14 @@ public class ProductsVO extends BaseDiffUtilModel {
...
@@ -42,6 +56,14 @@ public class ProductsVO extends BaseDiffUtilModel {
this
.
isChecked
=
false
;
this
.
isChecked
=
false
;
}
}
public
int
getLayoutType
()
{
return
layoutType
;
}
public
void
setLayoutType
(
int
layoutType
)
{
this
.
layoutType
=
layoutType
;
}
public
boolean
isChecked
()
{
public
boolean
isChecked
()
{
return
isChecked
;
return
isChecked
;
}
}
...
@@ -82,6 +104,22 @@ public class ProductsVO extends BaseDiffUtilModel {
...
@@ -82,6 +104,22 @@ public class ProductsVO extends BaseDiffUtilModel {
this
.
unitPrice
=
unitPrice
;
this
.
unitPrice
=
unitPrice
;
}
}
public
Boolean
getChecked
()
{
return
isChecked
;
}
public
void
setChecked
(
Boolean
checked
)
{
isChecked
=
checked
;
}
public
List
<
String
>
getImgPathList
()
{
return
imgPathList
;
}
public
void
setImgPathList
(
List
<
String
>
imgPathArray
)
{
this
.
imgPathList
=
imgPathArray
;
}
@NonNull
@NonNull
@Override
@Override
public
String
toString
()
{
public
String
toString
()
{
...
...
common/src/main/java/com/wmdigit/common/view/keyboard/EnglishAndNumberKeyboard.java
View file @
309f64be
...
@@ -31,7 +31,7 @@ public class EnglishAndNumberKeyboard extends ConstraintLayout {
...
@@ -31,7 +31,7 @@ public class EnglishAndNumberKeyboard extends ConstraintLayout {
private
TextView
key0
,
key1
,
key2
,
key3
,
key4
,
key5
,
key6
,
key7
,
key8
,
key9
,
keyPoint
;
private
TextView
key0
,
key1
,
key2
,
key3
,
key4
,
key5
,
key6
,
key7
,
key8
,
key9
,
keyPoint
;
private
ConstraintLayout
clEnglishKeyboard
,
clNumberKeyboard
;
private
ConstraintLayout
clEnglishKeyboard
,
clNumberKeyboard
;
private
TextView
keySwitch123
,
keySwitchAbc
;
private
TextView
keySwitch123
,
keySwitchAbc
;
private
TextView
tvKeywords
,
tvKeywordsHint
,
tvClear
,
tvReDetect
,
tvSave
;
private
TextView
tvKeywords
,
tvKeywordsHint
,
tvClear
,
tvReDetect
,
tvSave
,
tvResetEmptyBackground
;
private
static
InverseBindingListener
inverseBindingListener
;
private
static
InverseBindingListener
inverseBindingListener
;
...
@@ -146,6 +146,12 @@ public class EnglishAndNumberKeyboard extends ConstraintLayout {
...
@@ -146,6 +146,12 @@ public class EnglishAndNumberKeyboard extends ConstraintLayout {
onKeyboardClickListener
.
onClickSave
();
onKeyboardClickListener
.
onClickSave
();
}
}
});
});
// 重置背景
tvResetEmptyBackground
.
setOnClickListener
(
v
->
{
if
(
onKeyboardClickListener
!=
null
){
onKeyboardClickListener
.
onClickResetEmptyBackground
();
}
});
}
}
private
void
initView
(){
private
void
initView
(){
...
@@ -199,6 +205,7 @@ public class EnglishAndNumberKeyboard extends ConstraintLayout {
...
@@ -199,6 +205,7 @@ public class EnglishAndNumberKeyboard extends ConstraintLayout {
tvClear
=
findViewById
(
R
.
id
.
tv_clear
);
tvClear
=
findViewById
(
R
.
id
.
tv_clear
);
tvReDetect
=
findViewById
(
R
.
id
.
tv_re_detect
);
tvReDetect
=
findViewById
(
R
.
id
.
tv_re_detect
);
tvSave
=
findViewById
(
R
.
id
.
tv_save
);
tvSave
=
findViewById
(
R
.
id
.
tv_save
);
tvResetEmptyBackground
=
findViewById
(
R
.
id
.
tv_reset_empty_background
);
}
}
public
void
setKeywords
(
String
keywords
){
public
void
setKeywords
(
String
keywords
){
...
@@ -260,6 +267,11 @@ public class EnglishAndNumberKeyboard extends ConstraintLayout {
...
@@ -260,6 +267,11 @@ public class EnglishAndNumberKeyboard extends ConstraintLayout {
* 键盘按钮点击监听
* 键盘按钮点击监听
*/
*/
public
interface
OnKeyboardClickListener
{
public
interface
OnKeyboardClickListener
{
/**
* 点击重置背景
*/
void
onClickResetEmptyBackground
();
/**
/**
* 点击重新识别
* 点击重新识别
*/
*/
...
@@ -269,5 +281,6 @@ public class EnglishAndNumberKeyboard extends ConstraintLayout {
...
@@ -269,5 +281,6 @@ public class EnglishAndNumberKeyboard extends ConstraintLayout {
* 点击保存
* 点击保存
*/
*/
void
onClickSave
();
void
onClickSave
();
}
}
}
}
common/src/main/res/drawable/ic_switch.png
0 → 100644
View file @
309f64be
3.83 KB
common/src/main/res/layout/layout_english_number_keyboard.xml
View file @
309f64be
...
@@ -72,13 +72,25 @@
...
@@ -72,13 +72,25 @@
style=
"@style/text_base.keyboard_button.red"
style=
"@style/text_base.keyboard_button.red"
android:text=
"@string/empty"
android:text=
"@string/empty"
android:textSize=
"@dimen/sp_32"
android:textSize=
"@dimen/sp_32"
app:layout_constraintEnd_toStartOf=
"@+id/tv_re
_detect
"
app:layout_constraintEnd_toStartOf=
"@+id/tv_re
set_empty_background
"
app:layout_constraintStart_toEndOf=
"@+id/gl_v_40"
app:layout_constraintStart_toEndOf=
"@+id/gl_v_40"
app:layout_constraintTop_toTopOf=
"@+id/cl_search"
app:layout_constraintTop_toTopOf=
"@+id/cl_search"
app:layout_constraintBottom_toBottomOf=
"@+id/cl_search"
app:layout_constraintBottom_toBottomOf=
"@+id/cl_search"
app:layout_constraintHorizontal_bias=
"0.5"
app:layout_constraintHorizontal_bias=
"0.5"
/>
/>
<!--重设背景-->
<TextView
android:id=
"@+id/tv_reset_empty_background"
style=
"@style/text_base.keyboard_button"
android:text=
"@string/re_take_empty_background_photo"
android:textSize=
"@dimen/sp_32"
app:layout_constraintStart_toEndOf=
"@+id/tv_clear"
app:layout_constraintEnd_toStartOf=
"@+id/tv_re_detect"
app:layout_constraintTop_toTopOf=
"@+id/cl_search"
app:layout_constraintBottom_toBottomOf=
"@+id/cl_search"
app:layout_constraintHorizontal_bias=
"0.5"
/>
<!--重新识别-->
<!--重新识别-->
<TextView
<TextView
android:id=
"@+id/tv_re_detect"
android:id=
"@+id/tv_re_detect"
...
@@ -86,7 +98,7 @@
...
@@ -86,7 +98,7 @@
android:text=
"@string/re_detect"
android:text=
"@string/re_detect"
android:textSize=
"@dimen/sp_32"
android:textSize=
"@dimen/sp_32"
app:layout_constraintEnd_toStartOf=
"@+id/tv_save"
app:layout_constraintEnd_toStartOf=
"@+id/tv_save"
app:layout_constraintStart_toEndOf=
"@+id/tv_
clear
"
app:layout_constraintStart_toEndOf=
"@+id/tv_
reset_empty_background
"
app:layout_constraintTop_toTopOf=
"@+id/cl_search"
app:layout_constraintTop_toTopOf=
"@+id/cl_search"
app:layout_constraintBottom_toBottomOf=
"@+id/cl_search"
app:layout_constraintBottom_toBottomOf=
"@+id/cl_search"
app:layout_constraintHorizontal_bias=
"0.5"
app:layout_constraintHorizontal_bias=
"0.5"
...
...
common/src/main/res/values/strings.xml
View file @
309f64be
...
@@ -27,7 +27,11 @@
...
@@ -27,7 +27,11 @@
<string
name=
"save"
>
保存
</string>
<string
name=
"save"
>
保存
</string>
<string
name=
"camera_opening"
>
相机启动中…
</string>
<string
name=
"camera_opening"
>
相机启动中…
</string>
<string
name=
"camera_open_error"
>
相机启动异常
</string>
<string
name=
"camera_open_error"
>
相机启动异常
</string>
<string
name=
"please_select_correct_goods_for_every_rect"
>
请为照片中的每个框对应正确的商品
</string>
<string
name=
"camera_not_open"
>
摄像头未启动
</string>
<string
name=
"please_select_correct_goods_for_every_rect"
>
请为照片中的每个框指定正确的商品
</string>
<string
name=
"re_take_empty_background_photo"
>
重置背景
</string>
<string
name=
"describe_re_take_empty_background_photo"
>
重置前,请确保移走摄像头画面中的所有物体
</string>
<string
name=
"reset_empty_background_successful"
>
背景设置成功
</string>
<string
name=
"key_1"
>
1
</string>
<string
name=
"key_1"
>
1
</string>
<string
name=
"key_2"
>
2
</string>
<string
name=
"key_2"
>
2
</string>
...
@@ -71,6 +75,10 @@
...
@@ -71,6 +75,10 @@
<string
name=
"key_delete_1"
>
←
</string>
<string
name=
"key_delete_1"
>
←
</string>
<string
name=
"key_delete_2"
>
退格
</string>
<string
name=
"key_delete_2"
>
退格
</string>
<string
name=
"product_list"
>
商品列表
</string>
<string
name=
"learning_records"
>
学习记录
</string>
<string
name=
"switch_to_error_correction_mode"
>
纠错模式
</string>
<string
name=
"switch_to_learning_mode"
>
学习模式
</string>
<string
name=
"no_data"
>
暂无数据
</string>
<string
name=
"no_data"
>
暂无数据
</string>
<string
name=
"previous_page"
>
上一页
</string>
<string
name=
"previous_page"
>
上一页
</string>
<string
name=
"next_page"
>
下一页
</string>
<string
name=
"next_page"
>
下一页
</string>
...
@@ -83,4 +91,7 @@
...
@@ -83,4 +91,7 @@
<string
name=
"title_download_remote_tool"
>
下载远程工具
</string>
<string
name=
"title_download_remote_tool"
>
下载远程工具
</string>
<string
name=
"confirm_download_remote_tool"
>
请确认是否下载远程工具
</string>
<string
name=
"confirm_download_remote_tool"
>
请确认是否下载远程工具
</string>
<string
name=
"upgrade_progress"
>
下载进度:
</string>
<string
name=
"upgrade_progress"
>
下载进度:
</string>
<string
name=
"delete_success"
>
删除成功
</string>
<string
name=
"delete_failed_empty_product_code"
>
删除失败,商品编码为空
</string>
</resources>
</resources>
\ No newline at end of file
core/src/main/cpp/CMakeLists.txt
View file @
309f64be
...
@@ -210,7 +210,9 @@ target_link_libraries(
...
@@ -210,7 +210,9 @@ target_link_libraries(
clsretri
clsretri
detfea
detfea
c++_shared
c++_shared
-Wl,--whole-archive
wmai
wmai
-Wl,--no-whole-archive
opencv
opencv
image_tools
image_tools
${
log-lib
}
${
log-lib
}
...
@@ -232,7 +234,11 @@ target_link_libraries(
...
@@ -232,7 +234,11 @@ target_link_libraries(
clsretri_plate
clsretri_plate
detfea_color
detfea_color
c++_shared
c++_shared
-Wl,--whole-archive
wmai
wmai
-Wl,--no-whole-archive
opencv
opencv
image_tools
image_tools
${
log-lib
}
${
log-lib
}
...
...
core/src/main/cpp/features_hnsw.cpp
View file @
309f64be
...
@@ -132,4 +132,31 @@ float calculateSimilar(const float v1[], const float v2[], int size) {
...
@@ -132,4 +132,31 @@ float calculateSimilar(const float v1[], const float v2[], int size) {
}
}
if
(
mod1
==
0
||
mod2
==
0
)
return
0
;
if
(
mod1
==
0
||
mod2
==
0
)
return
0
;
return
(
ret
/
sqrt
(
mod1
)
/
sqrt
(
mod2
)
+
1
)
/
2.0
;
return
(
ret
/
sqrt
(
mod1
)
/
sqrt
(
mod2
)
+
1
)
/
2.0
;
}
extern
"C"
JNIEXPORT
jint
JNICALL
Java_com_wmdigit_core_hnsw_Hnsw_deleteByRowId
(
JNIEnv
*
env
,
jobject
thiz
,
jlong
row_id
)
{
int
temp_row_id
=
-
1
;
if
(
vector
.
empty
()
||
idx
==
nullptr
){
return
temp_row_id
;
}
// 遍历删除对应索引
for
(
auto
it
=
vector
.
begin
();
it
!=
vector
.
end
();)
{
if
(
it
->
first
==
row_id
){
it
=
vector
.
erase
(
it
);
temp_row_id
=
row_id
;
idx
->
Removesample
(
temp_row_id
);
LOGD
(
"删除了%d"
,
temp_row_id
);
break
;
}
else
{
it
++
;
}
}
// idx为空,删除
if
(
idx
->
get_cur_element_count
()
==
0
){
Java_com_wmdigit_core_hnsw_Hnsw_deleteAllSample
(
env
,
thiz
);
}
return
temp_row_id
;
}
}
\ No newline at end of file
core/src/main/java/com/wmdigit/core/catering/TargetDetectionRepository.java
View file @
309f64be
package
com
.
wmdigit
.
core
.
catering
;
package
com
.
wmdigit
.
core
.
catering
;
import
android.annotation.SuppressLint
;
import
android.graphics.Bitmap
;
import
android.graphics.Bitmap
;
import
android.graphics.Canvas
;
import
android.graphics.Canvas
;
import
android.graphics.Color
;
import
android.graphics.Color
;
import
android.graphics.Paint
;
import
android.graphics.Paint
;
import
com.elvishew.xlog.XLog
;
import
com.wmdigit.common.model.CropValueDTO
;
import
com.wmdigit.common.model.CropValueDTO
;
import
com.wmdigit.core.catering.dish.DishDetection
;
import
com.wmdigit.core.catering.dish.DishDetection
;
import
com.wmdigit.core.catering.model.TargetDetectResult
;
import
com.wmdigit.core.catering.model.TargetDetectResult
;
...
@@ -16,10 +18,16 @@ import com.wmdigit.data.mmkv.repository.CropLocalRepository;
...
@@ -16,10 +18,16 @@ import com.wmdigit.data.mmkv.repository.CropLocalRepository;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.atomic.AtomicBoolean
;
import
io.reactivex.Completable
;
import
io.reactivex.CompletableObserver
;
import
io.reactivex.Observable
;
import
io.reactivex.Observable
;
import
io.reactivex.android.schedulers.AndroidSchedulers
;
import
io.reactivex.android.schedulers.AndroidSchedulers
;
import
io.reactivex.disposables.Disposable
;
import
io.reactivex.disposables.Disposable
;
import
io.reactivex.functions.Consumer
;
import
io.reactivex.schedulers.Schedulers
;
import
io.reactivex.schedulers.Schedulers
;
/**
/**
...
@@ -36,6 +44,22 @@ public class TargetDetectionRepository {
...
@@ -36,6 +44,22 @@ public class TargetDetectionRepository {
*/
*/
public
static
final
int
AI_MODE_PLATE_DETECTION
=
1
;
public
static
final
int
AI_MODE_PLATE_DETECTION
=
1
;
private
static
final
Map
<
Integer
,
Class
<?>>
DETECTION_FACTORY
=
new
ConcurrentHashMap
<>();
static
{
DETECTION_FACTORY
.
put
(
AI_MODE_DISH_DETECTION
,
DishDetection
.
class
);
DETECTION_FACTORY
.
put
(
AI_MODE_PLATE_DETECTION
,
PlateDetection
.
class
);
}
/**
* 目标检测算法
*/
private
TargetDetection
targetDetection
;
/**
* 初始化完成标识
*/
private
final
AtomicBoolean
initializeComplete
=
new
AtomicBoolean
(
false
);
/**
/**
* 单例模式
* 单例模式
*/
*/
...
@@ -52,35 +76,53 @@ public class TargetDetectionRepository {
...
@@ -52,35 +76,53 @@ public class TargetDetectionRepository {
}
}
/**
/**
* 目标检测算法
* 获取是否初始化完成
* @return
*/
*/
private
TargetDetection
targetDetection
;
public
boolean
isInitializeComplete
()
{
return
initializeComplete
.
get
();
}
/**
/**
* 初始化算法模式
* 初始化目标检测功能
* @param aiMode
* 此方法根据当前的人工智能模式初始化相应的目标检测对象
* 如果当前目标检测对象的模式与新的模式不匹配,则先释放当前对象,再创建新的目标检测对象
* 支持的模式包括菜品检测和餐具检测
*/
*/
@SuppressLint
(
"CheckResult"
)
public
void
initTargetDetection
(){
public
void
initTargetDetection
(){
int
aiMode
=
AiLocalRepository
.
getInstance
().
getAiMode
();
try
{
// 释放之前初始化的算法
// 获取当前的人工智能模式
if
(
targetDetection
!=
null
&&
targetDetection
.
getAiMode
()
!=
aiMode
){
int
aiMode
=
AiLocalRepository
.
getInstance
().
getAiMode
();
targetDetection
.
close
();
// 释放之前初始化的算法
targetDetection
=
null
;
if
(
targetDetection
!=
null
&&
targetDetection
.
getAiMode
()
!=
aiMode
)
{
targetDetection
.
close
();
targetDetection
=
null
;
}
// 根据不同的AI模式创建对应的目标检测对象
Class
<?>
detectionClass
=
DETECTION_FACTORY
.
get
(
aiMode
);
if
(
detectionClass
!=
null
)
{
targetDetection
=
(
TargetDetection
)
detectionClass
.
getDeclaredConstructor
().
newInstance
();
}
else
{
XLog
.
e
(
"Unsupported AI mode: "
+
aiMode
);
return
;
}
// 使用Observable异步初始化目标检测
Observable
.
create
(
emitter
->
{
initializeComplete
.
set
(
false
);
targetDetection
.
initTargetDetection
();
emitter
.
onNext
(
true
);
}).
observeOn
(
Schedulers
.
io
())
.
subscribeOn
(
AndroidSchedulers
.
mainThread
())
.
subscribe
(
success
->
initializeComplete
.
set
(
true
),
error
->
{
// 初始化失败时设置标志为false并记录错误日志
initializeComplete
.
set
(
false
);
XLog
.
e
(
error
);
});
}
catch
(
Exception
e
){
XLog
.
e
(
e
);
}
}
switch
(
aiMode
){
case
AI_MODE_DISH_DETECTION:
targetDetection
=
new
DishDetection
();
break
;
case
AI_MODE_PLATE_DETECTION:
targetDetection
=
new
PlateDetection
();
break
;
default
:
break
;
}
assert
targetDetection
!=
null
;
targetDetection
.
initTargetDetection
();
}
}
/**
/**
...
@@ -129,6 +171,7 @@ public class TargetDetectionRepository {
...
@@ -129,6 +171,7 @@ public class TargetDetectionRepository {
finalCanvas
.
drawBitmap
(
bitmap
,
left
,
top
,
new
Paint
());
finalCanvas
.
drawBitmap
(
bitmap
,
left
,
top
,
new
Paint
());
// 使用目标检测模型对处理后的图片进行推理
// 使用目标检测模型对处理后的图片进行推理
TargetDetectResult
result
=
targetDetection
.
processImage
(
background
);
TargetDetectResult
result
=
targetDetection
.
processImage
(
background
);
background
.
recycle
();
// 如果检测到目标并且存在特征向量,则返回第一个特征向量
// 如果检测到目标并且存在特征向量,则返回第一个特征向量
if
(
result
!=
null
&&
result
.
getFeatures
()
!=
null
&&
result
.
getFeatures
().
length
>
0
){
if
(
result
!=
null
&&
result
.
getFeatures
()
!=
null
&&
result
.
getFeatures
().
length
>
0
){
return
result
.
getFeatures
()[
0
];
return
result
.
getFeatures
()[
0
];
...
...
core/src/main/java/com/wmdigit/core/hnsw/Hnsw.java
View file @
309f64be
...
@@ -41,6 +41,13 @@ public class Hnsw {
...
@@ -41,6 +41,13 @@ public class Hnsw {
*/
*/
private
native
void
deleteAllSample
();
private
native
void
deleteAllSample
();
/**
* 删除指定索引
* @param rowId
* @return
*/
private
native
int
deleteByRowId
(
long
rowId
);
/**
/**
* 同步锁
* 同步锁
*/
*/
...
@@ -78,6 +85,15 @@ public class Hnsw {
...
@@ -78,6 +85,15 @@ public class Hnsw {
}
}
}
}
/**
* 删除指定特征ID
* @param featureId
* @return
*/
public
int
delSampleByFeatureId
(
long
featureId
){
return
deleteByRowId
(
featureId
);
}
public
void
deleteAll
(){
public
void
deleteAll
(){
synchronized
(
syncLock
){
synchronized
(
syncLock
){
deleteAllSample
();
deleteAllSample
();
...
...
core/src/main/java/com/wmdigit/core/hnsw/HnswRepository.java
View file @
309f64be
...
@@ -3,7 +3,6 @@ package com.wmdigit.core.hnsw;
...
@@ -3,7 +3,6 @@ package com.wmdigit.core.hnsw;
import
android.text.TextUtils
;
import
android.text.TextUtils
;
import
com.elvishew.xlog.XLog
;
import
com.elvishew.xlog.XLog
;
import
com.wmdigit.core.catering.TargetDetectionRepository
;
import
com.wmdigit.data.database.entity.FeaturesPO
;
import
com.wmdigit.data.database.entity.FeaturesPO
;
import
com.wmdigit.data.database.entity.ProductsPO
;
import
com.wmdigit.data.database.entity.ProductsPO
;
import
com.wmdigit.data.database.repository.FeaturesRepository
;
import
com.wmdigit.data.database.repository.FeaturesRepository
;
...
@@ -15,7 +14,6 @@ import io.reactivex.Observable;
...
@@ -15,7 +14,6 @@ import io.reactivex.Observable;
import
io.reactivex.android.schedulers.AndroidSchedulers
;
import
io.reactivex.android.schedulers.AndroidSchedulers
;
import
io.reactivex.disposables.CompositeDisposable
;
import
io.reactivex.disposables.CompositeDisposable
;
import
io.reactivex.disposables.Disposable
;
import
io.reactivex.disposables.Disposable
;
import
io.reactivex.functions.Consumer
;
import
io.reactivex.schedulers.Schedulers
;
import
io.reactivex.schedulers.Schedulers
;
/**
/**
...
@@ -209,6 +207,17 @@ public class HnswRepository {
...
@@ -209,6 +207,17 @@ public class HnswRepository {
}
}
}
}
/**
* 根据特征向量删除样本
* @param featureId
*/
public
void
deleteByFeatureId
(
long
featureId
){
if
(!
initComplete
){
return
;
}
hnsw
.
delSampleByFeatureId
(
featureId
);
}
/**
/**
* 检查是否初始化完成
* 检查是否初始化完成
* @return 如果初始化完成返回true,否则返回false
* @return 如果初始化完成返回true,否则返回false
...
...
core/src/main/java/com/wmdigit/core/videopipe/VideoPipeRepository.java
View file @
309f64be
...
@@ -126,6 +126,8 @@ public class VideoPipeRepository {
...
@@ -126,6 +126,8 @@ public class VideoPipeRepository {
CropValueDTO
cropValueDTO
=
CropLocalRepository
.
getInstance
().
getCropValue
();
CropValueDTO
cropValueDTO
=
CropLocalRepository
.
getInstance
().
getCropValue
();
Bitmap
croppedBitmap
=
Bitmap
.
createBitmap
(
bitmap
,
cropValueDTO
.
getLeft
(),
cropValueDTO
.
getTop
(),
cropValueDTO
.
getWidth
(),
cropValueDTO
.
getHeight
());
Bitmap
croppedBitmap
=
Bitmap
.
createBitmap
(
bitmap
,
cropValueDTO
.
getLeft
(),
cropValueDTO
.
getTop
(),
cropValueDTO
.
getWidth
(),
cropValueDTO
.
getHeight
());
feedFrame
(
croppedBitmap
);
feedFrame
(
croppedBitmap
);
croppedBitmap
.
recycle
();
croppedBitmap
=
null
;
}
}
else
{
else
{
feedFrame
(
bitmap
);
feedFrame
(
bitmap
);
...
...
data-local/src/main/java/com/wmdigit/data/database/dao/FeaturesDao.java
View file @
309f64be
...
@@ -76,4 +76,20 @@ public interface FeaturesDao {
...
@@ -76,4 +76,20 @@ public interface FeaturesDao {
@Query
(
"SELECT COUNT(*) FROM Features"
)
@Query
(
"SELECT COUNT(*) FROM Features"
)
int
getCount
();
int
getCount
();
/**
* 根据文件地址查询
* @param imgPath
* @return
*/
@Query
(
"SELECT * FROM Features WHERE imgPath = :imgPath"
)
List
<
FeaturesPO
>
queryByImgPath
(
String
imgPath
);
/**
* 根据商品CODE查询
* @param productCode
* @return
*/
@Query
(
"SELECT * FROM Features WHERE productCode = :productCode"
)
List
<
FeaturesPO
>
queryByProductCode
(
String
productCode
);
}
}
data-local/src/main/java/com/wmdigit/data/database/dao/ProductsDao.java
View file @
309f64be
...
@@ -5,6 +5,7 @@ import androidx.room.Insert;
...
@@ -5,6 +5,7 @@ import androidx.room.Insert;
import
androidx.room.OnConflictStrategy
;
import
androidx.room.OnConflictStrategy
;
import
androidx.room.Query
;
import
androidx.room.Query
;
import
com.wmdigit.data.database.entity.ProductAndImgPathsPO
;
import
com.wmdigit.data.database.entity.ProductsPO
;
import
com.wmdigit.data.database.entity.ProductsPO
;
import
java.util.List
;
import
java.util.List
;
...
@@ -57,6 +58,21 @@ public interface ProductsDao {
...
@@ -57,6 +58,21 @@ public interface ProductsDao {
@Query
(
"SELECT * FROM Products WHERE productMnemonicCode LIKE :keywords OR productCode LIKE :keywords LIMIT :offset, :limit"
)
@Query
(
"SELECT * FROM Products WHERE productMnemonicCode LIKE :keywords OR productCode LIKE :keywords LIMIT :offset, :limit"
)
List
<
ProductsPO
>
getProductsByKeywords
(
String
keywords
,
int
offset
,
int
limit
);
List
<
ProductsPO
>
getProductsByKeywords
(
String
keywords
,
int
offset
,
int
limit
);
/**
* 根据关键词获取产品及其图片路径列表
* 此查询通过联合Products和Features表,根据产品代码进行匹配,
* 并根据关键词(产品助记码或产品代码)进行搜索,最后对结果进行分组和分页
*
* @param keywords 搜索关键词,可以是产品助记码或产品代码
* @param offset 查询结果的起始偏移量,用于分页
* @param limit 每页查询结果的数量
* @return 包含产品及其图片路径的列表
*/
@Query
(
"SELECT a.*, GROUP_CONCAT( b.imgPath ) AS imgPaths FROM Products a JOIN Features b ON a.productCode = b.productCode "
+
"WHERE productMnemonicCode LIKE :keywords OR a.productCode LIKE :keywords "
+
"GROUP BY a.productCode LIMIT :offset, :limit"
)
List
<
ProductAndImgPathsPO
>
getProductAndImgPathsByKeywords
(
String
keywords
,
int
offset
,
int
limit
);
/**
/**
* 根据商品编码查询
* 根据商品编码查询
* @param productCode
* @param productCode
...
...
data-local/src/main/java/com/wmdigit/data/database/entity/ProductAndImgPathsPO.java
0 → 100644
View file @
309f64be
package
com
.
wmdigit
.
data
.
database
.
entity
;
/**
* 商品信息和对应的图片地址
* @author dizi
*/
public
class
ProductAndImgPathsPO
{
private
long
id
;
/**
* 商品名称
*/
private
String
productName
;
/**
* 商品编码
*/
private
String
productCode
;
/**
* 助记码(中文名拼音缩写)
*/
private
String
productMnemonicCode
;
/**
* 单价
*/
private
String
unitPrice
;
/**
* 在售状态,1:在售 0:下架
*/
private
int
onSale
;
/**
* 所有图片的路径,以逗号分隔
*/
private
String
imgPaths
;
public
ProductAndImgPathsPO
(
long
id
,
String
productName
,
String
productCode
,
String
productMnemonicCode
,
String
unitPrice
,
int
onSale
,
String
imgPaths
)
{
this
.
id
=
id
;
this
.
productName
=
productName
;
this
.
productCode
=
productCode
;
this
.
productMnemonicCode
=
productMnemonicCode
;
this
.
unitPrice
=
unitPrice
;
this
.
onSale
=
onSale
;
this
.
imgPaths
=
imgPaths
;
}
public
long
getId
()
{
return
id
;
}
public
void
setId
(
long
id
)
{
this
.
id
=
id
;
}
public
String
getProductName
()
{
return
productName
;
}
public
void
setProductName
(
String
productName
)
{
this
.
productName
=
productName
;
}
public
String
getProductCode
()
{
return
productCode
;
}
public
void
setProductCode
(
String
productCode
)
{
this
.
productCode
=
productCode
;
}
public
String
getProductMnemonicCode
()
{
return
productMnemonicCode
;
}
public
void
setProductMnemonicCode
(
String
productMnemonicCode
)
{
this
.
productMnemonicCode
=
productMnemonicCode
;
}
public
String
getUnitPrice
()
{
return
unitPrice
;
}
public
void
setUnitPrice
(
String
unitPrice
)
{
this
.
unitPrice
=
unitPrice
;
}
public
int
getOnSale
()
{
return
onSale
;
}
public
void
setOnSale
(
int
onSale
)
{
this
.
onSale
=
onSale
;
}
public
String
getImgPaths
()
{
return
imgPaths
;
}
public
void
setImgPaths
(
String
imgPaths
)
{
this
.
imgPaths
=
imgPaths
;
}
}
data-local/src/main/java/com/wmdigit/data/database/mapper/FeaturesMapper.java
View file @
309f64be
package
com
.
wmdigit
.
data
.
database
.
mapper
;
package
com
.
wmdigit
.
data
.
database
.
mapper
;
import
com.wmdigit.data.database.entity.ExportFeaturesPO
;
import
com.wmdigit.data.database.entity.ExportFeaturesPO
;
import
com.wmdigit.data.database.entity.FeaturesPO
;
import
com.wmdigit.data.database.entity.FeaturesPO
;
...
@@ -48,6 +49,5 @@ public interface FeaturesMapper {
...
@@ -48,6 +49,5 @@ public interface FeaturesMapper {
*/
*/
List
<
FeaturesPO
>
toFeaturesPOList
(
List
<
ExportFeaturesPO
>
list
);
List
<
FeaturesPO
>
toFeaturesPOList
(
List
<
ExportFeaturesPO
>
list
);
}
}
data-local/src/main/java/com/wmdigit/data/database/mapper/ProductsMapper.java
View file @
309f64be
package
com
.
wmdigit
.
data
.
database
.
mapper
;
package
com
.
wmdigit
.
data
.
database
.
mapper
;
import
android.text.TextUtils
;
import
com.wmdigit.common.model.ProductsDTO
;
import
com.wmdigit.common.model.ProductsDTO
;
import
com.wmdigit.common.model.ProductsVO
;
import
com.wmdigit.common.model.ProductsVO
;
import
com.wmdigit.data.database.entity.ProductAndImgPathsPO
;
import
com.wmdigit.data.database.entity.ProductsPO
;
import
com.wmdigit.data.database.entity.ProductsPO
;
import
org.mapstruct.Mapper
;
import
org.mapstruct.Mapper
;
import
org.mapstruct.Mapping
;
import
org.mapstruct.Named
;
import
org.mapstruct.factory.Mappers
;
import
org.mapstruct.factory.Mappers
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.List
;
/**
/**
...
@@ -29,5 +36,29 @@ public interface ProductsMapper {
...
@@ -29,5 +36,29 @@ public interface ProductsMapper {
List
<
ProductsVO
>
toVoList
(
List
<
ProductsPO
>
poList
);
List
<
ProductsVO
>
toVoList
(
List
<
ProductsPO
>
poList
);
/**
* 将包含多个图片路径的字符串转换为图片路径数组
* 此方法用于处理以逗号分隔的图片路径字符串,将其转换为字符串数组,以便于进一步处理或显示图片
*
* @param imgPaths 以逗号分隔的图片路径字符串
* @return 图片路径字符串数组如果输入字符串为空或null,则返回null
*/
@Named
(
"convertImgPathsToImgPathArray"
)
default
List
<
String
>
convertImgPathsToImgPathArray
(
String
imgPaths
){
// 检查输入的图片路径字符串是否为空或null
if
(
TextUtils
.
isEmpty
(
imgPaths
)){
// 如果为空或null,则返回null
return
null
;
}
// 使用逗号分割输入字符串,返回图片路径字符串数组
String
[]
array
=
imgPaths
.
split
(
","
);
return
new
ArrayList
<>(
Arrays
.
asList
(
array
));
}
@Mapping
(
source
=
"imgPaths"
,
target
=
"imgPathList"
,
qualifiedByName
=
"convertImgPathsToImgPathArray"
)
ProductsVO
toVoWithImgPaths
(
ProductAndImgPathsPO
po
);
List
<
ProductsVO
>
toVoListWithImgPaths
(
List
<
ProductAndImgPathsPO
>
productAndImgPathsPoList
);
}
}
data-local/src/main/java/com/wmdigit/data/database/repository/FeaturesRepository.java
View file @
309f64be
...
@@ -2,6 +2,8 @@ package com.wmdigit.data.database.repository;
...
@@ -2,6 +2,8 @@ package com.wmdigit.data.database.repository;
import
android.text.TextUtils
;
import
android.text.TextUtils
;
import
androidx.annotation.NonNull
;
import
com.elvishew.xlog.XLog
;
import
com.elvishew.xlog.XLog
;
import
com.wmdigit.data.database.AppDatabase
;
import
com.wmdigit.data.database.AppDatabase
;
import
com.wmdigit.data.database.dao.FeaturesDao
;
import
com.wmdigit.data.database.dao.FeaturesDao
;
...
@@ -111,4 +113,29 @@ public class FeaturesRepository {
...
@@ -111,4 +113,29 @@ public class FeaturesRepository {
public
int
getCount
(){
public
int
getCount
(){
return
getFeaturesDao
().
getCount
();
return
getFeaturesDao
().
getCount
();
}
}
/**
* 根据地址删除,返回被删除的特征ID
* @param path
* @return
*/
public
long
deleteByPath
(
String
path
){
List
<
FeaturesPO
>
list
=
getFeaturesDao
().
queryByImgPath
(
path
);
if
(
list
==
null
||
list
.
size
()
==
0
){
return
-
1
;
}
else
{
getFeaturesDao
().
deleteById
(
list
.
get
(
0
).
getId
());
return
list
.
get
(
0
).
getId
();
}
}
/**
* 根据商品CODE查询
* @param productCode
* @return
*/
public
List
<
FeaturesPO
>
queryByProductCode
(
@NonNull
String
productCode
){
return
getFeaturesDao
().
queryByProductCode
(
productCode
);
}
}
}
data-local/src/main/java/com/wmdigit/data/database/repository/ProductsRepository.java
View file @
309f64be
...
@@ -4,6 +4,7 @@ import com.wmdigit.common.model.ProductsDTO;
...
@@ -4,6 +4,7 @@ import com.wmdigit.common.model.ProductsDTO;
import
com.wmdigit.common.model.ProductsVO
;
import
com.wmdigit.common.model.ProductsVO
;
import
com.wmdigit.data.database.AppDatabase
;
import
com.wmdigit.data.database.AppDatabase
;
import
com.wmdigit.data.database.dao.ProductsDao
;
import
com.wmdigit.data.database.dao.ProductsDao
;
import
com.wmdigit.data.database.entity.ProductAndImgPathsPO
;
import
com.wmdigit.data.database.entity.ProductsPO
;
import
com.wmdigit.data.database.entity.ProductsPO
;
import
com.wmdigit.data.database.mapper.ProductsMapper
;
import
com.wmdigit.data.database.mapper.ProductsMapper
;
...
@@ -92,6 +93,15 @@ public class ProductsRepository {
...
@@ -92,6 +93,15 @@ public class ProductsRepository {
return
getProductsDao
().
getByProductCode
(
productCode
);
return
getProductsDao
().
getByProductCode
(
productCode
);
}
}
public
List
<
ProductsVO
>
queryProductsAndImgPathsByKeywords
(
String
keywords
,
int
page
,
int
pageSize
){
int
offset
=
(
page
-
1
)
*
pageSize
;
List
<
ProductAndImgPathsPO
>
list
=
getProductsDao
().
getProductAndImgPathsByKeywords
(
"%"
+
keywords
+
"%"
,
offset
,
pageSize
);
if
(
list
==
null
){
list
=
new
ArrayList
<>();
}
return
ProductsMapper
.
INSTANCE
.
toVoListWithImgPaths
(
list
);
}
/**
/**
* 删除全部
* 删除全部
*/
*/
...
...
history.txt
View file @
309f64be
...
@@ -24,6 +24,9 @@ v1.0.2.1 2025/04/22 1.特征表增加字段记录图片地址,数据库版本
...
@@ -24,6 +24,9 @@ v1.0.2.1 2025/04/22 1.特征表增加字段记录图片地址,数据库版本
v1.0.2.2 2025/04/25 1.UvcCamera从mjpeg改为yuv
v1.0.2.2 2025/04/25 1.UvcCamera从mjpeg改为yuv
2.增加推理时的日志
2.增加推理时的日志
3.修改索引库默认阈值为0.77
3.修改索引库默认阈值为0.77
v1.0.2.3 2025/04/25 1.todo 增加GPU推理
2.增加纠错功能
3.学习页增加重置背景功能
todo 增加学习记录管理模块
todo 增加学习记录管理模块
...
...
module-setting/src/main/java/com/wmdigit/setting/SettingActivity.java
View file @
309f64be
...
@@ -9,11 +9,9 @@ import androidx.recyclerview.widget.RecyclerView;
...
@@ -9,11 +9,9 @@ import androidx.recyclerview.widget.RecyclerView;
import
com.alibaba.android.arouter.facade.annotation.Route
;
import
com.alibaba.android.arouter.facade.annotation.Route
;
import
com.jiangdg.uvc.USBCameraHelper
;
import
com.jiangdg.uvc.USBCameraHelper
;
import
com.wmdigit.camera.CameraxController
;
import
com.wmdigit.common.base.mvvm.BaseMvvmNaviDrawerActivity
;
import
com.wmdigit.common.base.mvvm.BaseMvvmNaviDrawerActivity
;
import
com.wmdigit.common.constants.RouteConstant
;
import
com.wmdigit.common.constants.RouteConstant
;
import
com.wmdigit.common.model.DrawerMenuItemVO
;
import
com.wmdigit.common.model.DrawerMenuItemVO
;
import
com.wmdigit.data.mmkv.repository.CameraLocalRepository
;
import
com.wmdigit.data.mmkv.repository.CropLocalRepository
;
import
com.wmdigit.data.mmkv.repository.CropLocalRepository
;
import
com.wmdigit.setting.databinding.ActivitySettingBinding
;
import
com.wmdigit.setting.databinding.ActivitySettingBinding
;
import
com.wmdigit.setting.viewmodel.SettingViewModel
;
import
com.wmdigit.setting.viewmodel.SettingViewModel
;
...
@@ -49,6 +47,7 @@ public class SettingActivity extends BaseMvvmNaviDrawerActivity<SettingViewModel
...
@@ -49,6 +47,7 @@ public class SettingActivity extends BaseMvvmNaviDrawerActivity<SettingViewModel
@Override
@Override
protected
void
initData
()
{
protected
void
initData
()
{
mDataBinding
.
setViewModel
(
mViewModel
);
// 测试数据
// 测试数据
// List<ProductsDTO> list = new ArrayList<>();
// List<ProductsDTO> list = new ArrayList<>();
// list.add(new ProductsDTO("西红柿炒鸡蛋","000323", "XHSCJD", "12.80", 1));
// list.add(new ProductsDTO("西红柿炒鸡蛋","000323", "XHSCJD", "12.80", 1));
...
@@ -66,7 +65,7 @@ public class SettingActivity extends BaseMvvmNaviDrawerActivity<SettingViewModel
...
@@ -66,7 +65,7 @@ public class SettingActivity extends BaseMvvmNaviDrawerActivity<SettingViewModel
public
void
initObserve
()
{
public
void
initObserve
()
{
super
.
initObserve
();
super
.
initObserve
();
// 观察页码位置
// 观察页码位置
mViewModel
.
pagePosition
.
observe
(
this
,
position
->
{
mViewModel
.
getPagePosition
()
.
observe
(
this
,
position
->
{
if
(
position
==
3
){
if
(
position
==
3
){
mDrawerLayout
.
setDrawerLockMode
(
DrawerLayout
.
LOCK_MODE_UNLOCKED
);
mDrawerLayout
.
setDrawerLockMode
(
DrawerLayout
.
LOCK_MODE_UNLOCKED
);
// 关闭抽屉
// 关闭抽屉
...
@@ -148,7 +147,7 @@ public class SettingActivity extends BaseMvvmNaviDrawerActivity<SettingViewModel
...
@@ -148,7 +147,7 @@ public class SettingActivity extends BaseMvvmNaviDrawerActivity<SettingViewModel
@Override
@Override
protected
void
onDrawerMenuItemClickListener
(
int
position
)
{
protected
void
onDrawerMenuItemClickListener
(
int
position
)
{
if
(
position
==
mViewModel
.
pagePosition
.
getValue
())
{
if
(
position
==
mViewModel
.
getPagePosition
()
.
getValue
())
{
return
;
return
;
}
}
if
(
FRAGMENTS_NAVI_IDS
[
position
]
==
R
.
id
.
dataLearningFragment
){
if
(
FRAGMENTS_NAVI_IDS
[
position
]
==
R
.
id
.
dataLearningFragment
){
...
...
module-setting/src/main/java/com/wmdigit/setting/adapter/FuncButtonAdapter.java
View file @
309f64be
...
@@ -18,19 +18,19 @@ import java.util.List;
...
@@ -18,19 +18,19 @@ import java.util.List;
* 数据管理页功能按钮列表 适配器
* 数据管理页功能按钮列表 适配器
* @author dizi
* @author dizi
*/
*/
public
class
FuncButtonAdapter
extends
BaseRecyclerViewAdapter
<
FuncButton
Adapter
.
ViewHolder
,
FuncButton
>
{
public
class
FuncButtonAdapter
extends
BaseRecyclerViewAdapter
<
FuncButton
>
{
public
FuncButtonAdapter
(
Context
mContext
,
List
<
FuncButton
>
mList
)
{
public
FuncButtonAdapter
(
Context
mContext
,
List
<
FuncButton
>
mList
)
{
super
(
mContext
,
mList
);
super
(
mContext
,
mList
);
}
}
@Override
@Override
protected
int
get
ItemLayoutResId
(
)
{
protected
int
get
LayoutResIdByViewType
(
int
viewType
)
{
return
R
.
layout
.
layout_data_manager_item
;
return
R
.
layout
.
layout_data_manager_item
;
}
}
@Override
@Override
protected
ViewHolder
createViewHolder
(
View
itemView
,
BaseViewHolder
.
OnItemClickListener
onItemClickListener
)
{
protected
ViewHolder
createViewHolder
(
View
itemView
,
BaseViewHolder
.
OnItemClickListener
onItemClickListener
,
int
viewType
)
{
return
new
ViewHolder
(
itemView
,
onItemClickListener
);
return
new
ViewHolder
(
itemView
,
onItemClickListener
);
}
}
...
...
module-setting/src/main/java/com/wmdigit/setting/adapter/LocalImageAdapter.java
0 → 100644
View file @
309f64be
package
com
.
wmdigit
.
setting
.
adapter
;
import
android.content.Context
;
import
android.graphics.Bitmap
;
import
android.view.View
;
import
android.widget.ImageView
;
import
androidx.annotation.NonNull
;
import
com.squareup.picasso.Picasso
;
import
com.wmdigit.common.base.adapter.BaseDiffRecyclerViewAdapter
;
import
com.wmdigit.common.base.viewholder.BaseViewHolder
;
import
com.wmdigit.common.view.imageview.RoundedCornersTransformation
;
import
com.wmdigit.setting.R
;
import
com.wmdigit.setting.adapter.diff.LocalImageDiffUtil
;
import
com.wmdigit.setting.model.LocalImage
;
import
java.io.File
;
import
java.util.List
;
/**
* 本地图片适配器
* @author dizi
*/
public
class
LocalImageAdapter
extends
BaseDiffRecyclerViewAdapter
<
LocalImage
,
LocalImageDiffUtil
>
{
public
LocalImageAdapter
(
Context
mContext
,
List
<
LocalImage
>
mList
)
{
super
(
mContext
,
mList
);
}
@Override
protected
LocalImageDiffUtil
createDiffUtil
(
List
<
LocalImage
>
oldList
,
List
<
LocalImage
>
newList
)
{
return
new
LocalImageDiffUtil
(
oldList
,
newList
);
}
@Override
protected
int
getLayoutResIdByViewType
(
int
viewType
)
{
return
R
.
layout
.
layout_local_image_item
;
}
@Override
protected
BaseViewHolder
<
LocalImage
>
createViewHolder
(
View
itemView
,
BaseViewHolder
.
OnItemClickListener
onItemClickListener
,
int
viewType
)
{
return
new
LocalImageViewHolder
(
itemView
,
onItemClickListener
);
}
public
static
class
LocalImageViewHolder
extends
BaseViewHolder
<
LocalImage
>{
private
ImageView
img
;
public
LocalImageViewHolder
(
@NonNull
View
itemView
,
OnItemClickListener
itemListener
)
{
super
(
itemView
,
itemListener
);
img
=
itemView
.
findViewById
(
R
.
id
.
img_local_image
);
}
@Override
public
void
bind
(
LocalImage
item
)
{
Picasso
.
get
()
.
load
(
new
File
(
item
.
getPath
()))
.
transform
(
new
RoundedCornersTransformation
(
10
))
.
config
(
Bitmap
.
Config
.
RGB_565
)
.
into
(
this
.
img
);
}
}
}
module-setting/src/main/java/com/wmdigit/setting/adapter/ProductsAdapter.java
View file @
309f64be
...
@@ -3,21 +3,32 @@ package com.wmdigit.setting.adapter;
...
@@ -3,21 +3,32 @@ package com.wmdigit.setting.adapter;
import
android.content.Context
;
import
android.content.Context
;
import
android.view.View
;
import
android.view.View
;
import
android.widget.Button
;
import
android.widget.TextView
;
import
android.widget.TextView
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.NonNull
;
import
androidx.recyclerview.widget.GridLayoutManager
;
import
androidx.recyclerview.widget.RecyclerView
;
import
com.wmdigit.common.base.adapter.BaseDiffRecyclerViewAdapter
;
import
com.wmdigit.common.base.adapter.BaseDiffRecyclerViewAdapter
;
import
com.wmdigit.common.base.viewholder.BaseViewHolder
;
import
com.wmdigit.common.base.viewholder.BaseViewHolder
;
import
com.wmdigit.common.model.ProductsVO
;
import
com.wmdigit.common.model.ProductsVO
;
import
com.wmdigit.setting.R
;
import
com.wmdigit.setting.R
;
import
com.wmdigit.setting.adapter.diff.ProductsDiffUtil
;
import
com.wmdigit.setting.adapter.diff.ProductsDiffUtil
;
import
com.wmdigit.setting.model.DelAllFeaturesByProductCodeMessage
;
import
com.wmdigit.setting.model.LocalImage
;
import
com.wmdigit.setting.model.DelOneFeatureByPathMessage
;
import
org.greenrobot.eventbus.EventBus
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
/**
/**
* 商品列表适配器
* 商品列表适配器
* @author dizi
* @author dizi
*/
*/
public
class
ProductsAdapter
extends
BaseDiffRecyclerViewAdapter
<
Products
Adapter
.
ViewHolder
,
Products
VO
,
ProductsDiffUtil
>
{
public
class
ProductsAdapter
extends
BaseDiffRecyclerViewAdapter
<
ProductsVO
,
ProductsDiffUtil
>
{
public
ProductsAdapter
(
Context
mContext
,
List
<
ProductsVO
>
mList
)
{
public
ProductsAdapter
(
Context
mContext
,
List
<
ProductsVO
>
mList
)
{
super
(
mContext
,
mList
);
super
(
mContext
,
mList
);
...
@@ -29,37 +40,143 @@ public class ProductsAdapter extends BaseDiffRecyclerViewAdapter<ProductsAdapter
...
@@ -29,37 +40,143 @@ public class ProductsAdapter extends BaseDiffRecyclerViewAdapter<ProductsAdapter
}
}
@Override
@Override
protected
int
getItemLayoutResId
()
{
public
int
getItemViewType
(
int
position
)
{
return
R
.
layout
.
layout_product_item
;
return
mList
.
get
(
position
).
getLayoutType
();
}
@Override
protected
int
getLayoutResIdByViewType
(
int
viewType
)
{
if
(
viewType
==
0
){
return
R
.
layout
.
layout_product_item
;
}
else
{
return
R
.
layout
.
layout_learning_correction_item
;
}
}
}
@Override
@Override
protected
ViewHolder
createViewHolder
(
View
itemView
,
BaseViewHolder
.
OnItemClickListener
onItemClickListener
)
{
protected
BaseViewHolder
<
ProductsVO
>
createViewHolder
(
View
itemView
,
BaseViewHolder
.
OnItemClickListener
onItemClickListener
,
int
viewType
)
{
return
new
ViewHolder
(
itemView
,
onItemClickListener
);
if
(
viewType
==
0
){
return
new
ProductsViewHolder
(
itemView
,
onItemClickListener
);
}
else
{
return
new
LearningRecordsViewHolder
(
itemView
,
onItemClickListener
);
}
}
}
public
static
class
ViewHolder
extends
BaseViewHolder
<
ProductsVO
>{
/**
* 学习记录视图持有者类,用于显示产品学习记录的详细信息
* 继承自BaseViewHolder,用于管理产品视图的展示
*/
public
static
class
LearningRecordsViewHolder
extends
BaseViewHolder
<
ProductsVO
>{
// 用于显示产品名称的文本视图
private
TextView
tvProductName
;
// 用于显示产品编码的文本视图
private
TextView
tvProductCode
;
// 删除学习数据的按钮
private
Button
btnDeleteLearningData
;
// 显示本地图片的循环视图
private
RecyclerView
recyclerView
;
/**
* 构造函数,初始化视图组件
*
* @param itemView 视图项
* @param itemListener 项点击监听器
*/
public
LearningRecordsViewHolder
(
@NonNull
View
itemView
,
OnItemClickListener
itemListener
)
{
super
(
itemView
,
null
);
// 初始化视图组件
tvProductName
=
itemView
.
findViewById
(
R
.
id
.
tv_product_name2
);
tvProductCode
=
itemView
.
findViewById
(
R
.
id
.
tv_product_code2
);
btnDeleteLearningData
=
itemView
.
findViewById
(
R
.
id
.
btn_del_all_learning_data
);
recyclerView
=
itemView
.
findViewById
(
R
.
id
.
rv_local_images
);
// 设置RecyclerView的布局管理器,使用8列的网格布局
recyclerView
.
setLayoutManager
(
new
GridLayoutManager
(
itemView
.
getContext
(),
8
));
}
/**
* 绑定产品数据到视图
*
* @param item 产品数据对象
*/
@Override
public
void
bind
(
ProductsVO
item
)
{
// 设置产品名称和编码到对应的文本视图
tvProductName
.
setText
(
item
.
getProductName
());
tvProductCode
.
setText
(
item
.
getProductCode
());
// 创建本地图片列表
List
<
LocalImage
>
list
=
new
ArrayList
<>();
// 遍历产品图片路径列表,创建本地图片对象,并添加到列表中
for
(
String
path:
item
.
getImgPathList
()){
list
.
add
(
new
LocalImage
(
path
));
}
// 创建并设置本地图片适配器到RecyclerView
LocalImageAdapter
adapter
=
new
LocalImageAdapter
(
itemView
.
getContext
(),
list
);
recyclerView
.
setAdapter
(
adapter
);
// 图片数量为空时,隐藏删除图标
if
(
list
.
size
()
==
0
){
btnDeleteLearningData
.
setVisibility
(
View
.
INVISIBLE
);
}
else
{
btnDeleteLearningData
.
setVisibility
(
View
.
VISIBLE
);
}
// 设置适配器的项点击监听器,用于删除单个特征
adapter
.
setOnItemClickListener
(
position
->
EventBus
.
getDefault
().
post
(
new
DelOneFeatureByPathMessage
(
list
.
get
(
position
).
getPath
())));
// 设置删除学习数据按钮的点击监听器,用于删除所有特征
btnDeleteLearningData
.
setOnClickListener
(
v
->{
EventBus
.
getDefault
().
post
(
new
DelAllFeaturesByProductCodeMessage
(
item
.
getProductCode
()));
});
}
}
/**
* ProductsViewHolder 类是用于在 RecyclerView 中显示产品信息的视图持有者类
* 它继承自 BaseViewHolder,并专门用于绑定和显示 ProductsVO 类型的数据
*/
public
static
class
ProductsViewHolder
extends
BaseViewHolder
<
ProductsVO
>{
// 定义用于显示产品名称、代码和价格的 TextView 变量
private
TextView
tvProductName
,
tvProductCode
,
tvProductPrice
;
private
TextView
tvProductName
,
tvProductCode
,
tvProductPrice
;
public
ViewHolder
(
@NonNull
View
itemView
,
OnItemClickListener
itemListener
)
{
/**
* 构造函数用于初始化 ProductsViewHolder
* 它调用父类的构造函数,并初始化产品信息的 TextView
*
* @param itemView 视图项,用于 findViewById 来查找视图
* @param itemListener 项点击监听器,用于处理点击事件
*/
public
ProductsViewHolder
(
@NonNull
View
itemView
,
OnItemClickListener
itemListener
)
{
super
(
itemView
,
itemListener
);
super
(
itemView
,
itemListener
);
// 初始化显示产品信息的 TextView
tvProductName
=
itemView
.
findViewById
(
R
.
id
.
tv_product_name
);
tvProductName
=
itemView
.
findViewById
(
R
.
id
.
tv_product_name
);
tvProductCode
=
itemView
.
findViewById
(
R
.
id
.
tv_product_code
);
tvProductCode
=
itemView
.
findViewById
(
R
.
id
.
tv_product_code
);
tvProductPrice
=
itemView
.
findViewById
(
R
.
id
.
tv_product_price
);
tvProductPrice
=
itemView
.
findViewById
(
R
.
id
.
tv_product_price
);
}
}
/**
* bind 方法用于将产品数据绑定到视图上
* 它将产品名称、代码和价格设置到对应的 TextView 上
*
* @param item ProductsVO 类型的产品数据对象,包含产品信息
*/
@Override
@Override
public
void
bind
(
ProductsVO
item
)
{
public
void
bind
(
ProductsVO
item
)
{
// 设置产品名称、代码和价格到对应的 TextView
tvProductName
.
setText
(
item
.
getProductName
());
tvProductName
.
setText
(
item
.
getProductName
());
tvProductCode
.
setText
(
item
.
getProductCode
());
tvProductCode
.
setText
(
item
.
getProductCode
());
// 产品价格前添加货币符号
tvProductPrice
.
setText
(
"¥"
+
item
.
getUnitPrice
());
tvProductPrice
.
setText
(
"¥"
+
item
.
getUnitPrice
());
if
(
item
.
isChecked
()){
}
else
{
}
}
}
}
}
}
}
module-setting/src/main/java/com/wmdigit/setting/adapter/diff/LocalImageDiffUtil.java
0 → 100644
View file @
309f64be
package
com
.
wmdigit
.
setting
.
adapter
.
diff
;
import
com.wmdigit.common.base.diffutil.BaseDiffUtil
;
import
com.wmdigit.setting.model.LocalImage
;
import
java.util.List
;
public
class
LocalImageDiffUtil
extends
BaseDiffUtil
<
LocalImage
>
{
public
LocalImageDiffUtil
(
List
<
LocalImage
>
oldList
,
List
<
LocalImage
>
newList
)
{
super
(
oldList
,
newList
);
}
@Override
protected
boolean
areItemsTheSame
(
LocalImage
oldItem
,
LocalImage
newItem
)
{
if
(!
oldItem
.
getPath
().
equals
(
newItem
.
getPath
())){
return
false
;
}
return
true
;
}
@Override
protected
boolean
checkContentsTheSame
(
LocalImage
oldItem
,
LocalImage
newItem
)
{
if
(!
oldItem
.
getPath
().
equals
(
newItem
.
getPath
())){
return
false
;
}
return
true
;
}
}
module-setting/src/main/java/com/wmdigit/setting/adapter/diff/ProductsDiffUtil.java
View file @
309f64be
...
@@ -16,7 +16,27 @@ public class ProductsDiffUtil extends BaseDiffUtil<ProductsVO> {
...
@@ -16,7 +16,27 @@ public class ProductsDiffUtil extends BaseDiffUtil<ProductsVO> {
@Override
@Override
protected
boolean
areItemsTheSame
(
ProductsVO
oldItem
,
ProductsVO
newItem
)
{
protected
boolean
areItemsTheSame
(
ProductsVO
oldItem
,
ProductsVO
newItem
)
{
return
oldItem
.
getProductCode
().
equals
(
newItem
.
getProductCode
());
if
(!
oldItem
.
getProductCode
().
equals
(
newItem
.
getProductCode
())){
return
false
;
}
if
(
oldItem
.
getLayoutType
()
!=
newItem
.
getLayoutType
()){
return
false
;
}
// 判断图片列表
if
(
oldItem
.
getImgPathList
()
!=
null
&&
newItem
.
getImgPathList
()
!=
null
){
if
(
oldItem
.
getImgPathList
().
size
()
!=
newItem
.
getImgPathList
().
size
()){
return
false
;
}
}
else
if
(
oldItem
.
getImgPathList
()
==
null
&&
newItem
.
getImgPathList
()
!=
null
){
return
false
;
}
else
if
(
oldItem
.
getImgPathList
()
!=
null
&&
newItem
.
getImgPathList
()
==
null
){
return
false
;
}
else
{
}
return
true
;
}
}
@Override
@Override
...
...
module-setting/src/main/java/com/wmdigit/setting/fragment/DataLearningFragment.java
View file @
309f64be
package
com
.
wmdigit
.
setting
.
fragment
;
package
com
.
wmdigit
.
setting
.
fragment
;
import
android.annotation.SuppressLint
;
import
android.view.MotionEvent
;
import
android.view.MotionEvent
;
import
android.view.View
;
import
androidx.lifecycle.Observer
;
import
androidx.recyclerview.widget.GridLayoutManager
;
import
androidx.recyclerview.widget.GridLayoutManager
;
import
androidx.recyclerview.widget.LinearLayoutManager
;
import
com.elvishew.xlog.XLog
;
import
com.jiangdg.uvc.USBCameraHelper
;
import
com.jiangdg.uvc.USBCameraHelper
;
import
com.wmdigit.camera.CameraxController
;
import
com.wmdigit.common.base.mvvm.BaseMvvmFragment
;
import
com.wmdigit.common.base.mvvm.BaseMvvmFragment
;
import
com.wmdigit.common.view.keyboard.EnglishAndNumberKeyboard
;
import
com.wmdigit.common.view.keyboard.EnglishAndNumberKeyboard
;
import
com.wmdigit.core.videopipe.VideoPipeRepository
;
import
com.wmdigit.setting.R
;
import
com.wmdigit.setting.R
;
import
com.wmdigit.setting.adapter.ProductsAdapter
;
import
com.wmdigit.setting.adapter.ProductsAdapter
;
import
com.wmdigit.setting.databinding.FragmentDataLearningBinding
;
import
com.wmdigit.setting.databinding.FragmentDataLearningBinding
;
import
com.wmdigit.setting.model.DelAllFeaturesByProductCodeMessage
;
import
com.wmdigit.setting.model.DelOneFeatureByPathMessage
;
import
com.wmdigit.setting.viewmodel.DataLearningViewModel
;
import
com.wmdigit.setting.viewmodel.DataLearningViewModel
;
import
com.wmdigit.setting.viewmodel.SettingViewModel
;
import
org.greenrobot.eventbus.EventBus
;
import
org.greenrobot.eventbus.Subscribe
;
import
org.greenrobot.eventbus.ThreadMode
;
/**
/**
...
@@ -25,8 +29,16 @@ import com.wmdigit.setting.viewmodel.DataLearningViewModel;
...
@@ -25,8 +29,16 @@ import com.wmdigit.setting.viewmodel.DataLearningViewModel;
*/
*/
public
class
DataLearningFragment
extends
BaseMvvmFragment
<
DataLearningViewModel
,
FragmentDataLearningBinding
>
{
public
class
DataLearningFragment
extends
BaseMvvmFragment
<
DataLearningViewModel
,
FragmentDataLearningBinding
>
{
/**
* 商品列表适配器
*/
private
ProductsAdapter
productsAdapter
;
private
ProductsAdapter
productsAdapter
;
/**
* activity的ViewModel
*/
private
SettingViewModel
settingViewModel
;
@Override
@Override
protected
int
getLayoutId
()
{
protected
int
getLayoutId
()
{
return
R
.
layout
.
fragment_data_learning
;
return
R
.
layout
.
fragment_data_learning
;
...
@@ -35,6 +47,8 @@ public class DataLearningFragment extends BaseMvvmFragment<DataLearningViewModel
...
@@ -35,6 +47,8 @@ public class DataLearningFragment extends BaseMvvmFragment<DataLearningViewModel
@Override
@Override
protected
void
initObserve
()
{
protected
void
initObserve
()
{
super
.
initObserve
();
super
.
initObserve
();
// 从Activity中获取共享的SettingViewModel实例
settingViewModel
=
getSharedViewModelFromActivity
(
SettingViewModel
.
class
);
// 观察关键字变化
// 观察关键字变化
mViewModel
.
keywords
.
observe
(
this
,
keyword
->
{
mViewModel
.
keywords
.
observe
(
this
,
keyword
->
{
mViewModel
.
onKeywordsChangedEvent
(
keyword
);
mViewModel
.
onKeywordsChangedEvent
(
keyword
);
...
@@ -42,31 +56,77 @@ public class DataLearningFragment extends BaseMvvmFragment<DataLearningViewModel
...
@@ -42,31 +56,77 @@ public class DataLearningFragment extends BaseMvvmFragment<DataLearningViewModel
});
});
// 观察页码变化
// 观察页码变化
mViewModel
.
currentPage
.
observe
(
this
,
page
->
{
mViewModel
.
currentPage
.
observe
(
this
,
page
->
{
mViewModel
.
onPageChangedEvent
(
page
);
if
(!
mViewModel
.
currentPage
.
getValue
().
equals
(
page
))
{
mViewModel
.
onPageChangedEvent
(
page
);
productsAdapter
.
diffAndUpdate
();
}
});
// 观察学习模式
settingViewModel
.
getModeOnLearningPage
().
observe
(
this
,
mode
->{
if
(
mViewModel
.
getLearningMode
()
!=
mode
)
{
mViewModel
.
onSwitchLearningMode
(
mode
);
initRecyclerView
(
mode
);
productsAdapter
.
diffAndUpdate
();
}
});
//
mViewModel
.
getDataSourceChanged
().
observe
(
this
,
b
->{
productsAdapter
.
diffAndUpdate
();
productsAdapter
.
diffAndUpdate
();
});
});
}
}
@Override
@Override
protected
void
initView
()
{
protected
void
initView
()
{
mDataBinding
.
rvProducts
.
setLayoutManager
(
new
GridLayoutManager
(
requireContext
(),
4
));
initRecyclerView
(
0
);
}
/**
* 初始化列表
* @param mode
*/
private
void
initRecyclerView
(
int
mode
){
if
(
mode
==
0
)
{
// 学习模式,水平布局列表
mDataBinding
.
rvProducts
.
setLayoutManager
(
new
GridLayoutManager
(
requireContext
(),
4
));
}
else
{
// 纠错模式,垂直列表
mDataBinding
.
rvProducts
.
setLayoutManager
(
new
LinearLayoutManager
(
requireContext
()));
}
}
}
/**
* 初始化数据方法
* 该方法用于在当前Fragment中初始化所需的数据和视图模型
*/
@Override
@Override
protected
void
initData
()
{
protected
void
initData
()
{
// 设置ViewModel,以便数据绑定
mDataBinding
.
setViewModel
(
mViewModel
);
mDataBinding
.
setViewModel
(
mViewModel
);
productsAdapter
=
new
ProductsAdapter
(
requireContext
(),
mViewModel
.
products
);
// 设置Activity级别的ViewModel,用于跨Fragment通信
mDataBinding
.
setActivityViewModel
(
settingViewModel
);
// 创建并设置产品适配器
productsAdapter
=
new
ProductsAdapter
(
requireContext
(),
mViewModel
.
getProducts
());
mDataBinding
.
rvProducts
.
setAdapter
(
productsAdapter
);
mDataBinding
.
rvProducts
.
setAdapter
(
productsAdapter
);
}
}
@SuppressLint
(
"ClickableViewAccessibility"
)
@Override
@Override
protected
void
initListener
()
{
protected
void
initListener
()
{
// 注册商品列表Item点击事件
// 注册商品列表Item点击事件
productsAdapter
.
setOnItemClickListener
(
position
->
{
productsAdapter
.
setOnItemClickListener
(
position
->
{
mViewModel
.
feedback
(
mViewModel
.
products
.
get
(
position
));
mViewModel
.
feedback
(
mViewModel
.
getProducts
()
.
get
(
position
));
});
});
// 注册键盘按钮点击事件
// 注册键盘按钮点击事件
mDataBinding
.
keyboard
.
setOnKeyboardClickListener
(
new
EnglishAndNumberKeyboard
.
OnKeyboardClickListener
()
{
mDataBinding
.
keyboard
.
setOnKeyboardClickListener
(
new
EnglishAndNumberKeyboard
.
OnKeyboardClickListener
()
{
@Override
public
void
onClickResetEmptyBackground
()
{
// 重置背景
showResetEmptyBackgroundDialog
();
}
@Override
@Override
public
void
onClickReDetect
()
{
public
void
onClickReDetect
()
{
// 重新识别
// 重新识别
...
@@ -88,6 +148,17 @@ public class DataLearningFragment extends BaseMvvmFragment<DataLearningViewModel
...
@@ -88,6 +148,17 @@ public class DataLearningFragment extends BaseMvvmFragment<DataLearningViewModel
});
});
}
}
/**
* 展示重置空盘确认框
*/
private
void
showResetEmptyBackgroundDialog
(){
mSecondConfirmWindow
.
setTitle
(
getString
(
com
.
wmdigit
.
common
.
R
.
string
.
prompt
))
.
setContent
(
getString
(
com
.
wmdigit
.
common
.
R
.
string
.
describe_re_take_empty_background_photo
))
.
setClickListener
(()->
mViewModel
.
setEmptyBackgroundForVideoPipe
())
.
showWindow
();
}
@Override
@Override
protected
Class
<
DataLearningViewModel
>
getViewModel
()
{
protected
Class
<
DataLearningViewModel
>
getViewModel
()
{
return
DataLearningViewModel
.
class
;
return
DataLearningViewModel
.
class
;
...
@@ -102,20 +173,53 @@ public class DataLearningFragment extends BaseMvvmFragment<DataLearningViewModel
...
@@ -102,20 +173,53 @@ public class DataLearningFragment extends BaseMvvmFragment<DataLearningViewModel
@Override
@Override
public
void
onResume
()
{
public
void
onResume
()
{
super
.
onResume
();
super
.
onResume
();
EventBus
.
getDefault
().
register
(
this
);
// 注册相机回调
// 注册相机回调
/*CameraxController.getInstance(requireContext())
.setFrameInterval(2)
.setOnImageAnalyzeListener(mViewModel.getOnImageAnalyzeListener());*/
USBCameraHelper
.
getInstance
(
requireContext
())
USBCameraHelper
.
getInstance
(
requireContext
())
.
setOnImageAnalyzeListener
(
mViewModel
.
getOnImageAnalyzeListener
());
.
setOnImageAnalyzeListener
(
mViewModel
.
getOnImageAnalyzeListener
());
mViewModel
.
openVideoPipe
();
mViewModel
.
openVideoPipe
();
}
}
@Override
@Override
public
void
onPause
()
{
public
void
onPause
()
{
super
.
onPause
();
super
.
onPause
();
// CameraxController.getInstance().setOnImageAnalyzeListener(null
);
EventBus
.
getDefault
().
unregister
(
this
);
USBCameraHelper
.
getInstance
(
requireContext
()).
setOnImageAnalyzeListener
(
null
);
USBCameraHelper
.
getInstance
(
requireContext
()).
setOnImageAnalyzeListener
(
null
);
mViewModel
.
closeVideoPipe
();
mViewModel
.
closeVideoPipe
();
}
}
/**
* 当接收到删除特定路径的特征信息消息时执行的操作
* 此方法在主线程中调用,显示一个确认窗口,以确保用户确实希望删除指定的特征和图片
*
* @param message 包含待删除特征路径信息的消息对象
*/
@Subscribe
(
threadMode
=
ThreadMode
.
MAIN
)
public
void
onEvent
(
DelOneFeatureByPathMessage
message
){
// 设置确认窗口的标题、内容和点击事件处理程序,然后显示窗口
mSecondConfirmWindow
.
setTitle
(
getString
(
com
.
wmdigit
.
common
.
R
.
string
.
prompt
))
.
setContent
(
getString
(
R
.
string
.
confirm_del_photo
))
.
setClickListener
(()
->
{
// 用户确认后,调用ViewModel中的方法删除指定特征和图片
mViewModel
.
deleteFeatureAndImage
(
message
.
getPayload
());
}).
showWindow
();
}
/**
* 当接收到删除指定产品代码的所有特征信息消息时执行的操作
* 此方法在主线程中调用,显示一个确认窗口,以确保用户确实希望删除该产品所有的特征和图片
*
* @param message 包含待删除产品代码信息的消息对象
*/
@Subscribe
(
threadMode
=
ThreadMode
.
MAIN
)
public
void
onEvent
(
DelAllFeaturesByProductCodeMessage
message
){
// 设置确认窗口的标题、内容和点击事件处理程序,然后显示窗口
mSecondConfirmWindow
.
setTitle
(
getString
(
com
.
wmdigit
.
common
.
R
.
string
.
prompt
))
.
setContent
(
getString
(
R
.
string
.
confirm_del_all_photos_of_this_product
))
.
setClickListener
(()->{
// 用户确认后,调用ViewModel中的方法删除指定产品所有的特征和图片
mViewModel
.
deleteAllFeaturesAndImageOfProduct
(
message
.
getPayload
());
}).
showWindow
();
}
}
}
\ No newline at end of file
module-setting/src/main/java/com/wmdigit/setting/model/DelAllFeaturesByProductCodeMessage.java
0 → 100644
View file @
309f64be
package
com
.
wmdigit
.
setting
.
model
;
import
com.wmdigit.common.base.model.BaseMessage
;
import
com.wmdigit.common.enums.MessageType
;
/**
* 继承自 BaseMessage 的 DelAllFeaturesByProductCodeMessage 类
* 用于处理通过产品代码删除所有特性消息的类
* 这个类的存在意义在于封装删除操作的消息结构,使其具有明确的语义和用途
*
* @param <String> 指定消息的有效载荷类型为字符串
*/
public
class
DelAllFeaturesByProductCodeMessage
extends
BaseMessage
<
String
>
{
/**
* 构造函数,初始化删除所有特性消息的实例
*
* @param payload 消息的有效载荷,即产品代码字符串
* 这个参数是构造函数的核心,因为它承载了执行删除操作所需的信息
*/
public
DelAllFeaturesByProductCodeMessage
(
String
payload
)
{
super
(
MessageType
.
DEL_ALL_FEATURES_BY_PRODUCT_CODE
,
payload
);
}
}
module-setting/src/main/java/com/wmdigit/setting/model/DelOneFeatureByPathMessage.java
0 → 100644
View file @
309f64be
package
com
.
wmdigit
.
setting
.
model
;
import
com.wmdigit.common.base.model.BaseMessage
;
import
com.wmdigit.common.enums.MessageType
;
/**
* 根据图片路径删除向量
* @author dizi
*/
public
class
DelOneFeatureByPathMessage
extends
BaseMessage
<
String
>
{
public
DelOneFeatureByPathMessage
(
String
payload
)
{
super
(
MessageType
.
DEL_ONE_FEATURE_BY_PATH
,
payload
);
}
}
module-setting/src/main/java/com/wmdigit/setting/model/LocalImage.java
0 → 100644
View file @
309f64be
package
com
.
wmdigit
.
setting
.
model
;
import
com.wmdigit.common.base.diffutil.BaseDiffUtilModel
;
/**
* 本地图
* @author dizi
*/
public
class
LocalImage
extends
BaseDiffUtilModel
{
private
String
path
;
public
LocalImage
(
String
path
)
{
this
.
path
=
path
;
}
public
String
getPath
()
{
return
path
;
}
public
void
setPath
(
String
path
)
{
this
.
path
=
path
;
}
}
module-setting/src/main/java/com/wmdigit/setting/viewmodel/DataLearningViewModel.java
View file @
309f64be
This diff is collapsed.
Click to expand it.
module-setting/src/main/java/com/wmdigit/setting/viewmodel/SettingViewModel.java
View file @
309f64be
...
@@ -3,7 +3,10 @@ package com.wmdigit.setting.viewmodel;
...
@@ -3,7 +3,10 @@ package com.wmdigit.setting.viewmodel;
import
android.app.Application
;
import
android.app.Application
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.NonNull
;
import
androidx.lifecycle.MediatorLiveData
;
import
androidx.lifecycle.MutableLiveData
;
import
com.elvishew.xlog.XLog
;
import
com.wmdigit.common.base.mvvm.BaseViewModel
;
import
com.wmdigit.common.base.mvvm.BaseViewModel
;
import
com.wmdigit.common.base.mvvm.SingleLiveEvent
;
import
com.wmdigit.common.base.mvvm.SingleLiveEvent
;
import
com.wmdigit.common.model.DrawerMenuItemVO
;
import
com.wmdigit.common.model.DrawerMenuItemVO
;
...
@@ -26,15 +29,20 @@ public class SettingViewModel extends BaseViewModel {
...
@@ -26,15 +29,20 @@ public class SettingViewModel extends BaseViewModel {
* 3-菜品学习页
* 3-菜品学习页
* 4-相机标定页
* 4-相机标定页
*/
*/
public
SingleLiveEvent
<
Integer
>
pagePosition
=
new
SingleLiveEvent
<>();
private
final
MutableLiveData
<
Integer
>
pagePosition
=
new
MutableLiveData
<>();
/**
* 0-学习模式 1-纠错模式
*/
private
final
MutableLiveData
<
Integer
>
modeOnLearningPage
=
new
MutableLiveData
<>();
/**
/**
* 抽屉菜单列表
* 抽屉菜单列表
*/
*/
private
List
<
DrawerMenuItemVO
>
list
=
new
ArrayList
<>();
private
final
List
<
DrawerMenuItemVO
>
list
=
new
ArrayList
<>();
public
SettingViewModel
(
@NonNull
Application
application
)
{
public
SettingViewModel
(
@NonNull
Application
application
)
{
super
(
application
);
super
(
application
);
pagePosition
.
postValue
(
0
);
modeOnLearningPage
.
setValue
(
0
);
pagePosition
.
setValue
(
0
);
// 初始化抽屉菜单
// 初始化抽屉菜单
list
.
add
(
new
DrawerMenuItemVO
(
R
.
drawable
.
ic_menu_system
,
getApplication
().
getString
(
R
.
string
.
module_setting_system
),
true
));
list
.
add
(
new
DrawerMenuItemVO
(
R
.
drawable
.
ic_menu_system
,
getApplication
().
getString
(
R
.
string
.
module_setting_system
),
true
));
list
.
add
(
new
DrawerMenuItemVO
(
R
.
drawable
.
ic_menu_register
,
getApplication
().
getString
(
R
.
string
.
module_setting_register
),
false
));
list
.
add
(
new
DrawerMenuItemVO
(
R
.
drawable
.
ic_menu_register
,
getApplication
().
getString
(
R
.
string
.
module_setting_register
),
false
));
...
@@ -70,4 +78,29 @@ public class SettingViewModel extends BaseViewModel {
...
@@ -70,4 +78,29 @@ public class SettingViewModel extends BaseViewModel {
public
boolean
checkAllowCloseDrawer
(){
public
boolean
checkAllowCloseDrawer
(){
return
pagePosition
.
getValue
()
==
3
;
return
pagePosition
.
getValue
()
==
3
;
}
}
/**
* 切换学习页面的模式
* 此方法用于在学习页面上切换当前的模式当模式值为0时,切换到1,反之亦然
* 这种切换机制对于支持两种不同学习状态的界面非常有用
*/
public
void
switchModeOnLearningPage
(){
// 检查当前模式值是否为0
if
(
modeOnLearningPage
.
getValue
()
==
0
){
// 如果当前模式为0,则切换到1
modeOnLearningPage
.
setValue
(
1
);
}
else
{
// 如果当前模式不为0,则切换回0
modeOnLearningPage
.
setValue
(
0
);
}
}
public
MutableLiveData
<
Integer
>
getPagePosition
()
{
return
pagePosition
;
}
public
MutableLiveData
<
Integer
>
getModeOnLearningPage
()
{
return
modeOnLearningPage
;
}
}
}
module-setting/src/main/res/layout/activity_setting.xml
View file @
309f64be
...
@@ -5,7 +5,11 @@
...
@@ -5,7 +5,11 @@
tools:ignore=
"ResourceName"
>
tools:ignore=
"ResourceName"
>
<data>
<data>
<import
type=
"android.view.View"
/>
<variable
name=
"viewModel"
type=
"com.wmdigit.setting.viewmodel.SettingViewModel"
/>
</data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
<androidx.constraintlayout.widget.ConstraintLayout
...
@@ -24,8 +28,36 @@
...
@@ -24,8 +28,36 @@
style=
"@style/ToolbarTheme"
style=
"@style/ToolbarTheme"
app:navigationIcon=
"@drawable/ic_drawer_close"
app:navigationIcon=
"@drawable/ic_drawer_close"
app:title=
"@string/module_setting_name"
app:title=
"@string/module_setting_name"
app:menu=
"@menu/toolbar_menu"
app:menu=
"@menu/toolbar_menu"
>
/>
<LinearLayout
android:layout_width=
"wrap_content"
android:layout_height=
"match_parent"
android:orientation=
"horizontal"
android:gravity=
"start|center_vertical"
android:paddingStart=
"@dimen/dp_20"
>
<!--纠错、学习模式切换按钮-->
<com.google.android.material.button.MaterialButton
android:id=
"@+id/btn_switch_learning_mode"
style=
"@style/Widget.MaterialComponents.Button.TextButton"
android:text=
"@{viewModel.modeOnLearningPage == 0 ? @string/switch_to_learning_mode : @string/switch_to_error_correction_mode}"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:visibility=
"@{viewModel.pagePosition != 3 ? View.GONE : View.VISIBLE}"
android:onClick=
"@{()->viewModel.switchModeOnLearningPage()}"
app:icon=
"@drawable/ic_switch"
app:iconGravity=
"textStart"
app:iconPadding=
"@dimen/dp_4"
app:iconSize=
"@dimen/dp_30"
android:insetTop=
"@dimen/dp_0"
android:insetBottom=
"@dimen/dp_0"
/>
</LinearLayout>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout>
</com.google.android.material.appbar.AppBarLayout>
...
...
module-setting/src/main/res/layout/fragment_data_learning.xml
View file @
309f64be
...
@@ -8,6 +8,9 @@
...
@@ -8,6 +8,9 @@
<variable
<variable
name=
"viewModel"
name=
"viewModel"
type=
"com.wmdigit.setting.viewmodel.DataLearningViewModel"
/>
type=
"com.wmdigit.setting.viewmodel.DataLearningViewModel"
/>
<variable
name=
"activityViewModel"
type=
"com.wmdigit.setting.viewmodel.SettingViewModel"
/>
</data>
</data>
<FrameLayout
<FrameLayout
...
@@ -27,6 +30,7 @@
...
@@ -27,6 +30,7 @@
android:orientation=
"vertical"
android:orientation=
"vertical"
app:layout_constraintGuide_percent=
"0.46"
/>
app:layout_constraintGuide_percent=
"0.46"
/>
<!--右侧相机预览-->
<androidx.constraintlayout.widget.ConstraintLayout
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width=
"@dimen/dp_0"
android:layout_width=
"@dimen/dp_0"
android:layout_height=
"@dimen/dp_0"
android:layout_height=
"@dimen/dp_0"
...
@@ -44,25 +48,26 @@
...
@@ -44,25 +48,26 @@
app:layout_constraintStart_toStartOf=
"@+id/img_preview"
app:layout_constraintStart_toStartOf=
"@+id/img_preview"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintBottom_toTopOf=
"@+id/img_preview"
/>
app:layout_constraintBottom_toTopOf=
"@+id/img_preview"
/>
<!--相机预览图-->
<ImageView
<ImageView
android:id=
"@+id/img_preview"
android:id=
"@+id/img_preview"
android:layout_width=
"
@dimen/dp_720
"
android:layout_width=
"
wrap_content
"
android:layout_height=
"@dimen/dp_
54
0"
android:layout_height=
"@dimen/dp_0"
android:adjustViewBounds=
"true"
android:adjustViewBounds=
"true"
android:background=
"@color/black"
android:background=
"@color/black"
android:layout_marginTop=
"@dimen/dp_10"
android:layout_marginTop=
"@dimen/dp_10"
app:image=
"@{viewModel.frame}"
app:image=
"@{viewModel.frame}"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/tv_image_desc"
app:layout_constraintTop_toBottomOf=
"@+id/tv_image_desc"
app:layout_constraintBottom_toBottomOf=
"parent"
/>
/>
<TextView
<TextView
android:id=
"@+id/tv_camera_status"
android:id=
"@+id/tv_camera_status"
style=
"@style/text_base.content.white"
style=
"@style/text_base.content.white"
android:text=
"@string/camera_opening"
android:text=
"@string/camera_opening"
android:visibility=
"@{
viewModel.cameraOpened ? View.INVISIBLE : View.
VISIBLE}"
android:visibility=
"@{
!viewModel.cameraOpened && viewModel.frame != null ? View.VISIBLE : View.IN
VISIBLE}"
app:layout_constraintStart_toStartOf=
"@+id/img_preview"
app:layout_constraintStart_toStartOf=
"@+id/img_preview"
app:layout_constraintTop_toTopOf=
"@+id/img_preview"
app:layout_constraintTop_toTopOf=
"@+id/img_preview"
app:layout_constraintEnd_toEndOf=
"@+id/img_preview"
app:layout_constraintEnd_toEndOf=
"@+id/img_preview"
...
@@ -76,10 +81,11 @@
...
@@ -76,10 +81,11 @@
android:layout_width=
"@dimen/dp_0"
android:layout_width=
"@dimen/dp_0"
android:layout_height=
"@dimen/dp_0"
android:layout_height=
"@dimen/dp_0"
android:layout_margin=
"@dimen/dp_5"
android:layout_margin=
"@dimen/dp_5"
android:paddingBottom=
"@dimen/dp_15"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintEnd_toStartOf=
"@+id/gl_v_46"
app:layout_constraintEnd_toStartOf=
"@+id/gl_v_46"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintBottom_to
BottomOf=
"parent
"
/>
app:layout_constraintBottom_to
TopOf=
"@+id/tv_page
"
/>
<!--空数据的图-->
<!--空数据的图-->
<ImageView
<ImageView
...
...
module-setting/src/main/res/layout/layout_learning_correction_item.xml
0 → 100644
View file @
309f64be
<?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"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:paddingHorizontal=
"@dimen/dp_10"
android:paddingVertical=
"@dimen/dp_10"
android:layout_margin=
"@dimen/dp_5"
android:background=
"@drawable/sel_rect_10_white_gray"
>
<TextView
android:id=
"@+id/tv_product_name2"
style=
"@style/text_base.title"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:ellipsize=
"end"
android:maxLines=
"1"
android:text=
"商品名称"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"@+id/btn_del_all_learning_data"
app:layout_constraintBottom_toBottomOf=
"@+id/btn_del_all_learning_data"
/>
<TextView
android:id=
"@+id/tv_product_code2"
style=
"@style/text_base.content"
android:text=
"00000000"
android:layout_marginStart=
"@dimen/dp_10"
app:layout_constraintStart_toEndOf=
"@+id/tv_product_name2"
app:layout_constraintTop_toTopOf=
"@+id/tv_product_name2"
app:layout_constraintBottom_toBottomOf=
"@+id/tv_product_name2"
/>
<Button
android:id=
"@+id/btn_del_all_learning_data"
style=
"@style/button_base.w130.red"
android:layout_width=
"wrap_content"
android:paddingHorizontal=
"@dimen/dp_8"
android:text=
"@string/delete_all_learning_data"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
/>
<androidx.recyclerview.widget.RecyclerView
android:id=
"@+id/rv_local_images"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"@dimen/dp_10"
app:layout_constraintTop_toBottomOf=
"@+id/btn_del_all_learning_data"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
module-setting/src/main/res/layout/layout_local_image_item.xml
0 → 100644
View file @
309f64be
<?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"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_margin=
"@dimen/dp_3"
android:padding=
"@dimen/dp_3"
>
<ImageView
android:id=
"@+id/img_local_image"
android:layout_width=
"0dp"
android:layout_height=
"0dp"
android:scaleType=
"centerCrop"
android:adjustViewBounds=
"true"
app:layout_constraintDimensionRatio=
"1:1"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
module-setting/src/main/res/values/strings.xml
View file @
309f64be
...
@@ -66,4 +66,7 @@
...
@@ -66,4 +66,7 @@
<string
name=
"import_failed"
>
导入失败
</string>
<string
name=
"import_failed"
>
导入失败
</string>
<string
name=
"learn_local_image_success"
>
学习本地图片成功
</string>
<string
name=
"learn_local_image_success"
>
学习本地图片成功
</string>
<string
name=
"learn_local_image_fail"
>
学习本地图片失败
</string>
<string
name=
"learn_local_image_fail"
>
学习本地图片失败
</string>
<string
name=
"delete_all_learning_data"
>
删除学习记录
</string>
<string
name=
"confirm_del_photo"
>
请确认是否删除该照片
</string>
<string
name=
"confirm_del_all_photos_of_this_product"
>
请确认是否删除该商品所有照片
</string>
</resources>
</resources>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment