如何点击FAB创建带EditText和ImageButtons的弹窗/Activity(仿Todoist)
Hey there! I’ve got you covered on both of these tasks—let’s dive into practical, working implementations for each.
1. Create a Popup/Activity with EditText & ImageButtons on FAB Click
You’ve got two solid options here: using a Dialog (lighter weight, stays within your current screen) or a Dialog-themed Activity (more flexible if you need extra functionality). Let’s cover both.
Option 1: Using a Custom Dialog
First, create your dialog layout (let’s call it dialog_custom_input.xml):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> <!-- Your EditText for input --> <EditText android:id="@+id/et_input" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Enter your text..." android:inputType="text"/> <!-- ImageButtons for actions --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="end" android:layout_marginTop="12dp"> <ImageButton android:id="@+id/btn_cancel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_cancel" android:background="?attr/selectableItemBackgroundBorderless"/> <ImageButton android:id="@+id/btn_save" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_save" android:background="?attr/selectableItemBackgroundBorderless" android:layout_marginStart="16dp"/> </LinearLayout> </LinearLayout>
Then, in your Activity/Fragment, handle the FAB click to show the dialog:
// Inside your Activity/Fragment fab.setOnClickListener { val dialog = Dialog(this) dialog.setContentView(R.layout.dialog_custom_input) // Get references to views val etInput = dialog.findViewById<EditText>(R.id.et_input) val btnCancel = dialog.findViewById<ImageButton>(R.id.btn_cancel) val btnSave = dialog.findViewById<ImageButton>(R.id.btn_save) // Handle cancel click btnCancel.setOnClickListener { dialog.dismiss() } // Handle save click btnSave.setOnClickListener { val inputText = etInput.text.toString() // Do something with the input text dialog.dismiss() } dialog.show() }
Option 2: Using a Dialog-Themed Activity
If you need more control (like handling lifecycle events), create a new Activity and set its theme to a dialog style in AndroidManifest.xml:
<activity android:name=".InputActivity" android:theme="@style/Theme.AppCompat.Dialog" android:windowSoftInputMode="adjustResize"/>
Then design its layout just like the dialog above, and start it from the FAB click:
fab.setOnClickListener { startActivity(Intent(this, InputActivity::class.java)) }
2. Todoist-Style Bottom Popup (Stays Above Keyboard)
For this, BottomSheetDialogFragment is the perfect tool—it’s designed for bottom-aligned popups and can easily adapt to the soft keyboard.
Step 1: Create the Bottom Sheet Layout (bottom_sheet_todoist.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> <EditText android:id="@+id/et_todo_input" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Add a task..." android:inputType="text" android:textSize="18sp"/> <!-- Add your ImageButtons or other actions here --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="end" android:layout_marginTop="12dp"> <ImageButton android:id="@+id/btn_close" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_close" android:background="?attr/selectableItemBackgroundBorderless"/> <ImageButton android:id="@+id/btn_add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_add" android:background="?attr/selectableItemBackgroundBorderless" android:layout_marginStart="16dp"/> </LinearLayout> </LinearLayout>
Step 2: Create the BottomSheetDialogFragment Subclass
class TodoistBottomSheet : BottomSheetDialogFragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.bottom_sheet_todoist, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val etTodoInput = view.findViewById<EditText>(R.id.et_todo_input) val btnClose = view.findViewById<ImageButton>(R.id.btn_close) val btnAdd = view.findViewById<ImageButton>(R.id.btn_add) // Auto-focus the EditText and show keyboard when the sheet opens etTodoInput.requestFocus() val imm = requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager imm.showSoftInput(etTodoInput, InputMethodManager.SHOW_IMPLICIT) btnClose.setOnClickListener { dismiss() } btnAdd.setOnClickListener { val taskText = etTodoInput.text.toString() // Handle adding the task dismiss() } } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val dialog = super.onCreateDialog(savedInstanceState) // Ensure the sheet resizes when keyboard pops up dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) return dialog } }
Step 3: Show the Bottom Sheet from FAB Click
In your Activity/Fragment:
fab.setOnClickListener { TodoistBottomSheet().show(supportFragmentManager, "TodoistBottomSheet") }
Key Notes for Keyboard Adaptation:
- The
SOFT_INPUT_ADJUST_RESIZEflag tells the system to resize the bottom sheet when the keyboard appears, keeping it above the keyboard (just like Todoist). - Auto-focusing the EditText and showing the keyboard immediately makes the experience feel responsive, matching Todoist’s behavior.
内容的提问来源于stack exchange,提问作者Jake Iarmilko

