求助:实现9个带边框方形EditText点击时修改自身边框颜色
Hey there! Let's get those EditText borders switching properly when clicked. I'll walk you through a few reliable approaches—pick the one that matches exactly what you need for your 9 square EditTexts.
First: Double-Check Your Border Drawables
Before diving into code, make sure your border1.xml and border2.xml are set up correctly in the res/drawable folder. Here’s a standard template you can adapt:
border1.xml (default state):
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <stroke android:width="2dp" android:color="@color/default_border" /> <!-- Replace with your color --> <solid android:color="@color/white" /> <!-- Match your layout background --> <corners android:radius="0dp" /> <!-- Square shape --> </shape>
border2.xml (clicked/selected state):
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <stroke android:width="2dp" android:color="@color/selected_border" /> <!-- Replace with your highlight color --> <solid android:color="@color/white" /> <corners android:radius="0dp" /> </shape>
Approach 1: Auto State Switch with Selector (Easiest)
If you want the border to change when the EditText is pressed or focused (and revert when not), a state selector is perfect. No extra code needed—Android handles the state changes automatically.
Create edittext_border_selector.xml in res/drawable:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Active state when clicked/focused --> <item android:drawable="@drawable/border2" android:state_pressed="true" /> <item android:drawable="@drawable/border2" android:state_focused="true" /> <!-- Default state --> <item android:drawable="@drawable/border1" /> </selector>
Then apply this selector to all your EditTexts in the layout:
<EditText android:id="@+id/editText1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/edittext_border_selector" android:inputType="text" />
Approach 2: Manual Toggle (Click to Switch Back and Forth)
If you need the border to stay changed until the next click (toggle behavior), add click listeners to each EditText. Here’s how to do it cleanly in Kotlin (Java version included):
Kotlin Implementation
class YourActivity : AppCompatActivity() { // Track each EditText's current border state private val editTextStates = mutableMapOf<EditText, Boolean>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.your_layout) // List all your 9 EditTexts val editTexts = listOf( findViewById<EditText>(R.id.editText1), findViewById<EditText>(R.id.editText2), findViewById<EditText>(R.id.editText3), // Add editText4 to editText9 here ) // Initialize state and set click listeners editTexts.forEach { editText -> editTextStates[editText] = false // Start with border1 editText.setOnClickListener { val isCurrentlySelected = editTextStates[it] ?: false if (isCurrentlySelected) { it.setBackgroundResource(R.drawable.border1) editTextStates[it] = false } else { it.setBackgroundResource(R.drawable.border2) editTextStates[it] = true } } } } }
Java Implementation
public class YourActivity extends AppCompatActivity { private HashMap<EditText, Boolean> editTextStates = new HashMap<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_layout); List<EditText> editTexts = Arrays.asList( findViewById(R.id.editText1), findViewById(R.id.editText2), // Add editText3 to editText9 here ); for (EditText editText : editTexts) { editTextStates.put(editText, false); editText.setOnClickListener(v -> { EditText clickedEt = (EditText) v; boolean isSelected = editTextStates.get(clickedEt); if (isSelected) { clickedEt.setBackgroundResource(R.drawable.border1); editTextStates.put(clickedEt, false); } else { clickedEt.setBackgroundResource(R.drawable.border2); editTextStates.put(clickedEt, true); } }); } } }
Approach 3: Single Selected EditText (Only One Has Highlight)
If you want only the last clicked EditText to have border2 (others revert to border1), simplify the listener like this (Kotlin example):
private var lastSelectedEditText: EditText? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.your_layout) val editTexts = listOf( findViewById<EditText>(R.id.editText1), // ... other EditTexts ) editTexts.forEach { editText -> editText.setOnClickListener { // Revert previous selected to default border lastSelectedEditText?.setBackgroundResource(R.drawable.border1) // Set current clicked to highlight border it.setBackgroundResource(R.drawable.border2) lastSelectedEditText = it as EditText } } }
Troubleshooting Quick Fixes
- Ensure your drawable files are in
res/drawable(not a version-specific folder likedrawable-v24unless intentional). - Verify your color resources (
@color/default_border,@color/selected_border) are defined inres/values/colors.xml. - If you’re using
android:backgroundTint, it might override your drawable—remove it or adjust the tint mode.
Let me know if any of these methods need tweaking for your specific use case!
内容的提问来源于stack exchange,提问作者azed

