import Dialog from 'android.app.Dialog'; import Activity from 'android.app.Activity'; import Gravity from 'android.view.Gravity'; import ViewGroup from 'android.view.ViewGroup'; import View from 'android.view.View'; import Color from 'android.graphics.Color'; import R from 'io.dcloud.uts.prompt.R'; import TextView from 'android.widget.TextView'; import LayoutInflater from 'android.view.LayoutInflater'; import AppCompatTextView from 'androidx.appcompat.widget.AppCompatTextView'; import LinearLayoutCompat from 'androidx.appcompat.widget.LinearLayoutCompat'; import LinearLayoutManager from 'androidx.recyclerview.widget.LinearLayoutManager'; import RecyclerView from 'androidx.recyclerview.widget.RecyclerView'; import WindowManager from 'android.view.WindowManager'; import { ShowActionSheetOptions, ShowActionSheetSuccess} from '../interface.uts' // #ifdef UNI-APP-X import getCurrentPages from 'io.dcloud.uniapp.framework.getCurrentPages'; import onReady from 'io.dcloud.uniapp.framework.onReady'; import onUnload from 'io.dcloud.uniapp.framework.onUnload'; // #endif let uniActionSheet:UniActionSheet|null = null /** * 弹出功能入口 */ export function actionSheetImpl(style: ShowActionSheetOptions) { /** * 参数校验,itemList 不能为空 */ if(style.itemList == null || style.itemList.length < 1){ let res = new UniError("uni-prompt",-1,"showActionSheet:fail parameter error: parameter.itemList should have at least 1 item"); style.fail?.(res) style.complete?.(res) return ; } /** * 元素个数不能超过6个 */ if(style.itemList.size > 6){ let res = new UniError("uni-prompt",-2,"showActionSheet:fail parameter error: itemList should not be large than 6"); style.fail?.(res) style.complete?.(res) return ; } if(uniActionSheet != null){ uniActionSheet?.dismiss() uniActionSheet = null } // #ifndef UNI-APP-X /** * uni-app */ if(UTSAndroid.getTopPageActivity() == null){ return } if(UTSAndroid.getTopPageActivity()!.isFinishing()){ return } uniActionSheet = new UniActionSheet(UTSAndroid.getTopPageActivity()!, style) uniActionSheet?.show() UTSAndroid.onAppActivityDestroy(function(){ uniActionSheet?.dismiss() uniActionSheet = null }) // #endif // #ifdef UNI-APP-X /** * uni-app x * 需要特殊处理生命周期 */ const pages = getCurrentPages(); if (pages.length > 0) { const page = pages[pages.length - 1] const instance = page.$ if (page.$isReady) { if(UTSAndroid.getTopPageActivity() == null){ return } if(UTSAndroid.getTopPageActivity()!.isFinishing()){ return } uniActionSheet = new UniActionSheet(UTSAndroid.getTopPageActivity()!, style) uniActionSheet?.show() } else { onReady(() => { if(UTSAndroid.getTopPageActivity() == null){ return } if(UTSAndroid.getTopPageActivity()!.isFinishing()){ return } uniActionSheet = new UniActionSheet(UTSAndroid.getTopPageActivity()!, style) uniActionSheet?.show() }, instance) } onUnload(() => { uniActionSheet?.dismiss() uniActionSheet = null }, instance) } // #endif } /** * UniActionSheet * 功能实现 */ export class UniActionSheet extends Dialog{ /** * 宿主activity */ hostActivity: Activity /** * 宿主样式 */ hostStyle:ShowActionSheetOptions /** * 标题组件 */ title: AppCompatTextView /** * 取消按钮 */ cancel: AppCompatTextView /** * 列表 recycler */ myRecyclerView: RecyclerView /** * title 组件 */ lineTitle: LinearLayoutCompat /** * 内容组件 */ lineContent: LinearLayoutCompat /** * 取消组件 */ lineCancel: LinearLayoutCompat override dismiss():void { let res = new UniError("uni-prompt",1002,"showActionSheet:fail cancel"); this.hostStyle.fail?.(res) this.hostStyle.fail = null // 为了确保complete只调用一次,执行后手动置空 this.hostStyle.complete?.(res) this.hostStyle.complete = null super.dismiss() } constructor(activity: Activity, style: ShowActionSheetOptions) { super(activity,R.style.uni_prompt_ActionsheetDialog); this.hostActivity = activity this.hostStyle = style /** * 适配暗黑模式,配置不同的布局文件 */ if(UTSAndroid.getAppDarkMode()){ setContentView(R.layout.uni_prompt_uts_action_sheet_night) }else{ setContentView(R.layout.uni_prompt_uts_action_sheet) } this.title = findViewById(R.id.tvTitle) this.cancel = findViewById(R.id.tvCancelAction) this.lineTitle = findViewById(R.id.line_title) this.lineContent = findViewById(R.id.line_content) this.lineCancel = findViewById(R.id.line_cancel) this.myRecyclerView = findViewById(R.id.myRecyclerview) this.myRecyclerView.layoutManager = LinearLayoutManager(this.hostActivity) this.cancel.setOnClickListener(new CancelClickListener(this,this.hostStyle)); let recyclerviewAdapter = new ItemAdapter(this,this.hostStyle) this.myRecyclerView.adapter = recyclerviewAdapter if(!style.title.isNullOrBlank()){ this.lineTitle.setVisibility(View.VISIBLE) this.title.setText(style.title) } if(this.window != null){ this.window!.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT) this.window!.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); if(this.window!.attributes != null){ this.window!.attributes!.windowAnimations = R.style.uni_prompt_DialogAnimations_slideWindow; } } } } /** * 列表选项点击事件监听 */ class ItemClickListener extends View.OnClickListener{ host:Dialog hostStyle:ShowActionSheetOptions hostIndex:number constructor(dialog:Dialog,style: ShowActionSheetOptions,index:number){ super() this.host = dialog this.hostStyle = style this.hostIndex = index } override onClick(v?: View):void{ const res : ShowActionSheetSuccess = { tapIndex: this.hostIndex } this.hostStyle.success?.(res) this.hostStyle.success = null this.hostStyle.complete?.(res) this.hostStyle.complete = null // 点击触发成功后,去掉fail this.hostStyle.fail = null this.host.dismiss() } } /** * 取消按钮点击事件 */ class CancelClickListener extends View.OnClickListener{ host:Dialog hostStyle:ShowActionSheetOptions constructor(dialog:Dialog,style: ShowActionSheetOptions){ super() this.host = dialog this.hostStyle = style } override onClick(v?: View):void{ let res = new UniError("uni-prompt",1002,"showActionSheet:fail cancel"); this.hostStyle.fail?.(res) this.hostStyle.fail = null this.hostStyle.complete?.(res) this.hostStyle.complete = null this.host.dismiss() } } /** * 列表数据适配器 */ class ItemAdapter extends RecyclerView.Adapter{ mItemList: Array hostStyle:ShowActionSheetOptions hostDialog:Dialog constructor(dialog:Dialog ,style: ShowActionSheetOptions){ super() this.hostDialog = dialog this.mItemList = style.itemList this.hostStyle = style } /** * view 持有容器 */ ViewHolder = class extends RecyclerView.ViewHolder { itemName:TextView; constructor(view:View) { super(view); itemName = view.findViewById(R.id.tvName) as TextView; } } override getItemViewType(position: Int): Int { if(hostStyle.title.isNullOrBlank()){ // 无标题状态 if(position == 0){ return 1001 } return 1002 }else{ // 有标题状态 return 1002 } } override onCreateViewHolder( parent: ViewGroup, viewType: Int ): ViewHolder { let view: View if(viewType == 1002){ if(UTSAndroid.getAppDarkMode()){ view = LayoutInflater.from(parent.context).inflate(R.layout.uni_prompt_ac_recyclerview_layout_night, parent, false) }else{ view = LayoutInflater.from(parent.context).inflate(R.layout.uni_prompt_ac_recyclerview_layout, parent, false) } }else{ if(UTSAndroid.getAppDarkMode()){ view = LayoutInflater.from(parent.context).inflate(R.layout.uni_prompt_ac_recyclerview_layout_top_night, parent, false) }else{ view = LayoutInflater.from(parent.context).inflate(R.layout.uni_prompt_ac_recyclerview_layout_top, parent, false) } } return ViewHolder(view) } override onBindViewHolder(holder: ViewHolder, position: Int) { let perContent: String = mItemList[position] holder.itemName.setText(perContent) if(this.hostStyle.itemColor != null && isValidColor(this.hostStyle.itemColor)){ holder.itemName.setTextColor(Color.parseColor(this.hostStyle.itemColor)) } holder.itemName.setOnClickListener(new ItemClickListener(this.hostDialog,this.hostStyle,position)); } override getItemCount(): Int { return mItemList.size } } /** * 工具方法,判断一个color 字符串是否合法 */ function isValidColor(colorStr?:string):boolean{ if(colorStr == null){ return false } if(colorStr.length != 7){ return false } if(!colorStr.startsWith("#")){ return false } return true }