android.widget.PopupWindow,生成Dialog

本文介绍如何使用Android的PopupWindow类创建弹窗对话框,并通过按钮事件实现文本输入与用户操作反馈。

	public static void showPopupWindow(Context context, View parent) {
		LayoutInflater inflater = (LayoutInflater) context
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		final View vPopupWindow = inflater.inflate(R.layout.popupwindow, null,
				false);
		final PopupWindow pw = new PopupWindow(vPopupWindow, 300, 300, true);

		// OK按钮及其处理事件
		Button btnOK = (Button) vPopupWindow.findViewById(R.id.BtnOK);
		btnOK.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// 设置文本框内容
				EditText edtUsername = (EditText) vPopupWindow
						.findViewById(R.id.username_edit);
				edtUsername.setText("username");
				EditText edtPassword = (EditText) vPopupWindow
						.findViewById(R.id.password_edit);
				edtPassword.setText("password");
			}
		});

		// Cancel按钮及其处理事件
		Button btnCancel = (Button) vPopupWindow.findViewById(R.id.BtnCancel);
		btnCancel.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				pw.dismiss();// 关闭
			}
		});
		// 显示popupWindow对话框
		pw.showAtLocation(parent, Gravity.CENTER, 0, 0);
	}


 

 

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#E6E6E6" tools:context=".MainActivity"> <ImageView android:id="@+id/iv" android:layout_width="70dp" android:layout_height="70dp" android:layout_gravity="center" android:layout_marginTop="30dp" android:background="@mipmap/head" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ffffff" android:orientation="horizontal" android:layout_gravity="center" android:layout_marginRight="10dp" android:layout_marginLeft="10dp" android:layout_marginTop="30dp"> <TextView android:id="@+id/tv_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=" 账号:" android:textSize="25sp" android:textStyle="bold"/> <EditText android:id="@+id/username" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toRightOf="@+id/tv_1" android:background="@null" android:maxLines="1"/> </RelativeLayout> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ffffff" android:orientation="horizontal" android:layout_marginTop="10dp" android:layout_marginRight="10dp" android:layout_marginLeft="10dp"> <TextView android:id="@+id/tv_2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=" 密码:" android:textSize="25sp" android:textStyle="bold" /> <EditText android:id="@+id/password" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toRightOf="@+id/tv_2" android:inputType="textPassword" android:background="@null" android:maxLines="1"/> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:layout_marginHorizontal="60dp"> <Button android:id="@+id/signup" android:layout_width="80dp" android:layout_height="50dp" android:background="#3C8DC4" android:text="注册" android:textColor="#ffffff" /> <Button android:id="@+id/login" android:layout_width="80dp" android:layout_height="50dp" android:background="#3C8DC4" android:layout_toRightOf="@+id/signup" android:layout_marginLeft="50dp" android:text="登录" android:textColor="#ffffff" /> </RelativeLayout> </LinearLayout><?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayout 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="match_parent" android:background="#80000000"> <com.google.android.material.card.MaterialCardView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="24dp" app:cardCornerRadius="16dp" app:cardElevation="8dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="24dp"> <!-- 标题栏 --> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="用户注册" android:textSize="20sp" android:textStyle="bold" android:layout_centerHorizontal="true" /> <ImageButton android:id="@+id/closeButton" android:layout_width="40dp" android:layout_height="40dp" android:layout_alignParentEnd="true" android:background="?attr/selectableItemBackgroundBorderless" android:src="@drawable/ic_close" android:contentDescription="关闭" /> </RelativeLayout> <!-- 用户名输入 --> <com.google.android.material.textfield.TextInputLayout android:id="@+id/registerUsernameLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="用户名" app:startIconDrawable="@drawable/ic_person" android:layout_marginBottom="16dp"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/registerUsernameEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textCapWords" android:imeOptions="actionNext" /> </com.google.android.material.textfield.TextInputLayout> <!-- 邮箱输入 --> <com.google.android.material.textfield.TextInputLayout android:id="@+id/registerEmailLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="邮箱地址" app:startIconDrawable="@drawable/ic_email" android:layout_marginBottom="16dp"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/registerEmailEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textEmailAddress" android:imeOptions="actionNext" /> </com.google.android.material.textfield.TextInputLayout> <!-- 密码输入 --> <com.google.android.material.textfield.TextInputLayout android:id="@+id/registerPasswordLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="密码" app:startIconDrawable="@drawable/ic_lock" app:endIconMode="password_toggle" android:layout_marginBottom="16dp"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/registerPasswordEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPassword" android:imeOptions="actionNext" /> </com.google.android.material.textfield.TextInputLayout> <!-- 确认密码输入 --> <com.google.android.material.textfield.TextInputLayout android:id="@+id/registerConfirmPasswordLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="确认密码" app:startIconDrawable="@drawable/ic_lock" app:endIconMode="password_toggle" android:layout_marginBottom="24dp"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/registerConfirmPasswordEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPassword" android:imeOptions="actionDone" /> </com.google.android.material.textfield.TextInputLayout> <!-- 注册按钮 --> <com.google.android.material.button.MaterialButton android:id="@+id/registerButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="注册" android:textAllCaps="false" app:icon="@drawable/ic_person_add" app:iconGravity="textStart" style="@style/Widget.Material3.Button.ElevatedButton" /> <!-- 底部提示 --> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="注册即表示您同意我们的服务条款和隐私政策" android:textSize="12sp" android:gravity="center" android:layout_marginTop="16dp" android:textColor="@color/gray" /> </LinearLayout> </com.google.android.material.card.MaterialCardView> </androidx.coordinatorlayout.widget.CoordinatorLayout>package com.example.login; import androidx.appcompat.app.AppCompatActivity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageButton; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private Button Bt_login; private Button BT_signup; private EditText Username; private EditText Password; static String username1; static String password1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Bt_login = (Button) findViewById(R.id.login); BT_signup = (Button) findViewById(R.id.signup); Username = (EditText) findViewById(R.id.username); Password = (EditText) findViewById(R.id.password); Onclick onclick = new Onclick(); Bt_login.setOnClickListener(onclick); BT_signup.setOnClickListener(onclick); } class Onclick implements View.OnClickListener { @Override public void onClick(View v) { int id = v.getId(); if (id == R.id.login) { String username = Username.getText().toString(); String password = Password.getText().toString(); if (password.equals(password1) && username.equals(username1)) { Intent intent = new Intent(); intent.setAction("android.intent.action.VIEW"); intent.setData(Uri.parse("https://www.baidu.com/")); startActivity(intent); } else { AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); builder.setTitle("warning") .setMessage("您输入错误,请重新输入 您也有可能未注册") .setPositiveButton("重新登录", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Intent intent = new Intent(MainActivity.this, MainActivity.class); startActivity(intent); } }).setNegativeButton("退出", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(getApplicationContext(), "正在退出", Toast.LENGTH_LONG).show(); } }).show(); } } else if (id == R.id.signup) { showRegisterDialog(); } else { throw new IllegalStateException("Unexpected value: " + v.getId()); } } } private void showRegisterDialog() { // 创建自定义对话框 AlertDialog.Builder builder = new AlertDialog.Builder(this); // 获取布局填充器 LayoutInflater inflater = getLayoutInflater(); View dialogView = inflater.inflate(R.layout.popupwindow_register, null); // 获取对话框中的控件 EditText registerUsername = dialogView.findViewById(R.id.registerUsernameEditText); EditText registerEmail = dialogView.findViewById(R.id.registerEmailEditText); EditText registerPassword = dialogView.findViewById(R.id.registerPasswordEditText); EditText registerConfirmPassword = dialogView.findViewById(R.id.registerConfirmPasswordEditText); Button registerButton = dialogView.findViewById(R.id.registerButton); ImageButton closeButton = dialogView.findViewById(R.id.closeButton); // 创建对话框 AlertDialog dialog = builder.setView(dialogView).create(); // 设置关闭按钮点击事件 closeButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dialog.dismiss(); } }); // 设置注册按钮点击事件 registerButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String username = registerUsername.getText().toString(); String email = registerEmail.getText().toString(); String password = registerPassword.getText().toString(); String confirmPassword = registerConfirmPassword.getText().toString(); // 输入验证 if (username.isEmpty()) { Toast.makeText(MainActivity.this, "请输入用户名", Toast.LENGTH_SHORT).show(); return; } if (email.isEmpty() || !android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()) { Toast.makeText(MainActivity.this, "请输入有效的邮箱地址", Toast.LENGTH_SHORT).show(); return; } if (password.isEmpty() || password.length() < 6) { Toast.makeText(MainActivity.this, "密码长度至少6位", Toast.LENGTH_SHORT).show(); return; } if (!password.equals(confirmPassword)) { Toast.makeText(MainActivity.this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); return; } // 注册成功 username1 = username; password1 = password; // 同时更新主界面的用户名和密码输入框 Username.setText(username); Password.setText(password); Toast.makeText(MainActivity.this, "注册成功", Toast.LENGTH_LONG).show(); dialog.dismiss(); } }); // 显示对话框 dialog.show(); // 设置对话框宽度匹配父布局 if (dialog.getWindow() != null) { dialog.getWindow().setLayout(android.view.ViewGroup.LayoutParams.MATCH_PARENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT); } } } ERROR: AAPT: error: resource style/Theme.Material3.Light.DarkActionBar (aka com.example.login:style/Theme.Material3.Light.DarkActionBar) not found. error: failed linking references.
最新发布
09-27
然后我该怎么在acitvity-viewpager2-fragment-recyclerview 然后根据activity里的长按逻辑 删除itempackage com.example.assignment.client; import android.content.Intent; import android.os.Bundle; import android.view.Gravity; import android.view.View; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.RecyclerView; import androidx.viewpager2.widget.ViewPager2; import com.example.assignment.R; import com.example.assignment.client.repo.ClientItem; import com.example.assignment.databinding.ActivityClientBinding; import com.example.assignment.login.CreateIDActivity; import com.example.assignment.login.LoginChooseActivity; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.tabs.TabLayoutMediator; import com.tplink.apps.architecture.BaseMvvmActivity; import com.tplink.design.menu.TPListPopupWindow; import com.tplink.design.menu.TPSimplePopupAdapter; import com.tplink.design.menu.TPSimplePopupMenuItem; import java.util.ArrayList; import java.util.List; public class ClientActivity extends BaseMvvmActivity<ActivityClientBinding> { private int currentPagePosition = 0; // 当前页面位置 @Nullable @Override protected ActivityClientBinding bindContentView(@Nullable Bundle bundle) { return ActivityClientBinding.inflate(getLayoutInflater()); } @Override protected void subscribeViewModel(@Nullable Bundle bundle) { // 设置适配器 ViewPagerAdapter adapter = new ViewPagerAdapter(this); viewBinding.viewPager.setAdapter(adapter); viewBinding.viewPager.setOffscreenPageLimit(2); // 预加载所有页面 // 添加页面切换监听 viewBinding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override public void onPageSelected(int position) { currentPagePosition = position; } }); // 设置Fragment监听(延迟执行以确保Fragment已创建) viewBinding.viewPager.post(() -> { setupFragmentListeners(); if (viewBinding.viewPager.getCurrentItem() == 1) { // 如果初始在页面2 currentPagePosition = 1; // 手动设置位置 } }); // 启用嵌套滚动 View child = viewBinding.viewPager.getChildAt(0); if (child instanceof RecyclerView) { RecyclerView recyclerView = (RecyclerView) child; recyclerView.setNestedScrollingEnabled(true); } // 关联TabLayout和ViewPager2 new TabLayoutMediator(viewBinding.tabLayout, viewBinding.viewPager, (tab, position) -> { if (position == 0) { tab.setText("Main"); } else { tab.setText("Guest"); } }).attach(); viewBinding.toolbar.setOnMenuItemClickListener(v -> { Intent intent = new Intent(ClientActivity.this, BlockListActivity.class); startActivity(intent); return false; }); } // 为Fragment设置监听器 private void setupFragmentListeners() { Fragment mainFragment = getSupportFragmentManager().findFragmentByTag("f0"); // ViewPager2的Fragment标签规则:f + position Fragment guestFragment = getSupportFragmentManager().findFragmentByTag("f1"); if (mainFragment instanceof MainNetworkFragment) { ((MainNetworkFragment) mainFragment).setOnItemLongClickListener((view, position, isOnline) -> { showPopupMenuForItem(view, position, isOnline); }); } if (guestFragment instanceof GuestNetworkFragment) { ((GuestNetworkFragment) guestFragment).setOnItemLongClickListener((view, position, isOnline) -> { showPopupMenuForItem(view, position, isOnline); }); } } // 修改弹出窗口方法,增加位置参数 public void showPopupMenuForItem(View v, int itemPosition, boolean isOnline) { List<TPSimplePopupMenuItem> menuItems = new ArrayList<>(); menuItems.add(new TPSimplePopupMenuItem("Block", R.drawable.ic_block_black)); if(!isOnline) { menuItems.add(new TPSimplePopupMenuItem("Delete", R.drawable.ic_delete_24)); } TPListPopupWindow popupWindow = new TPListPopupWindow(this, v); popupWindow.setAdapter(new TPSimplePopupAdapter(this, menuItems)); popupWindow.setDropDownGravity(Gravity.END); // 添加菜单点击处理 popupWindow.setOnItemClickListener((parent, view1, menuPosition, id) -> { // 通过菜单位置区分点击项 if (menuPosition == 0) { // "Block" 是第一个菜单项 handleBlockAction(itemPosition, isOnline); } else if (menuPosition == 1) { // "Delete" 是第二个菜单项 handleDeleteAction(itemPosition, isOnline); } // popupWindow.dismiss(); }); popupWindow.show(); } // 处理 Block 操作 private void handleBlockAction(int devicePosition, boolean isOnline) { // 根据位置获取设备信息(需补充获取数据的方法) // ClientItem device = getDeviceByPosition(devicePosition, isOnline); new MaterialAlertDialogBuilder(this) .setTitle("Add to Block List") .setMessage("确定将XX设备加入黑名单?") .setPositiveButton("yes", (dialogInterface, i) -> { // todo sth }) .setNegativeButton("no", null) .show(); } private void handleDeleteAction(int devicePosition, boolean isOnline) { // 根据位置获取设备信息(需补充获取数据的方法) // ClientItem device = getDeviceByPosition(devicePosition, isOnline); new MaterialAlertDialogBuilder(this) .setTitle("Delete") .setMessage("确定删除吗?") .setPositiveButton("yes", (dialogInterface, i) -> { // todo sth }) .setNegativeButton("no", null) .show(); } // 根据位置获取设备(示例方法) // private ClientItem getDeviceByPosition(int position, boolean isOnline) { // // 需要根据当前网络类型获取对应数据源 // List<ClientItem> dataSource = isOnline ? onlineDevices : offlineDevices; // return dataSource.get(position); // } }
09-19
package com.example.suyzeko.fragment; import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.ActivityInfo; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.viewpager2.widget.ViewPager2; import android.os.Handler; import android.os.IBinder; import android.util.TypedValue; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; import android.widget.Button; import android.widget.ImageButton; import android.widget.PopupWindow; import android.widget.TextView; import android.widget.Toast; import com.example.suyzeko.MainActivity; import com.example.suyzeko.activitys.ledPanel.sixRoads.DeviceDetailsActivity; import com.example.suyzeko.activitys.ledPanel.twoRoads.PhototherapyBoardTwoActivity; import com.example.suyzeko.R; import com.example.suyzeko.SelectDeviceActivity; import com.example.suyzeko.activitys.therapyHelmet.fourZones.TherapyHelmetFourActivity; import com.example.suyzeko.activitys.therapyHelmet.nineteenZones.TherapyHelmetNineteenActivity; import com.example.suyzeko.entity.Device; import com.example.suyzeko.entity.DeviceClass; import com.example.suyzeko.service.BluetoothService; import com.example.suyzeko.utils.BannerAdapter; import com.example.suyzeko.utils.DeviceUtils; import com.example.suyzeko.utils.RetrofitAPI; import com.example.suyzeko.utils.RetrofitClient; import com.google.android.flexbox.FlexboxLayout; import java.util.Arrays; import java.util.List; import java.util.Objects; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; public class DashboardFragment extends Fragment{ private ViewPager2 viewPager; private FlexboxLayout flexboxContainer; private int buttonCount = 0; private View maskView; // 遮罩层视图 private PopupWindow popupWindow; private final Handler autoScrollHandler = new Handler(); private ImageButton btnAdd; private TextView textView; private BluetoothService bluetoothService; // 蓝牙后台服务实例 private final Runnable autoScrollRunnable = new Runnable() { @Override public void run() { if (viewPager != null) { int currentItem = viewPager.getCurrentItem(); viewPager.setCurrentItem(currentItem + 1, true); autoScrollHandler.postDelayed(this, 3000); // 3秒切换一次 } } }; private boolean isBound = false; private float flexBasisPercent = 0.4f; private int buttonHeight = 90; /** * 服务连接回调 */ private final ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { try { BluetoothService.LocalBinder binder = (BluetoothService.LocalBinder) service; bluetoothService = binder.getService(); isBound = true; registerReceivers(); // 注册广播接收器 } catch (SecurityException e) { throw new RuntimeException(e); } } @Override public void onServiceDisconnected(ComponentName name) { isBound = false; } }; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_dashboard, container, false); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); if (DeviceUtils.isTablet(requireActivity())) { flexBasisPercent = 0.22f; buttonHeight = 110; } else { // 手机设备 } viewPager = view.findViewById(R.id.viewPager); textView = view.findViewById(R.id.device_num); // 示例图片列表 List<Integer> images = Arrays.asList( R.drawable.ontc, R.drawable.offtc ); // 绑定服务 if (bluetoothService != null){ Intent intentBlue = new Intent(getActivity(), BluetoothService.class); bluetoothService.bindService(intentBlue, connection, Context.BIND_AUTO_CREATE); } // 初始化适配器并绑定 BannerAdapter adapter = new BannerAdapter(images); viewPager.setAdapter(adapter); // 设置初始位置(从中间开始,支持向左滑动) viewPager.setCurrentItem(Integer.MAX_VALUE / 2, false); // 自动轮播 autoScrollHandler.postDelayed(autoScrollRunnable, 3000); // 页面切换监听(可选) viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override public void onPageSelected(int position) { // 可以在此处理指示器逻辑 } }); flexboxContainer = view.findViewById(R.id.flexbox_container); // 初始化检查:如果没有按钮,显示添加按钮 checkAndShowAddButton(); // 获取加号按钮 btnAdd = view.findViewById(R.id.add_image_button); // 设置点击事件 btnAdd.setOnClickListener(this::showPopupMenu); } @Override public void onAttach(@NonNull Context context) { super.onAttach(context); if (context instanceof OnJumpToActivityListener) { onJumpToActivityListener = (OnJumpToActivityListener) context; } else { throw new RuntimeException("宿主 Activity 需实现 OnJumpToActivityListener"); } } @Override public void onResume(){ super.onResume(); loadActivity(); updateConnectionStatus(); } @Override public void onDestroyView() { super.onDestroyView(); autoScrollHandler.removeCallbacks(autoScrollRunnable); // 防止内存泄漏 // 确保 Fragment 销毁时移除遮罩 removeMask(); super.onDestroy(); } /** * 显示/隐藏"添加按钮"的逻辑 */ private void checkAndShowAddButton() { if (buttonCount == 0) { // 创建"添加按钮" Button addButton = new Button(requireContext()); addButton.setTextColor(Color.parseColor("#2A2A2A")); addButton.setBackgroundResource(R.drawable.button_style); // 可自定义样式 addButton.setText(getString(R.string.add)); // 布局参数 FlexboxLayout.LayoutParams params = new FlexboxLayout.LayoutParams( FlexboxLayout.LayoutParams.WRAP_CONTENT, FlexboxLayout.LayoutParams.WRAP_CONTENT ); params.setFlexBasisPercent(flexBasisPercent); params.setHeight(dpToPx(buttonHeight)); params.setMargins(32, 16, 32, 16); // 点击事件:开始添加普通按钮 addButton.setOnClickListener(v -> { onJumpToActivityListener.jumpToActivityAndClose();// 跳转到搜索设备页面 // navigateToNewActivity(); }); buttonCount++; flexboxContainer.addView(addButton, params); } } private List<Device> deviceLists; /** * 添加动态按钮的方法 * @param deviceList */ public void addNewButton(List<Device> deviceList) { for (Device device:deviceList){ int flag = 0; if(deviceLists != null){ for (Device device1:deviceLists){ if (device1.getDeviceMac().equals(device.getDeviceMac())) { flag = 1; break; } } } if (flag == 1){ continue; } buttonCount++; DeviceClass deviceTypeResources = getDeviceTypeResources(device.getDeviceClassCode()); Button newButton = new Button(requireContext()); newButton.setTag(device); newButton.post(() -> { // 获取按钮实际宽高(单位:像素) int buttonWidth = newButton.getWidth(); int buttonHeight = newButton.getHeight(); // 动态计算文字大小(示例:按钮宽度的 1/6) float textSizePx = buttonWidth / 20f; // 转换为 sp 单位(更符合用户习惯) float textSizeSp = pxToSp(textSizePx); // 设置文字大小 newButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSizeSp); }); // 创建状态图标层叠Drawable Drawable statusIcon = createStatusIcon(device); newButton.setText(device.getDeviceName()); // 获取设备类型对应的图标资源 Drawable icon = ContextCompat.getDrawable(requireContext(), deviceTypeResources.getIconRes()); // 计算按钮实际高度(从布局参数获取) int buttonHeightPx = dpToPx(buttonHeight); // 需与布局中params.setHeight(dpToPx(90))一致 // 设置图标尺寸为按钮高度的60%(按需调整比例) int iconSize = (int) (buttonHeightPx * 0.6); if (icon != null) { // 保持图标宽高比 float aspectRatio = (float) icon.getIntrinsicWidth() / icon.getIntrinsicHeight(); int scaledWidth = (int) (iconSize * aspectRatio); icon.setBounds(0, 0, scaledWidth, iconSize); // 设置绘制区域 } // 设置图标到按钮左侧 newButton.setCompoundDrawables(statusIcon, icon, null, null); newButton.setCompoundDrawablePadding(8); newButton.setBackgroundResource(R.drawable.button_style); newButton.setTextColor(Color.parseColor("#2A2A2A")); // 布局参数(与之前相同) FlexboxLayout.LayoutParams params = new FlexboxLayout.LayoutParams( FlexboxLayout.LayoutParams.WRAP_CONTENT, FlexboxLayout.LayoutParams.WRAP_CONTENT ); params.setFlexBasisPercent(flexBasisPercent); params.setHeight(dpToPx(buttonHeight)); params.setMargins(32, 16, 32, 16); // 点击事件 newButton.setOnClickListener(v -> { if (bluetoothService != null && bluetoothService.getConnectedDevice() != null){ if(device.getDeviceMac().equals(bluetoothService.getMACAddress())){ navigateToNewDeviceDetailsActivity(device); }else { new AlertDialog.Builder(getContext()) .setTitle("Device not connected") .setMessage("Do you want to redirect to the device connection page") // 确认按钮 .setPositiveButton(getString(R.string.OK), (dialog, which) -> { onJumpToActivityListener.jumpToActivityAndClose(); // 跳转到搜索设备页面 }) // 取消按钮 .setNegativeButton(getString(R.string.Cancel), (dialog, which) -> { dialog.dismiss(); }) .show(); } }else { new AlertDialog.Builder(getContext()) .setTitle("Device not connected") .setMessage("Do you want to redirect to the device connection page") // 确认按钮 .setPositiveButton(getString(R.string.OK), (dialog, which) -> { onJumpToActivityListener.jumpToActivityAndClose(); // 跳转到搜索设备页面 }) // 取消按钮 .setNegativeButton(getString(R.string.Cancel), (dialog, which) -> { dialog.dismiss(); }) .show(); } }); // // 长按删除(增加删除后的检查) // newButton.setOnLongClickListener(v -> { // flexboxContainer.removeView(v); // buttonCount--; // checkAndShowAddButton(); // 删除后检查是否需要恢复"添加按钮" // return true; // }); // 将新按钮添加到第一个 flexboxContainer.addView(newButton, 0, params); // --- 关键修改:强制刷新父容器和滚动视图 --- flexboxContainer.post(new Runnable() { @Override public void run() { flexboxContainer.requestLayout(); // 触发 NestedScrollView 重新计算滚动范围 ViewParent parent = flexboxContainer.getParent(); if (parent instanceof ViewGroup) { ((ViewGroup) parent).requestLayout(); } } }); } textView.setText(String.valueOf(buttonCount-1)); } public void updateConnectionStatus() { for (int i = 0; i < flexboxContainer.getChildCount() - 1; i++) { View view = flexboxContainer.getChildAt(i); if (view instanceof Button) { Button btn = (Button) view; Device device = (Device) btn.getTag(); Drawable newStatus = createStatusIcon(device); DeviceClass deviceTypeResources = getDeviceTypeResources(device.getDeviceClassCode()); // 获取设备类型对应的图标资源 Drawable icon = ContextCompat.getDrawable(requireContext(), deviceTypeResources.getIconRes()); // 计算按钮实际高度(从布局参数获取) int buttonHeightPx = dpToPx(buttonHeight); // 设置图标尺寸为按钮高度的60%(按需调整比例) int iconSize = (int) (buttonHeightPx * 0.6); if (icon != null) { // 保持图标宽高比 float aspectRatio = (float) icon.getIntrinsicWidth() / icon.getIntrinsicHeight(); int scaledWidth = (int) (iconSize * aspectRatio); icon.setBounds(0, 0, scaledWidth, iconSize); // 设置绘制区域 } // 设置图标到按钮左侧 btn.setCompoundDrawables(newStatus, icon, null, null); btn.postInvalidate(); // 线程安全刷新 } } } public void updateUnConnectionStatus() { for (int i = 0; i < flexboxContainer.getChildCount() - 1; i++) { View view = flexboxContainer.getChildAt(i); if (view instanceof Button) { Button btn = (Button) view; Device device = (Device) btn.getTag(); if(bluetoothService!= null && device.getDeviceMac().equals(bluetoothService.getMACAddress())){ bluetoothService.disconnect(); Drawable newStatus = createStatusIcon(device); DeviceClass deviceTypeResources = getDeviceTypeResources(device.getDeviceClassCode()); // 获取设备类型对应的图标资源 Drawable icon = ContextCompat.getDrawable(requireContext(), deviceTypeResources.getIconRes()); // 计算按钮实际高度(从布局参数获取) int buttonHeightPx = dpToPx(buttonHeight); // 设置图标尺寸为按钮高度的60%(按需调整比例) int iconSize = (int) (buttonHeightPx * 0.6); if (icon != null) { // 保持图标宽高比 float aspectRatio = (float) icon.getIntrinsicWidth() / icon.getIntrinsicHeight(); int scaledWidth = (int) (iconSize * aspectRatio); icon.setBounds(0, 0, scaledWidth, iconSize); // 设置绘制区域 } // 设置图标到按钮左侧 btn.setCompoundDrawables(newStatus, icon, null, null); btn.postInvalidate(); // 线程安全刷新 } } } } private Drawable createStatusIcon(Device device) { // 获取状态图标资源 int statusRes = isDeviceConnected(device) ? R.drawable.ic_connected_green_round : R.drawable.ic_disconnected_hui_round; // 创建缩放后的状态图标 Drawable statusIcon = ContextCompat.getDrawable(requireContext(), statusRes); int statusSize = dpToPx(12); // 状态图标尺寸 if (statusIcon != null) { statusIcon.setBounds(0, 0, statusSize, statusSize); } return statusIcon; } private boolean isDeviceConnected(Device device) { return bluetoothService != null && bluetoothService.getConnectedDevice() != null && device.getDeviceMac().equals(bluetoothService.getMACAddress()); } /** * 定义类型映射关系 * @param * @return */ private DeviceClass getDeviceTypeResources(String deviceClassCode) { DeviceClass deviceClass; if(deviceClassCode.equals("5A A5 01 01")){ deviceClass = new DeviceClass(0,R.drawable.up_down_black, "ELEVATING WHIRLING LED PANEL"); }else if(deviceClassCode.equals("5A A5 02 02")){ deviceClass = new DeviceClass(1,R.drawable.ontc, "红光床"); }else { deviceClass = new DeviceClass(2,R.drawable.up_down_black, "ELEVATING WHIRLING LED PANEL"); } return deviceClass; } /** * 弹出菜单 * @param anchorView */ public void showPopupMenu(View anchorView) { // 初始化布局 View popupView = LayoutInflater.from(requireContext()).inflate(R.layout.menu_popup_layout, null); // 创建 PopupWindow popupWindow = new PopupWindow( popupView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true ); // 设置背景和动画 popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); popupWindow.setElevation(8); // 阴影效果 popupWindow.setAnimationStyle(R.style.PopupAnimation); // 自定义动画 // 处理菜单项点击 popupView.findViewById(R.id.menu_item_add).setOnClickListener(v -> { // 处理“添加设备”逻辑 popupWindow.dismiss(); navigateToNewActivity(); }); popupView.findViewById(R.id.menu_item_scan).setOnClickListener(v -> { // 处理“扫一扫”逻辑 popupWindow.dismiss(); }); // 添加遮罩层 addMask(); // 设置 PopupWindow 关闭时移除遮罩 popupWindow.setOnDismissListener(() -> removeMask()); // 显示菜单(相对于锚点视图) popupWindow.showAsDropDown(anchorView, dpToPx(-130), dpToPx(15), Gravity.END); } /** * 将遮罩层添加到 Activity 的根布局 */ private void addMask() { if (getActivity() == null) return; ViewGroup rootView = (ViewGroup) getActivity().getWindow().getDecorView(); maskView = LayoutInflater.from(getContext()).inflate(R.layout.layout_background_mask, null); rootView.addView(maskView); } /** * 移除遮罩层 */ private void removeMask() { if (getActivity() == null || maskView == null) return; ViewGroup rootView = (ViewGroup) getActivity().getWindow().getDecorView(); rootView.removeView(maskView); maskView = null; } /** * 跳转查找设备Activity */ private void navigateToNewActivity() { if (getActivity() == null) return; // 避免 Fragment 未附加到 Activity 时崩溃 Intent intent = new Intent(getActivity(), SelectDeviceActivity.class); startActivity(intent); } /** * 跳转到新 Activity * @param device */ private void navigateToNewDeviceDetailsActivity(Device device) { if (getActivity() == null) return; // 避免 Fragment 未附加到 Activity 时崩溃 if(device.getDeviceClassCode().equals("5A A5 01 02")){ Intent intent = new Intent(getActivity(), PhototherapyBoardTwoActivity.class); intent.putExtra("devices",device); startActivity(intent); }else if(device.getDeviceClassCode().equals("5A A5 01 01")){ Intent intent = new Intent(getActivity(), DeviceDetailsActivity.class); intent.putExtra("devices",device); startActivity(intent); }else if(device.getDeviceClassCode().equals("5A A5 02 01")){ Intent intent = new Intent(getActivity(), TherapyHelmetFourActivity.class); intent.putExtra("devices",device); startActivity(intent); }else if(device.getDeviceClassCode().equals("5A A5 02 05")){ Intent intent = new Intent(getActivity(), TherapyHelmetNineteenActivity.class); intent.putExtra("devices",device); startActivity(intent); } } /** * 像素转 sp * @param px * @return */ private float pxToSp(float px) { return px / getResources().getDisplayMetrics().scaledDensity; } /** * dp 转像素工具方法 */ private int dpToPx(int dp) { float density = getResources().getDisplayMetrics().density; return Math.round(dp * density); } /** * 获取用户设备列表 */ private void loadActivity() { // 创建Retrofit服务实例 RetrofitAPI api = RetrofitClient.getClient(getActivity()).create(RetrofitAPI.class); // 发起异步请求 api.deviceFindAll().enqueue(new Callback<List<Device>>() { @Override public void onResponse(Call<List<Device>> call, Response<List<Device>> response) { if (response.isSuccessful() && response.body() != null) { addNewButton(response.body()); deviceLists = response.body(); } } @Override public void onFailure(Call<List<Device>> call, Throwable t) { if (getActivity() != null) { Toast.makeText(getContext(), "网络错误: " + t.getMessage(), Toast.LENGTH_SHORT).show(); // // todo 离线 // DevicesRepository devicesRepository = new DevicesRepository(getActivity()); // List<Devices> deviceByUsername = devicesRepository.getDevicesByUserId(1L); // List<Device> list = new ArrayList<>(); // for (Devices devices:deviceByUsername){ // Device device = new Device(); // device.setDeviceMac(devices.getDeviceMac()); // device.setDeviceName(devices.getDeviceName()); // device.setDeviceClassCode(String.valueOf(devices.getDeviceClassId())); // device.setUserId(devices.getUserId()); // list.add(device); // } // addNewButton(list); // deviceLists = list; // // / } } }); } /** * 注册本地广播接收器 * 用于接收来自BluetoothService的事件 */ private void registerReceivers() { IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothService.ACTION_CONNECTION_STATUS); // 连接状态变化 LocalBroadcastManager.getInstance(getActivity()) .registerReceiver(btReceiver, filter); // 注册广播接收器 } /** * 蓝牙事件广播接收器 * 处理三种事件: * 1. 发现新设备 - 更新设备列表 * 2. 连接状态变化 - 更新UI状态 * 3. 接收到数据 - 显示在消息框 */ private final BroadcastReceiver btReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { try { String action = intent.getAction(); if (BluetoothService.ACTION_CONNECTION_STATUS.equals(action)) { // 更新连接状态显示 String status = intent.getStringExtra(BluetoothService.EXTRA_STATUS); if(status.equals("DISCONNECTED")){ updateUnConnectionStatus(); } } } catch (SecurityException e) { throw new RuntimeException(e); } } }; @Override public void onStart() { super.onStart(); Intent intent = new Intent(getActivity(), BluetoothService.class); getActivity().bindService(intent, connection, Context.BIND_AUTO_CREATE); // 绑定服务 } @Override public void onStop() { super.onStop(); if (isBound) { getActivity().unbindService(connection); // 解绑服务‌ isBound = false; } LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(btReceiver); } private OnJumpToActivityListener onJumpToActivityListener; // 在 Fragment 中定义接口 public interface OnJumpToActivityListener { void jumpToActivityAndClose(); } }但设备按钮为4个时 手机版本显示顺序没问题 但平板版本的+add按钮会在第六个按钮的位置 而不是第五个
07-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值