-- 陀螺仪视差模块:传感器监听 + 3D视差效果 + 传感器卡片组件 local sensor = {} -- ========== 模块私有变量(不对外暴露) ========== local dexLoader = nil local MySensorManager = nil local SwitchButtonClass = nil local sensorListener = nil local BackV = nil local SensorV = nil local noticeView = nil local lastDeltaX = 0 local lastDeltaY = 0 local mIsVertical = true local mIsShowing = true local mConfig = {} -- ========== 内部工具:复用外部传入的公共方法 ========== local function getpx(val) return mConfig.getpx(val) end local function getRes(name) return mConfig.getRes(name) end -- ========== 核心:传感器事件监听 ========== local function createSensorListener() return luajava.createProxy('android.hardware.SensorEventListener', { onSensorChanged = function(event) -- 悬浮窗隐藏时停止视差更新,节省性能 if not mIsShowing then return end local sensorList = table.list(event.values) -- 根据横竖屏自动切换坐标轴 local deltaX = sensorList[mIsVertical and 2 or 1] local deltaY = sensorList[mIsVertical and 1 or 2] -- 低通滤波,平滑抖动 local alpha = 0.5 deltaX = alpha * deltaX + (1 - alpha) * (lastDeltaX or 0) deltaY = alpha * deltaY + (1 - alpha) * (lastDeltaY or 0) lastDeltaX = deltaX lastDeltaY = deltaY -- 死区阈值,微小晃动不触发 local threshold = 0.1 if math.abs(deltaX) < threshold then deltaX = 0 end if math.abs(deltaY) < threshold then deltaY = 0 end -- 背景层:慢速度视差 local transX1 = BackV:getTranslationX() + deltaX * 2 BackV:setTranslationX(math.max(-mConfig.dp20, math.min(mConfig.dp20, transX1))) -- 前景层:快速度视差,营造3D感 local transX2 = SensorV:getTranslationX() + deltaX * 5 local transY2 = SensorV:getTranslationY() - deltaY * 2 transY2 = math.max(-mConfig.DP10, math.min(mConfig.DP10, transY2)) SensorV:setTranslationX(transX2) SensorV:setTranslationY(transY2) end, onAccuracyChanged = function() end }) end -- ========== 构建传感器卡片视图 ========== local function buildSensorCard() local layout = { LinearLayout, layout_width='match_parent', gravity='center', { MaterialCardView, layout_width='200dp', layout_height='100dp', useCompatPadding=false, cardElevation='5dp', layout_margin='5dp', cardBackgroundColor='#00f00000', strokeColor=0x00ffffff, __onCreate=function(v) v:setRadius(getpx('10dp') / 2) end, { LinearLayout, layout_width='250dp', layout_height='150dp', layout_gravity='center', orientation='horizontal', gravity='center', background=getRes('grb'), onClick=function() sensor.reset() -- 点击重置视差位置 end, onTouch = mConfig.dragHandler, -- 保留原拖拽逻辑 __onFinish=function(v) BackV = v -- 视图加载完成后初始化传感器管理器 if MySensorManager and sensorListener then MySensorManager(mConfig.context, sensorListener) end end, { LinearLayout, layout_width='160dp', layout_height='126dp', background=getRes('grc'), __onFinish=function(v) SensorV = v end, } }, -- 底部公告跑马灯 { TextView, textColor='#ffffff', textSize='10sp', ellipsize='marquee', id=luajava.ids['ggt'], scrollHorizontally=true, layout_width='match_parent', background='#bb000000', singleLine=true, focusable=true, layout_height='wrap_content', layout_gravity='bottom', __onFinish=function(v) noticeView = v v:setSelected(true) if mConfig.typeface then v:setTypeface(mConfig.typeface) end end, }, } } return luajava.loadlayout(layout) end -- ========== 对外公开接口 ========== --- 初始化模块 --- @param config table 依赖配置:context、getpx、getRes、dragHandler、typeface、isVertical、isShowing function sensor.init(config) mConfig = config mIsVertical = config.isVertical ~= nil and config.isVertical or true mIsShowing = config.isShowing ~= nil and config.isShowing or true -- 加载传感器dex包 dexLoader = dex.loadfile('/sdcard/Violet/图片/sensor.dex') MySensorManager = dexLoader:loadClass('com.changan.CACore.MySensorManager') SwitchButtonClass = dexLoader:loadClass('com.changan.CACore.SwitchButton') -- 创建传感器监听 sensorListener = createSensorListener() -- 预计算尺寸常量 mConfig.dp20 = getpx('20dp') mConfig.DP10 = getpx('10dp') end --- 获取传感器卡片视图,直接插入主界面即可 function sensor.getView() return buildSensorCard() end --- 重置视差位置到原点 function sensor.reset() if BackV then BackV:setTranslationX(0) BackV:setTranslationY(0) end if SensorV then SensorV:setTranslationX(0) SensorV:setTranslationY(0) end end --- 更新横竖屏状态,自动切换坐标轴 --- @param isVertical boolean function sensor.setOrientation(isVertical) mIsVertical = isVertical end --- 更新悬浮窗显示状态,隐藏时停止视差更新 --- @param isShowing boolean function sensor.setShowing(isShowing) mIsShowing = isShowing end --- 设置公告文本 --- @param text string function sensor.setNotice(text) if noticeView then luajava.runUiThread(function() noticeView:setText(text) end) end end --- 获取SwitchButton类(兼容原有开关控件) function sensor.getSwitchButtonClass() return SwitchButtonClass end --- 销毁模块,释放资源 function sensor.destroy() sensorListener = nil BackV = nil SensorV = nil noticeView = nil dexLoader = nil MySensorManager = nil SwitchButtonClass = nil end return sensor